22
22
#include " swift/AST/ASTVisitor.h"
23
23
#include " swift/AST/Identifier.h"
24
24
#include " swift/AST/Module.h"
25
+ #include " swift/Basic/NullablePtr.h"
25
26
#include " swift/Basic/SourceLoc.h"
26
27
27
28
namespace swift {
@@ -36,52 +37,91 @@ namespace swift {
36
37
class TypeDecl ;
37
38
class ValueDecl ;
38
39
struct SelfBounds ;
40
+ class PatternBindingInitializer ;
41
+ class DefaultArgumentInitializer ;
42
+ class NominalTypeDecl ;
43
+
44
+ namespace ast_scope {
45
+ class ASTSourceFileScope ;
46
+ class ASTScopeImpl ;
47
+ } // namespace ast_scope
48
+
49
+ // / LookupResultEntry - One result of unqualified lookup.
50
+ struct LookupResultEntry {
51
+ private:
52
+ // / The declaration context through which we found \c Value. For instance,
53
+ // / \code
54
+ // / class BaseClass {
55
+ // / func foo() {}
56
+ // / }
57
+ // /
58
+ // / class DerivedClass : BaseClass {
59
+ // / func bar() {}
60
+ // / }
61
+ // / \endcode
62
+ // /
63
+ // / When finding \c foo() from the body of \c DerivedClass, \c BaseDC is \c
64
+ // / DerivedClass.
65
+ // /
66
+ // / Another example:
67
+ // / \code
68
+ // / class BaseClass {
69
+ // / func bar() {}
70
+ // / func foo() {}
71
+ // / }
72
+ // / \endcode
73
+ // /
74
+ // / When finding \c bar() from the function body of \c foo(), \c BaseDC is
75
+ // / the method \c foo().
76
+ // /
77
+ // / \c BaseDC will be the method if \c self is needed for the lookup,
78
+ // / and will be the type if not.
79
+ // / In other words: If \c baseDC is a method, it means you found an instance
80
+ // / member and you should add an implicit 'self.' (Each method has its own
81
+ // / implicit self decl.) There's one other kind of non-method context that
82
+ // / has a 'self.' -- a lazy property initializer, which unlike a non-lazy
83
+ // / property can reference \c self) Hence: \code
84
+ // / class Outer {
85
+ // / static func s()
86
+ // / func i()
87
+ // / class Inner {
88
+ // / static func ss()
89
+ // / func ii() {
90
+ // / func F() {
91
+ // / ii() // OK! implicitly self.ii; BaseDC is the method
92
+ // / s() // OK! s() is defined in an outer type; BaseDC is the type
93
+ // / ss() // error: must write /Inner.ss() here since its static
94
+ // / i() // error: there's no outer 'self.'
95
+ // / }
96
+ // / }
97
+ // / \endcode
98
+ // /
99
+ // / To sum up: The distinction is whether you need to know the run-time
100
+ // / value of \c self. It might be clearer if \code baseDC was always a type,
101
+ // / and there was an additional \c ParamDecl field in \c LookupResult which
102
+ // / would store the implicit self, if any. \c BaseDC is always one of your
103
+ // / outer DCs. if you're inside a type it should never be an extension of
104
+ // / that type. And if you're inside an extension it will always be an
105
+ // / extension (if it found something at that level).
106
+ DeclContext *BaseDC;
39
107
40
- // / LookupResultEntry - One result of unqualified lookup.
41
- struct LookupResultEntry {
42
- private:
43
-
44
- // / The declaration context through which we found Value. For instance,
45
- // / class BaseClass {
46
- // / func foo() {}
47
- // / }
48
- // /
49
- // / class DerivedClass : BaseClass {
50
- // / func bar() {}
51
- // / }
52
- // /
53
- // / When finding foo() from the body of DerivedClass, BaseDC is DerivedClass.
54
- // /
55
- // / Another example:
56
- // /
57
- // / class BaseClass {
58
- // / func bar() {}
59
- // / func foo() {}
60
- // / }
61
- // /
62
- // / When finding bar() from the function body of foo(), BaseDC is the method
63
- // / foo().
64
- DeclContext *BaseDC;
108
+ // / The declaration corresponds to the given name; i.e. the decl we are
109
+ // / looking up.
110
+ ValueDecl *Value;
65
111
66
- // / The declaration corresponds to the given name; i.e. the decl we are
67
- // / looking up.
68
- ValueDecl *Value;
112
+ public:
113
+ LookupResultEntry (ValueDecl *value) : BaseDC(nullptr ), Value(value) {}
69
114
70
- public:
71
- LookupResultEntry (ValueDecl *value) : BaseDC(nullptr ), Value(value) { }
115
+ LookupResultEntry (DeclContext *baseDC, ValueDecl *value)
116
+ : BaseDC(baseDC ), Value(value) {}
72
117
73
- LookupResultEntry (DeclContext *baseDC, ValueDecl *value)
74
- : BaseDC(baseDC), Value(value) { }
118
+ ValueDecl *getValueDecl () const { return Value; }
75
119
76
- ValueDecl *getValueDecl () const {
77
- return Value;
78
- }
120
+ DeclContext *getDeclContext () const { return BaseDC; }
79
121
80
- DeclContext *getDeclContext () const {
81
- return BaseDC;
82
- }
122
+ ValueDecl *getBaseDecl () const ;
83
123
84
- ValueDecl * getBaseDecl ( ) const ;
124
+ void print (llvm::raw_ostream & ) const ;
85
125
};
86
126
87
127
// / This class implements and represents the result of performing
@@ -110,13 +150,13 @@ class UnqualifiedLookup {
110
150
// / is used to determine which declarations in that body are visible.
111
151
UnqualifiedLookup (DeclName Name, DeclContext *DC, LazyResolver *TypeResolver,
112
152
SourceLoc Loc = SourceLoc(), Options options = Options());
113
-
114
- SmallVector<LookupResultEntry, 4 > Results;
153
+ using ResultsVector = SmallVector<LookupResultEntry, 4 >;
154
+ ResultsVector Results;
115
155
// / The index of the first result that isn't from the innermost scope
116
156
// / with results.
117
157
// /
118
158
// / That is, \c makeArrayRef(Results).take_front(IndexOfFirstOuterResults)
119
- // / will be Results from the innermost scope that had results, and the
159
+ // / will be \c Results from the innermost scope that had results, and the
120
160
// / remaining elements of Results will be from parent scopes of this one.
121
161
// /
122
162
// / Allows unqualified name lookup to return results from outer scopes.
@@ -136,7 +176,6 @@ inline UnqualifiedLookup::Options operator|(UnqualifiedLookup::Flags flag1,
136
176
return UnqualifiedLookup::Options (flag1) | flag2;
137
177
}
138
178
139
-
140
179
// / Describes the reason why a certain declaration is visible.
141
180
enum class DeclVisibilityKind {
142
181
// / Declaration is a local variable or type.
@@ -536,8 +575,91 @@ class FindLocalVal : public StmtVisitor<FindLocalVal> {
536
575
void visitCatchStmt (CatchStmt *S);
537
576
538
577
};
578
+
579
+
580
+ // / The bridge between the legacy UnqualifedLookupFactory and the new ASTScope
581
+ // / lookup system
582
+ class AbstractASTScopeDeclConsumer {
583
+ public:
584
+ AbstractASTScopeDeclConsumer () {}
585
+
586
+ virtual ~AbstractASTScopeDeclConsumer () = default ;
587
+
588
+ // / Called for every ValueDecl visible from the lookup.
589
+ // / Returns true if the lookup can be stopped at this point.
590
+ // / BaseDC is per legacy
591
+ // / Takes an array in order to batch the consumption before setting
592
+ // / IndexOfFirstOuterResult when necessary.
593
+ virtual bool consume (ArrayRef<ValueDecl *> values, DeclVisibilityKind vis,
594
+ NullablePtr<DeclContext> baseDC = nullptr ) = 0;
595
+
596
+ // / Eventually this functionality should move into ASTScopeLookup
597
+ virtual std::pair<bool , Optional<bool >>
598
+ lookupInSelfType (NullablePtr<DeclContext> selfDC, DeclContext *const scopeDC,
599
+ NominalTypeDecl *const nominal,
600
+ Optional<bool > isCascadingUse) = 0 ;
601
+
602
+ virtual void stopForDebuggingIfTargetLookup () = 0;
603
+ };
604
+
605
+ // / Just used to print
606
+ // / Used to gather lookup results
607
+ class ASTScopeDeclGatherer : public AbstractASTScopeDeclConsumer {
608
+ SmallVector<ValueDecl *, 32 > values;
609
+
610
+ public:
611
+ virtual ~ASTScopeDeclGatherer () = default ;
612
+
613
+ bool consume (ArrayRef<ValueDecl *> values, DeclVisibilityKind vis,
614
+ NullablePtr<DeclContext> baseDC = nullptr ) override ;
539
615
616
+ // / Eventually this functionality should move into ASTScopeLookup
617
+ std::pair<bool , Optional<bool >>
618
+ lookupInSelfType (NullablePtr<DeclContext>, DeclContext *const ,
619
+ NominalTypeDecl *const ,
620
+ Optional<bool > isCascadingUse) override {
621
+ return std::make_pair (false , isCascadingUse);
622
+ }
623
+
624
+ void stopForDebuggingIfTargetLookup () override {}
625
+
626
+ ArrayRef<ValueDecl *> getDecls () { return values; }
627
+ };
540
628
} // end namespace namelookup
629
+
630
+ // / The interface into the ASTScope subsystem
631
+ class ASTScope {
632
+ friend class ast_scope ::ASTScopeImpl;
633
+ ast_scope::ASTSourceFileScope *const impl;
634
+
635
+ public:
636
+ ASTScope (ast_scope::ASTSourceFileScope *sfs) : impl(sfs) {}
637
+ static ASTScope *createScopeTreeFor (SourceFile *);
638
+ static Optional<bool >
639
+ unqualifiedLookup (SourceFile *, DeclName, SourceLoc,
640
+ const DeclContext *startingContext,
641
+ Optional<bool > isCascadingUse,
642
+ namelookup::AbstractASTScopeDeclConsumer &);
643
+
644
+ void dump () const ;
645
+ void print (llvm::raw_ostream &) const ;
646
+ void dumpOneScopeMapLocation (std::pair<unsigned , unsigned >) const ;
647
+
648
+ // Make vanilla new illegal for ASTScopes.
649
+ void *operator new (size_t bytes) = delete ;
650
+ // Need this because have virtual destructors
651
+ void operator delete (void *data) {}
652
+
653
+ // Only allow allocation of scopes using the allocator of a particular source
654
+ // file.
655
+ void *operator new (size_t bytes, const ASTContext &ctx,
656
+ unsigned alignment = alignof(ASTScope));
657
+ void *operator new (size_t Bytes, void *Mem) {
658
+ assert (Mem);
659
+ return Mem;
660
+ }
661
+ };
662
+
541
663
} // end namespace swift
542
664
543
665
#endif
0 commit comments