TypeExpression* TypeFunction::buildMethod(ClassMethodNode* methodNode, Method* methodSymbol, TypeExpression* returnType) { //let's build the FunctionType: TypeFunction* typeFunction = new TypeFunction(methodSymbol->functionSignatures, methodSymbol->getName() , methodSymbol->getUniqueName()); //extract params TypeExpressions and add them to @paramsTE for (auto ¶mNode : methodNode->paramsList->nodes) { typeFunction->addToParams(paramNode->getNodeType()); typeFunction->paramsSymbols.push_back(dynamic_cast<ParameterNode*>(paramNode)->parSym);//append symbol as well } //extract return type: //check if a returnType exists in the symbol (might be a constructor) if (methodSymbol->getReturnType() != nullptr) { typeFunction->returnType = TypesTable::getInstance()->getType(methodSymbol->getReturnType()); if (strcmp(methodSymbol->getReturnType(), dynamic_cast<TypeClass*>(returnType)->getName().c_str()) == 0) { typeFunction->returnType = returnType; } //if return type not found, return a TypeError TypeError* errorReturnType = dynamic_cast<TypeError*>(typeFunction->returnType); if (errorReturnType != nullptr) return new TypeError("return type: " + string(methodSymbol->getReturnType()) + " is undefied."); } //everything is ok //now let's resize according to the new params typeFunction->resize(); typeFunction->isConstructorFT = methodSymbol->isConstructor; typeFunction->isStaticMethod = false; return typeFunction; }
TypeExpression* TypeFunction::buildFunction(FunctionDefineNode* functionNode, Function* functionSymbol) { //try to find a TypeFunction from the first signature of the given function symbol. //the @TypeFunction::isDeclared() returns false if a name of the function already found, not just unmatched signature. //this behaviour can be changed, so we can obtain the functionality of Function Overloading. bool isDeclared = TypeFunction::isDeclared(functionNode->functionSym->functionSignatures.at(0)); //if isDeclared, throw a TypeError with already defined if (isDeclared) return new TypeError(string(functionSymbol->getName()) + "already defined."); //let's build the FunctionType: TypeFunction* typeFunction = new TypeFunction(functionSymbol->functionSignatures, functionSymbol->getName() ,functionSymbol->getUniqueName()); //extract params TypeExpressions and add them to @paramsTE for (auto ¶mNode : functionNode->paramsList->nodes) { typeFunction->addToParams(paramNode->getNodeType()); typeFunction->paramsSymbols.push_back(dynamic_cast<ParameterNode*>(paramNode)->parSym);//append symbol as well } //extract return type typeFunction->returnType = TypesTable::getInstance()->getType(functionSymbol->getReturnType()); //if return type not found, return a TypeError TypeError* errorReturnType = dynamic_cast<TypeError*>(typeFunction->returnType); if (errorReturnType != nullptr) return new TypeError("return type: " + string(functionSymbol->getReturnType()) + " is undefied."); //everything is ok //now let's resize according to the new params typeFunction->resize(); typeFunction->isConstructorFT = false; // not a constructor typeFunction->isStaticMethod = false; //and finally, add it to the FunctionType's we have: TypeFunction::functionInstances.push_back(typeFunction); return typeFunction; }