build_import_mapping (std::move (import));
// Once this is done, we finalize their resolution
- FinalizeImports::go (import_mappings, toplevel, ctx);
+ FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
// We now proceed with resolving macros, which can be nested in almost any
// items
}
bool
-Early::resolve_glob_import (TopLevel::ImportKind &&glob)
+Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
{
auto resolved = ctx.types.resolve_path (glob.to_resolve.get_segments ());
if (!resolved.has_value ())
// here, we insert the module's NodeId into the import_mappings and will look
// up the module proper in `FinalizeImports`
// The namespace does not matter here since we are dealing with a glob
- import_mappings.insert ({std::move (glob), ImportData::Glob (*resolved)});
+ // TODO: Ugly
+ import_mappings.insert (
+ {use_dec_id, {{std::move (glob), ImportData::Glob (*resolved)}}});
return true;
}
bool
-Early::resolve_simple_import (TopLevel::ImportKind &&import)
+Early::resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind &&import)
{
return ctx.resolve_path (import.to_resolve)
.map ([&] (std::pair<Rib::Definition, Namespace> def_ns) {
- import_mappings.insert (
- {std::move (import), ImportData::Simple (def_ns)});
+ // 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;
+
+ imports.emplace_back (
+ std::make_pair (std::move (import), ImportData::Simple (def_ns)));
})
.has_value ();
}
bool
-Early::resolve_rebind_import (TopLevel::ImportKind &&rebind_import)
+Early::resolve_rebind_import (NodeId use_dec_id,
+ TopLevel::ImportKind &&rebind_import)
{
return ctx.resolve_path (rebind_import.to_resolve)
.map ([&] (std::pair<Rib::Definition, Namespace> def_ns) {
- import_mappings.insert (
- {std::move (rebind_import), ImportData::Rebind (def_ns)});
+ // 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;
+
+ imports.emplace_back (std::make_pair (std::move (rebind_import),
+ ImportData::Rebind (def_ns)));
})
.has_value ();
}
void
-Early::build_import_mapping (TopLevel::ImportKind &&import)
+Early::build_import_mapping (
+ std::pair<NodeId, std::vector<TopLevel::ImportKind>> &&use_import)
{
auto found = false;
+ auto use_dec_id = use_import.first;
- // We create a copy of the path in case of errors, since the `import` will
- // be moved into the newly created import mappings
- auto path = import.to_resolve;
-
- switch (import.kind)
+ for (auto &&import : use_import.second)
{
- case TopLevel::ImportKind::Kind::Glob:
- found = resolve_glob_import (std::move (import));
- break;
- case TopLevel::ImportKind::Kind::Simple:
- found = resolve_simple_import (std::move (import));
- break;
- case TopLevel::ImportKind::Kind::Rebind:
- found = resolve_rebind_import (std::move (import));
- break;
- }
+ // We create a copy of the path in case of errors, since the `import` will
+ // be moved into the newly created import mappings
+ auto path = import.to_resolve;
+
+ switch (import.kind)
+ {
+ case TopLevel::ImportKind::Kind::Glob:
+ found = resolve_glob_import (use_dec_id, std::move (import));
+ break;
+ case TopLevel::ImportKind::Kind::Simple:
+ found = resolve_simple_import (use_dec_id, std::move (import));
+ break;
+ case TopLevel::ImportKind::Kind::Rebind:
+ found = resolve_rebind_import (use_dec_id, std::move (import));
+ break;
+ }
- if (!found)
- rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
- "unresolved import %qs", path.as_string ().c_str ());
+ if (!found)
+ rust_error_at (path.get_final_segment ().get_locus (), ErrorCode::E0433,
+ "unresolved import %qs", path.as_string ().c_str ());
+ }
}
void
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::map<TopLevel::ImportKind, ImportData> import_mappings;
+ std::unordered_map<NodeId,
+ std::vector<std::pair<TopLevel::ImportKind, ImportData>>>
+ import_mappings;
// FIXME: Documentation
// Call this on all the paths of a UseDec - so each flattened path in a
// UseTreeList for example
// FIXME: Should that return `found`?
- bool resolve_simple_import (TopLevel::ImportKind &&import);
- bool resolve_glob_import (TopLevel::ImportKind &&glob_import);
- bool resolve_rebind_import (TopLevel::ImportKind &&rebind_import);
+ bool resolve_simple_import (NodeId use_dec_id, TopLevel::ImportKind &&import);
+ bool resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&import);
+ bool resolve_rebind_import (NodeId use_dec_id, TopLevel::ImportKind &&import);
// Handle an import, resolving it to its definition and adding it to the list
// of import mappings
- void build_import_mapping (TopLevel::ImportKind &&import);
+ void build_import_mapping (
+ std::pair<NodeId, std::vector<TopLevel::ImportKind>> &&use_import);
TextualScope textual_scope;
std::vector<Error> macro_resolve_errors;
// <http://www.gnu.org/licenses/>.
#include "rust-finalize-imports-2.0.h"
+#include "rust-default-resolver.h"
#include "rust-hir-map.h"
#include "rust-name-resolution-context.h"
#include "rust-rib.h"
data.ns.value ());
}
-void
-FinalizeImports::go (
- std::map<TopLevel::ImportKind, Early::ImportData> import_mappings,
+FinalizeImports::FinalizeImports (
+ std::unordered_map<
+ NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
+ &&data,
TopLevel &toplevel, NameResolutionContext &ctx)
+ : DefaultResolver (ctx), data (std::move (data)), toplevel (toplevel),
+ ctx (ctx)
+{}
+
+void
+FinalizeImports::go (AST::Crate &crate)
{
+ for (auto &item : crate.items)
+ item->accept_vis (*this);
+}
+
+void
+FinalizeImports::visit (AST::UseDeclaration &use)
+{
+ auto import_mappings = data[use.get_node_id ()];
+
for (const auto &mapping : import_mappings)
switch (mapping.first.kind)
{
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+#include "rust-ast.h"
+#include "rust-expr.h"
#include "rust-name-resolution-context.h"
#include "rust-toplevel-name-resolver-2.0.h"
#include "rust-early-name-resolver-2.0.h"
// each ImportKind - easy!
// - yay!
-class FinalizeImports
+class FinalizeImports : DefaultResolver
{
public:
- static void
- go (std::map<TopLevel::ImportKind, Early::ImportData> import_mappings,
- TopLevel &toplevel, NameResolutionContext &ctx);
+ FinalizeImports (
+ std::unordered_map<
+ NodeId, std::vector<std::pair<TopLevel::ImportKind, Early::ImportData>>>
+ &&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;
+ TopLevel &toplevel;
+ NameResolutionContext &ctx;
};
} // namespace Resolver2_0
const auto &tree = use.get_tree ();
flatten (tree.get (), paths, glob_path, rebind_path, this->ctx);
+ auto imports = std::vector<ImportKind> ();
+
for (auto &&path : paths)
- imports_to_resolve.emplace_back (
+ imports.emplace_back (
ImportKind::Simple (std::move (path), values_rib, types_rib, macros_rib));
for (auto &&glob : glob_path)
- imports_to_resolve.emplace_back (
+ imports.emplace_back (
ImportKind::Glob (std::move (glob), values_rib, types_rib, macros_rib));
for (auto &&rebind : rebind_path)
- imports_to_resolve.emplace_back (
+ imports.emplace_back (
ImportKind::Rebind (std::move (rebind.first), std::move (rebind.second),
values_rib, types_rib, macros_rib));
+
+ imports_to_resolve.insert ({use.get_node_id (), std::move (imports)});
}
} // namespace Resolver2_0