void DeclarationAnalyzer::visitTypeAlias(const TypeAliasPtr& node) { if(isLazyDeclared(node)) return; TypePtr type; SymbolScope* currentScope = symbolRegistry->getCurrentScope(); if(currentScope->isSymbolDefined(node->getName())) { error(node, Errors::E_INVALID_REDECLARATION_1, node->getName()); return; } //type = currentScope->getForwardDeclaration(node->getName()); if(ctx->currentType && ctx->currentType->getCategory() == Type::Protocol && !node->getType()) { //register a type place holder for protocol type = Type::newTypeAlias(node->getName(), nullptr, nullptr); } else { shared_ptr<TypeResolver> typeResolver(new TypeResolver(symbolRegistry, semanticAnalyzer, this, ctx, true)); type = resolveType(node->getType(), true); assert(type != nullptr && "Cannot resolve type"); //TypeBuilderPtr builder = static_pointer_cast<TypeBuilder>(type); //builder->setInnerType(type); //builder->initAlias(node->getType(), typeResolver); } validateDeclarationModifiers(node); declarationFinished(node->getName(), type, node); currentScope->addSymbol(node->getName(), type); }
void DeclarationAnalyzer::visitTypeAlias(const TypeAliasPtr& node) { SymbolScope* scope = nullptr; TypePtr type; SymbolScope* currentScope = symbolRegistry->getCurrentScope(); //check if this type is already defined symbolRegistry->lookupType(node->getName(), &scope, &type); if(type && scope == currentScope) { //invalid redeclaration of type T error(node, Errors::E_INVALID_REDECLARATION_1, node->getName()); return; } type = Type::newType(node->getName(), Type::Alias); if(ctx->currentType && ctx->currentType->getCategory() == Type::Protocol && !node->getType()) { //register a type place holder for protocol } else { TypePtr innerType = lookupType(node->getType()); if(innerType) type = innerType; //static_pointer_cast<TypeBuilder>(type)->setInnerType(innerType); } currentScope->addSymbol(node->getName(), type); validateDeclarationModifiers(node); declarationFinished(node->getName(), type, node); }
TEST(TestDeclaration, TypeAlias) { PARSE_STATEMENT(L"typealias NewType = Int"); ASSERT_EQ(0, compilerResults.numResults()); TypeAliasPtr typealias; TypeIdentifierPtr Int; ASSERT_NOT_NULL(typealias = std::dynamic_pointer_cast<TypeAlias>(root)); ASSERT_EQ(L"NewType", typealias->getName()); ASSERT_NOT_NULL(Int = std::dynamic_pointer_cast<TypeIdentifier>(typealias->getType())); ASSERT_EQ(L"Int", Int->getName()); }
TEST(TestDeclaration, TypeAlias_ProtocolNoType) { PARSE_STATEMENT(L"protocol MyProtocol { typealias NewType }"); ASSERT_EQ(0, compilerResults.numResults()); ProtocolDefPtr protocol; TypeAliasPtr typealias; TypeIdentifierPtr Int; ASSERT_NOT_NULL(protocol = std::dynamic_pointer_cast<ProtocolDef>(root)); ASSERT_EQ(1, protocol->numDeclarations()); ASSERT_NOT_NULL(typealias = std::dynamic_pointer_cast<TypeAlias>(protocol->getDeclaration(0))); ASSERT_EQ(L"NewType", typealias->getName()); ASSERT_NULL(typealias->getType()); }