예제 #1
0
TEST(TestDeclaration, testImportKind_Var)
{
    PARSE_STATEMENT(L"import var Foundation.NSFileManager");
    ImportPtr import;
    ASSERT_NOT_NULL(import = std::dynamic_pointer_cast<Import>(root));
    ASSERT_EQ(L"Foundation.NSFileManager", import->getPath());
    ASSERT_EQ(Import::Var, import->getKind());
}
예제 #2
0
TEST(TestDeclaration, testImportSubModule)
{
    PARSE_STATEMENT(L"import Foundation.SubModule");
    ImportPtr import;
    ASSERT_NOT_NULL(import = std::dynamic_pointer_cast<Import>(root));
    ASSERT_EQ(L"Foundation.SubModule", import->getPath());
    ASSERT_EQ(Import::_, import->getKind());
}
예제 #3
0
파일: loader.cpp 프로젝트: Blei/clay
void loadDependent(ModulePtr m, vector<string> *sourceFiles, ImportPtr dependent, bool verbose) {
    ImportPtr x = dependent;
    x->module = loadModuleByName(x->dottedName, sourceFiles, verbose);
    switch (x->importKind) {
    case IMPORT_MODULE : {
            ImportModule *im = (ImportModule *)x.ptr();
            IdentifierPtr name = NULL;
            if (im->alias.ptr()) {
                name = im->alias;
                m->importedModuleNames[im->alias->str].module = x->module;
            } else {
                llvm::ArrayRef<IdentifierPtr> parts = im->dottedName->parts;
                if (parts.size() == 1)
                    name = parts[0];
                else if (x->visibility == PUBLIC)
                    error(x->location,
                          "public imports of dotted module paths must have an \"as <name>\" alias");
                llvm::StringMap<ModuleLookup> *node = &m->importedModuleNames;
                for (size_t i = parts.size() - 1; i >= 1; --i) {
                    node = &(*node)[parts[i]->str].parents;
                }
                (*node)[parts[0]->str].module = x->module;
            }
            
            if (name.ptr()) {
                string nameStr(name->str.begin(), name->str.end());
                if (m->importedNames.count(nameStr))
                    error(name, "name imported already: " + nameStr);
                m->importedNames.insert(nameStr);
                m->allSymbols[nameStr].insert(x->module.ptr());
                if (x->visibility == PUBLIC)
                    m->publicSymbols[nameStr].insert(x->module.ptr());
            }
            
            break;
        }
    case IMPORT_STAR :
        break;
    case IMPORT_MEMBERS : {
            ImportMembers *y = (ImportMembers *)x.ptr();
            for (unsigned i = 0; i < y->members.size(); ++i) {
                ImportedMember &z = y->members[i];
                IdentifierPtr alias = z.alias.ptr() ? z.alias : z.name;
                string aliasStr(alias->str.begin(), alias->str.end());
                if (m->importedNames.count(aliasStr))
                    error(alias, "name imported already: " + aliasStr);
                assert(y->aliasMap.count(aliasStr) == 0);
                m->importedNames.insert(aliasStr);
                y->aliasMap[aliasStr] = z.name;
            }
            break;
        }
    default :
            assert(false);
}
}
예제 #4
0
/*
  GRAMMAR OF AN IMPORT DECLARATION
 
 ‌ import-declaration → attributesoptimportimport-kindoptimport-path
 ‌ import-kind → typealias  struct  class  enum protocol  var  func
 ‌ import-path → import-path-identifier | import-path-identifier.import-path
 ‌ import-path-identifier → identifier | operator”
*/
DeclarationPtr Parser::parseImport(const std::vector<AttributePtr>& attrs)
{
    Token token;
    expect(Keyword::Import, token);
    ImportPtr ret = nodeFactory->createImport(token.state);
    ret->setAttributes(attrs);
    expect_next(token);
    tassert(token, token.type == TokenType::Identifier, Errors::E_EXPECT_IDENTIFIER_1, token.token);
    Import::Kind kind = Import::_;
    switch(token.identifier.keyword)
    {
        case Keyword::_:
            restore(token);
            break;
        case Keyword::Typealias:
            kind = Import::Typealias;
            break;
        case Keyword::Struct:
            kind = Import::Struct;
            break;
        case Keyword::Class:
            kind = Import::Class;
            break;
        case Keyword::Enum:
            kind = Import::Enum;
            break;
        case Keyword::Protocol:
            kind = Import::Protocol;
            break;
        case Keyword::Var:
            kind = Import::Var;
            break;
        case Keyword::Func:
            kind = Import::Func;
            break;
        default:
            unexpected(token);
            break;
    }
    std::wstring path;
    int n = 0;
    do
    {
        expect_next(token);
        if(token.type != TokenType::Identifier && token.type != TokenType::Operator)
            unexpected(token);
        if(n)
            path += L".";
        path += token.token;
        n++;
    } while (match(L"."));
    ret->setPath(path);
    ret->setKind(kind);
    return ret;
}
예제 #5
0
static void loadDependents(ModulePtr m, vector<string> *sourceFiles) {
    m->rootHolder = new ModuleHolder();
    m->publicRootHolder = new ModuleHolder();
    vector<ImportPtr>::iterator ii, iend;
    for (ii = m->imports.begin(), iend = m->imports.end(); ii != iend; ++ii) {
        ImportPtr x = *ii;
        x->module = loadModuleByName(x->dottedName, sourceFiles);
        switch (x->importKind) {
        case IMPORT_MODULE : {
            ImportModule *y = (ImportModule *)x.ptr();
            {
                ModuleHolderPtr holder = m->rootHolder;
                if (y->alias.ptr()) {
                    holder = installHolder(holder, y->alias);
                }
                else {
                    vector<IdentifierPtr> &parts = y->dottedName->parts;
                    for (unsigned i = 0; i < parts.size(); ++i)
                        holder = installHolder(holder, parts[i]);
                }
                if (holder->import.ptr())
                    error(x, "module already imported");
                holder->import = y;
            }
            if (y->visibility == PUBLIC) {
                ModuleHolderPtr holder = m->publicRootHolder;
                if (y->alias.ptr()) {
                    holder = installHolder(holder, y->alias);
                }
                else {
                    vector<IdentifierPtr> &parts = y->dottedName->parts;
                    for (unsigned i = 0; i < parts.size(); ++i)
                        holder = installHolder(holder, parts[i]);
                }
                if (holder->import.ptr())
                    error(x, "module already imported");
                holder->import = y;
            }
            break;
        }
        case IMPORT_STAR : {
            break;
        }
        case IMPORT_MEMBERS : {
            ImportMembers *y = (ImportMembers *)x.ptr();
            for (unsigned i = 0; i < y->members.size(); ++i) {
                ImportedMember &z = y->members[i];
                IdentifierPtr alias = z.alias;
                if (!alias)
                    alias = z.name;
                if (y->aliasMap.count(alias->str))
                    error(alias, "name imported already: " + alias->str);
                y->aliasMap[alias->str] = z.name;
            }
            break;
        }
        default :
            assert(false);
        }
    }
}