summaryrefslogtreecommitdiff
path: root/src/resolve/index.cpp
blob: 4b6964fb5266a17b5f65c37299ff951eafa1e620 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * Build up a name index in all modules (optimising lookups in later stages)
 */
#include <ast/ast.hpp>
#include <ast/crate.hpp>
#include <main_bindings.hpp>

void _add_item(AST::Module& mod, bool is_type, const ::std::string& name, bool is_pub, ::AST::PathBinding ir)
{
    DEBUG("Add " << (is_type ? "type" : "value") << " item '" << name << "': " << ir);
    auto& list = (is_type ? mod.m_type_items : mod.m_value_items);
    
    if( false == list.insert( ::std::make_pair(name, ::std::make_pair(is_pub, mv$(ir))) ).second )
    {
        ERROR(Span(), E0000, "Duplicate definition of name '" << name << "' in " << (is_type ? "type" : "value") << " scope (" << mod.path() << ")");
    }
}
void _add_item_type(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir)
{
    _add_item(mod, true, name, is_pub, mv$(ir));
}
void _add_item_value(AST::Module& mod, const ::std::string& name, bool is_pub, ::AST::PathBinding ir)
{
    _add_item(mod, false, name, is_pub, mv$(ir));
}

void Resolve_Index_Module(AST::Module& mod)
{
    TRACE_FUNCTION_F("mod = " << mod.path());
    for( const auto& i : mod.items() )
    {
        TU_MATCH(AST::Item, (i.data), (e),
        (None,
            ),
        // - Types/modules only
        (Module,
            _add_item_type(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Module({&e}));
            ),
        (Crate,
            TODO(Span(), "Crate in Resolve_Index_Module");
            //_add_item_type(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Crate(e));
            ),
        (Enum,
            _add_item_type(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Enum({&e}));
            ),
        (Trait,
            _add_item_type(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Trait({&e}));
            ),
        (Type,
            _add_item_type(mod, i.name, i.is_pub,  ::AST::PathBinding::make_TypeAlias({&e}));
            ),
        // - Mixed
        (Struct,
            _add_item_type(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Struct({&e}));
            if( e.m_data.is_Struct() ) {
                _add_item_value(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Struct({&e}));
            }
            ),
        // - Values only
        (Function,
            _add_item_value(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Function({&e}));
            ),
        (Static,
            _add_item_value(mod, i.name, i.is_pub,  ::AST::PathBinding::make_Static({&e}));
            )
        )
    }
    
    for( const auto& i : mod.imports() )
    {
        if( i.name != "" )
        {
            const auto& sp = i.data.sp;
            const auto& b = i.data.path.binding();
            TU_MATCH(::AST::PathBinding, (b), (e),
            (Unbound,
                BUG(sp, "Import left unbound");
                ),
            (Variable,
                BUG(sp, "Import was bound to variable");
                ),
            (TypeParameter,
                BUG(sp, "Import was bound to type parameter");
                ),
            (TraitMethod,
                BUG(sp, "Import was bound to trait method");
                ),
            (StructMethod,
                BUG(sp, "Import was bound to struct method");
                ),
            
            (Module,  _add_item_type(mod, i.name, i.is_pub,  b.clone()); ),
            //(Crate,   _add_item_type(mod, i.name, i.is_pub,  b.clone()); ),
            (Enum,    _add_item_type(mod, i.name, i.is_pub,  b.clone()); ),
            (Trait,   _add_item_type(mod, i.name, i.is_pub,  b.clone()); ),
            (TypeAlias, _add_item_type(mod, i.name, i.is_pub,  b.clone()); ),
            
            (Struct,
                _add_item_type(mod, i.name, i.is_pub,  b.clone());
                ),
            (Static  , _add_item_value(mod, i.name, i.is_pub,  b.clone()); ),
            (Function, _add_item_value(mod, i.name, i.is_pub,  b.clone()); ),
            (EnumVar , _add_item_value(mod, i.name, i.is_pub,  b.clone()); )
            )
        }
    }
    
    for( auto& i : mod.items() )
    {
        TU_MATCH_DEF(AST::Item, (i.data), (e),
        (
            ),
        (Module,
            Resolve_Index_Module(e);
            )
        )
    }
}

void Resolve_Index(AST::Crate& crate)
{
    Resolve_Index_Module(crate.m_root_module);
}