ClassDefinition* Tree::startClass( const Identifier& name, const GenericTypeParameterList& genericTypeParameters, const IdentifierList& parents, ClassDefinition::Properties& properties, const Location& location) { NameBindings* containingNameBindings = &globalNameBindings; auto containingClass = getCurrentClass(); if (containingClass != nullptr) { containingNameBindings = &(containingClass->getNameBindings()); } auto newClass = ClassDefinition::create(name, genericTypeParameters, parents, containingNameBindings, properties, location); if (containingClass != nullptr) { newClass->setIsImported(containingClass->isImported()); } if (!containingNameBindings->insertClass(name, newClass)) { Trace::error("Class already declared at the same scope: " + name, location); } if (!newClass->isGeneric()) { // For generic message classes, the empty copy constructor will be // generated when the concrete class is created from the generic one. if (newClass->needsCloneMethod()) { // The body of the copy constructor will be generated later by the // CloneGenerator, here we just generate an empty copy constructor. // The reason for generating an empty copy constructor at this stage // is that the copy constructor needs to be in the name bindings of // the new class before any other class can inherit from it. // Otherwise, the copy constructor will not be in the name bindings // of the derived class since name bindings are copied from the base // class to the derived class. newClass->generateEmptyCopyConstructor(); CloneGenerator::generateEmptyCloneMethod(newClass); } } openClasses.push_back(newClass); return newClass; }
AST::Node<AST::Function> FunctionParser::parseGlobalFunction() { const auto start = reader_.position(); bool isPrimitive = false; bool isImported = false; bool isExported = false; switch (reader_.peek().kind()) { case Token::PRIMITIVEFUNCTION: reader_.consume(); isPrimitive = true; break; case Token::IMPORT: reader_.consume(); isImported = true; break; case Token::EXPORT: reader_.consume(); isExported = true; break; default: break; } auto function = parseBasicFunction(start); if (isPrimitive) { function->setIsPrimitive(true); } if (isImported) { function->setIsImported(true); } if (isExported) { function->setIsExported(true); } return function; }