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;
		}
	}
}
Example #2
0
bool TypeNode::isUnderTemplateClass()
{
	TypeNode* enclosing = m_enclosing;
	while (enclosing && !enclosing->isNamespace())
	{
		if (enclosing->isTemplateClass())
		{
			return true;
		}
		enclosing = enclosing->m_enclosing;
	}
	return false;
}
Example #3
0
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;
}
Example #4
0
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);
		}
	}
}
Example #5
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;
}
Example #6
0
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;
		}
	}
}