void DeclRefDataElement::BindTypes( MagoEE::ITypeEnv* typeEnv, IScope* scope ) { if ( !FindDeclaration( mPath.c_str(), typeEnv, scope, mDecl.Ref() ) ) throw L"Declaration not found."; if ( !mDecl->IsVar() ) throw L"Declaration must refer to a variable."; }
// ================================================================= // Performs semantic analysis on this node. // ================================================================= CASTNode* CClassASTNode::Semant(CSemanter* semanter) { SEMANT_TRACE("CClassASTNode=%s", Identifier.c_str()); // Only semant once. if (Semanted == true) { //m_semanting = false; return this; } Semanted = true; // Check for duplicate identifiers (only if we are not an instanced class). if (GenericInstanceOf == NULL) { Parent->CheckForDuplicateIdentifier(semanter, Identifier, this); } if (IsGeneric == false || GenericInstanceOf != NULL) { // Work out mangled identifier. if (MangledIdentifier == "") { MangledIdentifier = semanter->GetMangled("ls_" + Identifier); } // Interface cannot use inheritance. if (InheritedTypes.size() > 0 && IsInterface == true) { semanter->GetContext()->FatalError("Interfaces cannot inherit from other interfaces or classes.", Token); } if (InheritedTypes.size() > 0 && IsStatic == true) { semanter->GetContext()->FatalError("Static classes cannot inherit from interfaces.", Token); } // Flag this class as semanting - we do this so we can detect // inheritance loops. if (m_semanting == true) { semanter->GetContext()->FatalError("Detected illegal cyclic inheritance of '" + Identifier + "'.", Token); } m_semanting = true; // Semant inherited types. bool foundSuper = false; for (auto iter = InheritedTypes.begin(); iter != InheritedTypes.end(); iter++) { CIdentifierDataType* type = *iter; CClassASTNode* node = type->SemantAsClass(semanter, this, true); if (type->Identifier == Identifier) { semanter->GetContext()->FatalError("Attempt to inherit class from itself.", Token); } if (node->IsInterface == true) { Interfaces.push_back(node); } else { if (foundSuper == true) { semanter->GetContext()->FatalError("Multiple inheritance is not supported. Use interfaces instead.", Token); } SuperClass = node; foundSuper = true; } } // Native classes are not allowed to implement interfaces. //if (IsNative == true && Interfaces.size() > 0) //{ // semanter->GetContext()->FatalError("Native classes cannot implement interfaces.", Token); //} // If no inherited types the we inherit from object. if (SuperClass == NULL && IsNative == false) { SuperClass = dynamic_cast<CClassASTNode*>(FindDeclaration(semanter, "object")); if (SuperClass == NULL) { semanter->GetContext()->FatalError("Could not find base class to inherit from.", Token); } } else if (SuperClass != NULL) { // Check super class is valid. if (SuperClass->IsSealed == true) { semanter->GetContext()->FatalError("Classes cannot inherit from sealed class.", Token); } // Cannot inherit in static classes. if (IsStatic == true) { semanter->GetContext()->FatalError("Static classes cannot inherit from other classes.", Token); } } // Semant inherited classes. if (SuperClass != NULL) { SuperClass->Semant(semanter); } for (auto iter = Interfaces.begin(); iter != Interfaces.end(); iter++) { CClassASTNode* interfaceClass = *iter; interfaceClass->Semant(semanter); } // Look for interface in parent classes. if (SuperClass != NULL) { for (auto iter = Interfaces.begin(); iter != Interfaces.end(); iter++) { CClassASTNode* interfaceClass = *iter; if (SuperClass->InheritsFromClass(semanter, interfaceClass) != NULL) { semanter->GetContext()->FatalError(CStringHelper::FormatString("Attempt to implement interface '%s' that is already implemented by a parent class.", interfaceClass->Identifier.c_str()), Token); } } } // Remove semanting flag. m_semanting = false; } // If we are generic we only semant children of instanced classes. if (IsGeneric == false || GenericInstanceOf != NULL) { // Create static class constructor. if (IsInterface == false) { CClassMemberASTNode* defaultCtor = FindClassMethod(semanter, "__"+Identifier+"_ClassConstructor", std::vector<CDataType*>(), false); if (defaultCtor == NULL) { CClassMemberASTNode* member = new CClassMemberASTNode(NULL, Token); member->MemberType = MemberType::Method; member->Identifier = "__"+Identifier+"_ClassConstructor"; member->AccessLevel = AccessLevel::PUBLIC; member->Body = new CMethodBodyASTNode(member, Token); member->IsConstructor = true; member->IsStatic = true; member->ReturnType = new CVoidDataType(Token); member->IsExtension = IsNative; Body->AddChild(member); ClassConstructor = member; } if (IsNative == false && IsEnum == false) { // Create instance constructor. CClassMemberASTNode* instanceCtor = FindClassMethod(semanter, "__"+Identifier+"_InstanceConstructor", std::vector<CDataType*>(), false); if (instanceCtor == NULL) { CClassMemberASTNode* member = new CClassMemberASTNode(NULL, Token); member->MemberType = MemberType::Method; member->Identifier = "__"+Identifier+"_InstanceConstructor"; member->AccessLevel = AccessLevel::PUBLIC; member->Body = new CMethodBodyASTNode(member, Token); member->IsConstructor = true; member->IsStatic = false; member->ReturnType = new CVoidDataType(Token); Body->AddChild(member); InstanceConstructor = member; } } // If no argument-less constructor has been provided, lets create a default one. if (IsStatic == false && IsAbstract == false && IsInterface == false && IsNative == false && IsEnum == false) { CClassMemberASTNode* defaultCtor = FindClassMethod(semanter, Identifier, std::vector<CDataType*>(), false); if (defaultCtor == NULL) { CClassMemberASTNode* member = new CClassMemberASTNode(NULL, Token); member->MemberType = MemberType::Method; member->Identifier = Identifier; member->AccessLevel = AccessLevel::PUBLIC; member->Body = new CMethodBodyASTNode(member, Token); member->IsConstructor = true; member->ReturnType = new CVoidDataType(Token); Body->AddChild(member); } } } // Semant all members. SemantChildren(semanter); } return this; }