// up the module proper in `FinalizeImports`
// The namespace does not matter here since we are dealing with a glob
// TODO: Ugly
- import_mappings.insert (
- {use_dec_id, {{std::move (glob), ImportData::Glob (*resolved)}}});
+ import_mappings.insert (use_dec_id,
+ ImportPair (std::move (glob),
+ ImportData::Glob (*resolved)));
return true;
}
if (definitions.empty ())
return false;
- // We insert an empty vector, unless an element was already present for
- // `use_dec_id` - which is returned in the tuple's first member
- auto tuple = import_mappings.insert ({use_dec_id, {}});
- // We then get that tuple's first member, which will be an iterator to the
- // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly
- // created empty vector (plus its key since this is a hashmap iterator).
- // we then access the second member of the pair to get access to the
- // vector directly.
- auto &imports = tuple.first->second;
+ auto &imports = import_mappings.new_or_access (use_dec_id);
imports.emplace_back (
- std::make_pair (std::move (import),
- ImportData::Simple (std::move (definitions))));
+ ImportPair (std::move (import),
+ ImportData::Simple (std::move (definitions))));
return true;
}
if (definitions.empty ())
return false;
- // We insert an empty vector, unless an element was already present for
- // `use_dec_id` - which is returned in the tuple's first member
- auto tuple = import_mappings.insert ({use_dec_id, {}});
- // We then get that tuple's first member, which will be an iterator to the
- // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly
- // created empty vector (plus its key since this is a hashmap iterator).
- // we then access the second member of the pair to get access to the
- // vector directly.
- auto &imports = tuple.first->second;
+ auto &imports = import_mappings.new_or_access (use_dec_id);
imports.emplace_back (
- std::make_pair (std::move (rebind_import),
- ImportData::Rebind (std::move (definitions))));
+ ImportPair (std::move (rebind_import),
+ ImportData::Rebind (std::move (definitions))));
return true;
}
Rib::Definition glob_module;
};
+ struct ImportPair
+ {
+ TopLevel::ImportKind import_kind;
+ ImportData data;
+
+ explicit ImportPair (TopLevel::ImportKind &&kind, ImportData &&data)
+ : import_kind (std::move (kind)), data (std::move (data))
+ {}
+ };
+
+ class ImportMappings
+ {
+ public:
+ std::vector<ImportPair> &new_or_access (NodeId path_id)
+ {
+ // We insert an empty vector, unless an element was already present for
+ // `use_dec_id` - which is returned in the tuple's first member
+ auto iter = mappings.insert ({{path_id}, {}});
+
+ // We then get that tuple's first member, which will be an iterator to the
+ // existing vec<pair<ImportKind, ImportData>> OR an iterator to our newly
+ // created empty vector (plus its key since this is a hashmap iterator).
+ // we then access the second member of the pair to get access to the
+ // vector directly.
+ return iter.first->second;
+ }
+
+ void insert (NodeId path_id, std::vector<ImportPair> &&pairs)
+ {
+ mappings.insert ({{path_id}, std::move (pairs)});
+ }
+
+ // Same as `insert`, but with just one node
+ void insert (NodeId path_id, ImportPair &&pair)
+ {
+ mappings.insert ({{path_id}, {pair}});
+ }
+
+ std::vector<ImportPair> &get (NodeId use_id) { return mappings[use_id]; }
+
+ private:
+ // Each path can import in multiple namespaces, hence the mapping from one
+ // path to a vector of import pairs
+ std::unordered_map<NodeId, std::vector<ImportPair>> mappings;
+ };
+
private:
void visit_attributes (std::vector<AST::Attribute> &attrs);
std::vector<std::unordered_map<std::string, NodeId>> scopes;
};
- // TODO: This is becoming a very complex type - ugly
// Mappings between an import and the definition it imports
- std::unordered_map<NodeId,
- std::vector<std::pair<TopLevel::ImportKind, ImportData>>>
- import_mappings;
+ ImportMappings import_mappings;
// FIXME: Documentation
// Call this on all the paths of a UseDec - so each flattened path in a
}
void
-finalize_simple_import (
- TopLevel &toplevel,
- const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping)
+finalize_simple_import (TopLevel &toplevel, const Early::ImportPair &mapping)
{
// FIXME: We probably need to store namespace information
- auto locus = mapping.first.to_resolve.get_locus ();
- auto data = mapping.second;
+ auto locus = mapping.import_kind.to_resolve.get_locus ();
+ auto data = mapping.data;
auto identifier
- = mapping.first.to_resolve.get_final_segment ().get_segment_name ();
+ = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
for (auto &&definition : data.definitions ())
toplevel
}
void
-finalize_glob_import (
- NameResolutionContext &ctx,
- const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping)
+finalize_glob_import (NameResolutionContext &ctx,
+ const Early::ImportPair &mapping)
{
auto module = Analysis::Mappings::get ().lookup_ast_module (
- mapping.second.module ().get_node_id ());
+ mapping.data.module ().get_node_id ());
rust_assert (module);
GlobbingVisitor glob_visitor (ctx);
}
void
-finalize_rebind_import (
- TopLevel &toplevel,
- const std::pair<TopLevel::ImportKind, Early::ImportData> &mapping)
+finalize_rebind_import (TopLevel &toplevel, const Early::ImportPair &mapping)
{
// We can fetch the value here as `resolve_rebind` will only be called on
// imports of the right kind
- auto &path = mapping.first.to_resolve;
- auto &rebind = mapping.first.rebind.value ();
- auto data = mapping.second;
+ auto &path = mapping.import_kind.to_resolve;
+ auto &rebind = mapping.import_kind.rebind.value ();
+ auto data = mapping.data;
location_t locus = UNKNOWN_LOCATION;
std::string declared_name;
declared_name, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
}
-FinalizeImports::FinalizeImports (
- std::unordered_map<
- NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
- &&data,
- TopLevel &toplevel, NameResolutionContext &ctx)
+FinalizeImports::FinalizeImports (Early::ImportMappings &&data,
+ TopLevel &toplevel,
+ NameResolutionContext &ctx)
: DefaultResolver (ctx), data (std::move (data)), toplevel (toplevel),
ctx (ctx)
{}
void
FinalizeImports::visit (AST::UseDeclaration &use)
{
- auto import_mappings = data[use.get_node_id ()];
+ auto import_mappings = data.get (use.get_node_id ());
for (const auto &mapping : import_mappings)
- switch (mapping.first.kind)
+ switch (mapping.import_kind.kind)
{
case TopLevel::ImportKind::Kind::Glob:
finalize_glob_import (ctx, mapping);
class FinalizeImports : DefaultResolver
{
public:
- FinalizeImports (
- std::unordered_map<
- NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
- &&data,
- TopLevel &toplevel, NameResolutionContext &ctx);
+ FinalizeImports (Early::ImportMappings &&data, TopLevel &toplevel,
+ NameResolutionContext &ctx);
void go (AST::Crate &crate);
private:
void visit (AST::UseDeclaration &) override;
- std::unordered_map<
- NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
- data;
+ Early::ImportMappings data;
TopLevel &toplevel;
NameResolutionContext &ctx;
};