void TemplateClassInstanceNode::collectTypes(TypeNode* enclosingTypeNode, TemplateArguments* templateArguments) { assert(enclosingTypeNode->isNamespace() && 0 == templateArguments); assert(0 == m_typeNode && 0 == m_classTypeNode); TypeNode* childTypeNode = enclosingTypeNode->getChildNode(m_name->m_str); if (0 == childTypeNode || !childTypeNode->isTemplateClass()) { RaiseError_InvalidClassTemplateName(m_name); return; } m_classTypeNode = static_cast<ClassTypeNode*>(childTypeNode); ClassNode* classNode = static_cast<ClassNode*>(m_classTypeNode->m_classNode); std::vector<IdentifyNode*> parameterNodes; classNode->m_templateParametersNode->collectParameterNodes(parameterNodes); size_t paramCount = parameterNodes.size(); std::vector<TypeNameNode*> argumentNodes; m_parameterList->collectTypeNameNodes(argumentNodes); size_t argCount = argumentNodes.size(); if (paramCount != argCount) { if (paramCount < argCount) { RaiseError_TooManyTemplateArguments(m_name); } else { RaiseError_TooFewTemplateArguments(m_name); } return; } bool argError = false; for (size_t i = 0; i < argCount; ++i) { if (argumentNodes[i]->calcTypeNodes(enclosingTypeNode, 0)) { TemplateArgument arg; arg.m_name = parameterNodes[i]->m_str; arg.m_typeNode = argumentNodes[i]->m_typeNode; m_templateArguments.m_arguments.push_back(arg); } else { argError = true; RaiseError_InvalidTemplateArgument(argumentNodes[i]); } } if (!argError) { assert(enclosingTypeNode->isNamespace()); m_typeNode = static_cast<NamespaceTypeNode*>(enclosingTypeNode)->addTemplateClassInstance(this); if (m_typeNode) { m_templateArguments.m_className = m_name->m_str; m_templateArguments.m_classTypeNode = m_typeNode; } } }
bool TypeNode::isUnderTemplateClass() { TypeNode* enclosing = m_enclosing; while (enclosing && !enclosing->isNamespace()) { if (enclosing->isTemplateClass()) { return true; } enclosing = enclosing->m_enclosing; } return false; }
bool ClassNode::hasOverrideMethod(TemplateArguments* templateArguments) { std::vector<MemberNode*> memberNodes; m_memberList->collectMemberNodes(memberNodes); size_t count = memberNodes.size(); for(size_t i = 0; i < count; ++i) { MemberNode* memberNode = memberNodes[i]; if(snt_method == memberNode->m_nodeType) { MethodNode* methodNode = static_cast<MethodNode*>(memberNode); if(methodNode->m_override) { return true; } } } std::vector<TypeNameNode*> baseTypeNameNodes; m_baseList->collectTypeNameNodes(baseTypeNameNodes); count = baseTypeNameNodes.size(); for(size_t i = 0; i < count; ++i) { TypeNameNode* typeNameNode = baseTypeNameNodes[i]; TypeNode* typeNode = typeNameNode->getActualTypeNode(templateArguments); if (typeNode->isTemplateClassInstance()) { TemplateClassInstanceTypeNode* templateClassInstanceTypeNode = static_cast<TemplateClassInstanceTypeNode*>(typeNode); if (templateClassInstanceTypeNode->m_classNode->hasOverrideMethod(&templateClassInstanceTypeNode->m_templateClassInstanceNode->m_templateArguments)) { return true; } } else { assert(typeNode->isClass() && !typeNode->isTemplateClass()); ClassTypeNode* classTypeNode = static_cast<ClassTypeNode*>(typeNode); if (classTypeNode->m_classNode->hasOverrideMethod(0)) { return true; } } } return false; }
void ClassNode::collectOverrideMethods(std::vector<MethodNode*>& methodNodes, TemplateArguments* templateArguments) { std::vector<MemberNode*> memberNodes; m_memberList->collectMemberNodes(memberNodes); size_t count = memberNodes.size(); for(size_t i = 0; i < count; ++i) { MemberNode* memberNode = memberNodes[i]; if(snt_method == memberNode->m_nodeType) { MethodNode* methodNode = static_cast<MethodNode*>(memberNode); if(methodNode->m_override) { methodNodes.push_back(methodNode); } } } std::vector<TypeNameNode*> baseTypeNameNodes; m_baseList->collectTypeNameNodes(baseTypeNameNodes); count = baseTypeNameNodes.size(); for(size_t i = 0; i < count; ++i) { TypeNameNode* typeNameNode = baseTypeNameNodes[i]; TypeNode* typeNode = typeNameNode->getActualTypeNode(templateArguments); if (typeNode->isTemplateClassInstance()) { TemplateClassInstanceTypeNode* templateClassInstanceTypeNode = static_cast<TemplateClassInstanceTypeNode*>(typeNode); templateClassInstanceTypeNode->m_classNode->collectOverrideMethods(methodNodes, &templateClassInstanceTypeNode->m_templateClassInstanceNode->m_templateArguments); } else { assert(typeNode->isClass() && !typeNode->isTemplateClass()); ClassTypeNode* classTypeNode = static_cast<ClassTypeNode*>(typeNode); classTypeNode->m_classNode->collectOverrideMethods(methodNodes, 0); } } }
TypeNode* TypeNameNode::getTypeNode(TemplateArguments* templateArguments) { //assert(0 == templateArguments || templateArguments->m_classTypeNode->isTemplateClassInstance()); assert(0 != m_startTypeNode); TypeNode* result = 0; if (0 == m_typeNode)// under template parameter { assert(templateArguments && m_startTypeNode && (m_startTypeNode->isTemplateParameter() || m_startTypeNode->isTypedef()) ); if (templateArguments->m_classTypeNode->isClass()) { return 0; } TypeNode* actualStartTypeNode = m_startTypeNode->getActualTypeNode(templateArguments); assert(actualStartTypeNode); std::vector<ScopeNameNode*> scopeNameNodes; m_scopeNameList->collectIdentifyNodes(scopeNameNodes); if (scopeNameNodes.size() == 1) { result = actualStartTypeNode; } else { scopeNameNodes.erase(scopeNameNodes.begin()); TypeNode* initialTypeTreeNode = 0; TypeNode* finalTypeTreeNode = 0; if (g_typeTree.findNodeByScopeNames(initialTypeTreeNode, finalTypeTreeNode, scopeNameNodes, actualStartTypeNode, templateArguments)) { assert(finalTypeTreeNode); result = finalTypeTreeNode; } } } else if (m_typeNode->isTemplateParameter()) { assert(templateArguments); result = templateArguments->findTypeNode(m_scopeNameList->m_scopeName->m_name->m_str); } else if (m_typeNode->isTemplateClass()) { assert(templateArguments); if (m_scopeNameList->m_scopeName->isTemplateForm()) { result = g_typeTree.findNodeByScopeName(m_scopeNameList->m_scopeName, m_typeNode->m_enclosing, templateArguments); } else { assert(m_scopeNameList->m_scopeName->m_name->m_str == templateArguments->m_className); result = templateArguments->m_classTypeNode; } } else if (m_typeNode->isUnderTemplateClass()) { assert(templateArguments); if (m_startTypeNode->isUnderTemplateClass()) { std::vector<TypeNode*> typeNodes; TypeNode* typeNode = m_typeNode; while (typeNode) { if (typeNode->isTemplateClass()) { break; } typeNodes.push_back(typeNode); typeNode = typeNode->m_enclosing; } assert(typeNode->isTemplateClass() && typeNode->m_name == templateArguments->m_className); typeNode = templateArguments->m_classTypeNode; auto it = typeNodes.rbegin(); auto end = typeNodes.rend(); for (; it != end; ++it) { TypeNode* tempTypeNode = *it; typeNode = typeNode->getChildNode(tempTypeNode->m_name); assert(typeNode); } if (typeNode->isTypedef()) { TypeNode* actualTypeNode = typeNode->getActualTypeNode(templateArguments); if (actualTypeNode->isTemplateParameter()) { typeNode = templateArguments->findTypeNode(actualTypeNode->m_name); assert(0 != typeNode); } } result = typeNode; } else { std::vector<ScopeNameNode*> scopeNameNodes; m_scopeNameList->collectIdentifyNodes(scopeNameNodes); TypeNode* initialTypeTreeNode = 0; TypeNode* finalTypeTreeNode = 0; if (m_startTypeNode->isTemplateClass() && !scopeNameNodes[0]->isTemplateForm()) { assert(m_startTypeNode->m_name == templateArguments->m_className); scopeNameNodes.erase(scopeNameNodes.begin()); if (g_typeTree.findNodeByScopeNames(initialTypeTreeNode, finalTypeTreeNode, scopeNameNodes, templateArguments->m_classTypeNode, templateArguments)) { result = finalTypeTreeNode; } } else { if (g_typeTree.findNodeByScopeNames(initialTypeTreeNode, finalTypeTreeNode, scopeNameNodes, m_startTypeNode->m_enclosing, templateArguments)) { result = finalTypeTreeNode; } } } } else { assert(m_typeNode->isPredefinedType() || m_typeNode->isEnum() || m_typeNode->isClass() || m_typeNode->isTemplateClassInstance() || m_typeNode->isTypedef() || m_typeNode->isTypeDeclaration()); result = m_typeNode; } if(0 == result) { RaiseError_InvalidTypeName(m_scopeNameList); } return result; }
TypeNode* TypeTree::findNodeByScopeName(ScopeNameNode* scopeNameNode, TypeNode* enclosingTypeTreeNode, TemplateArguments* templateArguments) { if (templateArguments && templateArguments->m_classTypeNode->isTemplateClass())//must be TypeNameNode::calcTypeNodes { if (scopeNameNode->isTemplateForm()) { TypeNode* result = enclosingTypeTreeNode->getChildNode(scopeNameNode->m_name->m_str); if (0 == result || !result->isTemplateClass()) { return 0; } std::vector<TypeNameNode*> paramTypeNameNodes; scopeNameNode->m_parameterList->collectTypeNameNodes(paramTypeNameNodes); assert(!paramTypeNameNodes.empty()); if (paramTypeNameNodes.size() != static_cast<ClassTypeNode*>(result)->m_parameterNodes.size()) { return 0; } bool hasUndeteminedType = false; std::string name = scopeNameNode->m_name->m_str; name += "<"; auto begin = paramTypeNameNodes.begin(); auto end = paramTypeNameNodes.end(); for (auto it = begin; it != end; ++it) { if (it != begin) { name += ", "; } TypeNameNode* paramTypeNameNode = *it; assert(paramTypeNameNode->m_startTypeNode); if (0 == paramTypeNameNode->m_typeNode || paramTypeNameNode->m_typeNode->isTemplateParameter() || paramTypeNameNode->m_typeNode->isTemplateClass() || paramTypeNameNode->m_typeNode->isUnderTemplateClass()) { hasUndeteminedType = true; break; } else { assert(paramTypeNameNode->m_typeNode->isPredefinedType() || paramTypeNameNode->m_typeNode->isEnum() || paramTypeNameNode->m_typeNode->isClass() || paramTypeNameNode->m_typeNode->isTemplateClassInstance() || paramTypeNameNode->m_typeNode->isTypedef() || paramTypeNameNode->m_typeNode->isTypeDeclaration()); std::string paramName; paramTypeNameNode->m_typeNode->getActualTypeFullName(paramName); name += paramName; } } name += ">"; if (!hasUndeteminedType) { result = enclosingTypeTreeNode->getChildNode(name); } return result; } else { TypeNode* result = enclosingTypeTreeNode->getChildNode(scopeNameNode->m_name->m_str); if (0 == result || result->isTemplateClass()) { return 0; } return result; } } else { if (scopeNameNode->isTemplateForm()) { TypeNode* result = enclosingTypeTreeNode->getChildNode(scopeNameNode->m_name->m_str); if (0 == result || !result->isTemplateClass()) { return 0; } std::vector<TypeNameNode*> paramTypeNameNodes; scopeNameNode->m_parameterList->collectTypeNameNodes(paramTypeNameNodes); assert(!paramTypeNameNodes.empty()); if (paramTypeNameNodes.size() != static_cast<ClassTypeNode*>(result)->m_parameterNodes.size()) { return 0; } bool hasUndeteminedType = false; std::string name = scopeNameNode->m_name->m_str; name += "<"; auto begin = paramTypeNameNodes.begin(); auto end = paramTypeNameNodes.end(); for (auto it = begin; it != end; ++it) { if (it != begin) { name += ", "; } TypeNameNode* paramTypeNameNode = *it; TypeNode* paramTypeNode = paramTypeNameNode->getTypeNode(templateArguments); if(0 == paramTypeNode) { return 0; } else { std::string paramName; paramTypeNode->getActualTypeFullName(paramName); name += paramName; } } name += ">"; if (!hasUndeteminedType) { result = enclosingTypeTreeNode->getChildNode(name); } return result; } else { TypeNode* result = enclosingTypeTreeNode->getChildNode(scopeNameNode->m_name->m_str); if (0 == result || result->isTemplateClass()) { return 0; } return result; } } }