@@ -1360,6 +1360,41 @@ class UseInteriorEntry {
13601360 std::vector<UseTreeEntry*> subtrees_;
13611361};
13621362
1363+ // Represents a record of a "leaf" imported by a `use` statement into the module
1364+ // scope -- note the `name_def`, this is the name definition that will be bound
1365+ // in the module scope.
1366+ //
1367+ // A `use` like `use foo::{bar, baz}` will result in two `UseSubject`s.
1368+ class UseSubject {
1369+ public:
1370+ UseSubject (std::vector<std::string> identifiers, NameDef& name_def,
1371+ UseTreeEntry& use_tree_entry);
1372+
1373+ absl::Span<std::string const > identifiers () const { return identifiers_; }
1374+ const NameDef& name_def () const { return *name_def_; }
1375+ const UseTreeEntry& use_tree_entry () const { return *use_tree_entry_; }
1376+ UseTreeEntry& use_tree_entry () { return *use_tree_entry_; }
1377+
1378+ std::vector<std::string>& mutable_identifiers () { return identifiers_; }
1379+
1380+ // Returns a string that represents the subject of the `use` statement in
1381+ // the form of a colon-ref; e.g. `foo::bar::baz`.
1382+ //
1383+ // Note that the returned value is surrounded in backticks.
1384+ std::string ToErrorString () const ;
1385+
1386+ private:
1387+ // The identifier in the subject path; e.g. in `use foo::bar::baz` the
1388+ // identifiers are {`foo`, `bar`, `baz`}.
1389+ std::vector<std::string> identifiers_;
1390+
1391+ // The name definition that will be bound in the module scope.
1392+ const NameDef* name_def_;
1393+
1394+ // Use tree entry that wraps the `name_def`.
1395+ UseTreeEntry* use_tree_entry_;
1396+ };
1397+
13631398// Arbitrary entry (interior or leaf) in the `use` construct tree.
13641399class UseTreeEntry : public AstNode {
13651400 public:
@@ -1385,6 +1420,11 @@ class UseTreeEntry : public AstNode {
13851420 }
13861421 const Span& span () const { return span_; }
13871422
1423+ // Note: this is non-const because we capture a mutable AST node pointer in
1424+ // the results.
1425+ void LinearizeToSubjects (std::vector<std::string>& prefix,
1426+ std::vector<UseSubject>& results);
1427+
13881428 private:
13891429 std::variant<UseInteriorEntry, NameDef*> payload_;
13901430 Span span_;
@@ -1426,13 +1466,27 @@ class Use : public AstNode {
14261466
14271467 std::vector<AstNode*> GetChildren (bool want_types) const override ;
14281468
1469+ // Returns all the identifiers of the `NameDef`s at the leaves of the tree.
14291470 std::vector<std::string> GetLeafIdentifiers () const {
14301471 return root_->GetLeafIdentifiers ();
14311472 }
14321473 std::vector<NameDef*> GetLeafNameDefs () const {
14331474 return root_->GetLeafNameDefs ();
14341475 }
14351476
1477+ // Returns a vector of `UseSubject`s that represent the "subjects" (i.e.
1478+ // individual imported entities that get a name binding in the module) of
1479+ // the `use` statement.
1480+ //
1481+ // Note: this is non-const because we capture a mutable AST node pointer in
1482+ // the results.
1483+ std::vector<UseSubject> LinearizeToSubjects () {
1484+ std::vector<std::string> prefix;
1485+ std::vector<UseSubject> results;
1486+ root_->LinearizeToSubjects (prefix, results);
1487+ return results;
1488+ }
1489+
14361490 UseTreeEntry& root () { return *root_; }
14371491 const UseTreeEntry& root () const { return *root_; }
14381492 const Span& span () const { return span_; }
0 commit comments