Пример #1
0
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;
}
Пример #2
0
		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;
		}