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