namespace Rust {
namespace Resolver2_0 {
-Early::Early (NameResolutionContext &ctx) : DefaultResolver (ctx), dirty (false)
+Early::Early (NameResolutionContext &ctx)
+ : DefaultResolver (ctx), toplevel (TopLevel (ctx)), dirty (false)
{}
void
Early::go (AST::Crate &crate)
{
// First we go through TopLevel resolution to get all our declared items
- auto toplevel = TopLevel (ctx);
toplevel.go (crate);
// We start with resolving the list of imports that `TopLevel` has built for
// us
- for (auto &&import : toplevel.get_imports_to_resolve ())
- build_import_mapping (std::move (import));
-
- // Once this is done, we finalize their resolution
- FinalizeImports (std::move (import_mappings), toplevel, ctx).go (crate);
dirty = toplevel.is_dirty ();
// We now proceed with resolving macros, which can be nested in almost any
DefaultResolver::visit (s);
}
+void
+Early::finalize_simple_import (const Early::ImportPair &mapping)
+{
+ // FIXME: We probably need to store namespace information
+
+ auto locus = mapping.import_kind.to_resolve.get_locus ();
+ auto data = mapping.data;
+ auto identifier
+ = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
+
+ for (auto &&definition : data.definitions ())
+ toplevel
+ .insert_or_error_out (
+ identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
+}
+
+void
+Early::finalize_glob_import (NameResolutionContext &ctx,
+ const Early::ImportPair &mapping)
+{
+ auto module = Analysis::Mappings::get ().lookup_ast_module (
+ mapping.data.module ().get_node_id ());
+ rust_assert (module);
+
+ GlobbingVisitor glob_visitor (ctx);
+ glob_visitor.go (module.value ());
+}
+
+void
+Early::finalize_rebind_import (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.import_kind.to_resolve;
+ auto &rebind = mapping.import_kind.rebind.value ();
+ auto data = mapping.data;
+
+ location_t locus = UNKNOWN_LOCATION;
+ std::string declared_name;
+
+ // FIXME: This needs to be done in `FinalizeImports`
+ switch (rebind.get_new_bind_type ())
+ {
+ case AST::UseTreeRebind::NewBindType::IDENTIFIER:
+ declared_name = rebind.get_identifier ().as_string ();
+ locus = rebind.get_identifier ().get_locus ();
+ break;
+ case AST::UseTreeRebind::NewBindType::NONE:
+ declared_name = path.get_final_segment ().as_string ();
+ locus = path.get_final_segment ().get_locus ();
+ break;
+ case AST::UseTreeRebind::NewBindType::WILDCARD:
+ rust_unreachable ();
+ break;
+ }
+
+ for (auto &&definition : data.definitions ())
+ toplevel.insert_or_error_out (
+ 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 */);
+}
+
+void
+Early::visit (AST::UseDeclaration &decl)
+{
+ auto &imports = toplevel.get_imports_to_resolve ();
+ auto current_import = imports.find (decl.get_node_id ());
+ if (current_import != imports.end ())
+ {
+ build_import_mapping (*current_import);
+ }
+
+ // Once this is done, we finalize their resolution
+ for (const auto &mapping : import_mappings.get (decl.get_node_id ()))
+ switch (mapping.import_kind.kind)
+ {
+ case TopLevel::ImportKind::Kind::Glob:
+ finalize_glob_import (ctx, mapping);
+ break;
+ case TopLevel::ImportKind::Kind::Simple:
+ finalize_simple_import (mapping);
+ break;
+ case TopLevel::ImportKind::Kind::Rebind:
+ finalize_rebind_import (mapping);
+ break;
+ }
+
+ DefaultResolver::visit (decl);
+}
+
} // namespace Resolver2_0
} // namespace Rust
{
using DefaultResolver::visit;
+ TopLevel toplevel;
bool dirty;
public:
void visit (AST::Function &) override;
void visit (AST::StructStruct &) override;
+ void visit (AST::UseDeclaration &) override;
struct ImportData
{
std::vector<Error> macro_resolve_errors;
void collect_error (Error e) { macro_resolve_errors.push_back (e); }
+
+ void finalize_simple_import (const Early::ImportPair &mapping);
+
+ void finalize_glob_import (NameResolutionContext &ctx,
+ const Early::ImportPair &mapping);
+
+ void finalize_rebind_import (const Early::ImportPair &mapping);
};
} // namespace Resolver2_0
// Handle cycles ?
}
-void
-finalize_simple_import (TopLevel &toplevel, const Early::ImportPair &mapping)
-{
- // FIXME: We probably need to store namespace information
-
- auto locus = mapping.import_kind.to_resolve.get_locus ();
- auto data = mapping.data;
- auto identifier
- = mapping.import_kind.to_resolve.get_final_segment ().get_segment_name ();
-
- for (auto &&definition : data.definitions ())
- toplevel
- .insert_or_error_out (
- identifier, locus, definition.first.get_node_id (), definition.second /* TODO: This isn't clear - it would be better if it was called .ns or something */);
-}
-
-void
-finalize_glob_import (NameResolutionContext &ctx,
- const Early::ImportPair &mapping)
-{
- auto module = Analysis::Mappings::get ().lookup_ast_module (
- mapping.data.module ().get_node_id ());
- rust_assert (module);
-
- GlobbingVisitor glob_visitor (ctx);
- glob_visitor.go (module.value ());
-}
-
-void
-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.import_kind.to_resolve;
- auto &rebind = mapping.import_kind.rebind.value ();
- auto data = mapping.data;
-
- location_t locus = UNKNOWN_LOCATION;
- std::string declared_name;
-
- // FIXME: This needs to be done in `FinalizeImports`
- switch (rebind.get_new_bind_type ())
- {
- case AST::UseTreeRebind::NewBindType::IDENTIFIER:
- declared_name = rebind.get_identifier ().as_string ();
- locus = rebind.get_identifier ().get_locus ();
- break;
- case AST::UseTreeRebind::NewBindType::NONE:
- declared_name = path.get_final_segment ().as_string ();
- locus = path.get_final_segment ().get_locus ();
- break;
- case AST::UseTreeRebind::NewBindType::WILDCARD:
- rust_unreachable ();
- break;
- }
-
- for (auto &&definition : data.definitions ())
- toplevel.insert_or_error_out (
- 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 (Early::ImportMappings &&data,
TopLevel &toplevel,
NameResolutionContext &ctx)
void
FinalizeImports::visit (AST::UseDeclaration &use)
-{
- auto import_mappings = data.get (use.get_node_id ());
-
- for (const auto &mapping : import_mappings)
- switch (mapping.import_kind.kind)
- {
- case TopLevel::ImportKind::Kind::Glob:
- finalize_glob_import (ctx, mapping);
- break;
- case TopLevel::ImportKind::Kind::Simple:
- finalize_simple_import (toplevel, mapping);
- break;
- case TopLevel::ImportKind::Kind::Rebind:
- finalize_rebind_import (toplevel, mapping);
- break;
- }
-}
+{}
} // namespace Resolver2_0
} // namespace Rust
void go (AST::Crate &crate);
+ void visit (AST::UseDeclaration &) override;
+
private:
using AST::DefaultASTVisitor::visit;
- void visit (AST::UseDeclaration &) override;
-
Early::ImportMappings data;
TopLevel &toplevel;
NameResolutionContext &ctx;
{}
};
- std::unordered_map<NodeId, std::vector<ImportKind>> &&
- get_imports_to_resolve ()
+ std::unordered_map<NodeId, std::vector<ImportKind>> &get_imports_to_resolve ()
{
- return std::move (imports_to_resolve);
+ return imports_to_resolve;
}
void check_multiple_insertion_error (