Skip to content

Commit 6b98f8f

Browse files
committed
ASTScope: Add a new lookupSingleLocalDecl() entry point
This is used in a few places that used to expect parsed but not yet type-checked code to contain DeclRefExprs that reference local bindings. Instead, we can call lookupSingleLocalDecl() with an UnresolvedDeclRefExpr instead.
1 parent 29ce772 commit 6b98f8f

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

include/swift/AST/NameLookup.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,14 @@ class ASTScope {
684684
static void unqualifiedLookup(SourceFile *, SourceLoc,
685685
namelookup::AbstractASTScopeDeclConsumer &);
686686

687+
/// Lookup that only finds local declarations and does not trigger
688+
/// interface type computation.
689+
static void lookupLocalDecls(SourceFile *, DeclName, SourceLoc,
690+
SmallVectorImpl<ValueDecl *> &);
691+
692+
/// Returns the result if there is exactly one, nullptr otherwise.
693+
static ValueDecl *lookupSingleLocalDecl(SourceFile *, DeclName, SourceLoc);
694+
687695
/// Entry point to record the visible statement labels from the given
688696
/// point.
689697
///

lib/AST/UnqualifiedLookup.cpp

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,4 +778,59 @@ unsigned UnqualifiedLookupFactory::lookupCounter = 0;
778778
// set to ~0 when not debugging
779779
const unsigned UnqualifiedLookupFactory::targetLookup = ~0;
780780

781-
#endif // NDEBUG
781+
namespace {
782+
783+
class ASTScopeDeclConsumerForLocalLookup
784+
: public AbstractASTScopeDeclConsumer {
785+
SmallVectorImpl<ValueDecl *> &results;
786+
DeclName name;
787+
788+
public:
789+
ASTScopeDeclConsumerForLocalLookup(
790+
SmallVectorImpl<ValueDecl *> &results, DeclName name)
791+
: results(results), name(name) {}
792+
793+
bool consume(ArrayRef<ValueDecl *> values, DeclVisibilityKind vis,
794+
NullablePtr<DeclContext> baseDC) override {
795+
for (auto *value: values) {
796+
if (!value->getName().matchesRef(name))
797+
continue;
798+
799+
results.push_back(value);
800+
}
801+
802+
return !results.empty();
803+
}
804+
805+
bool lookInMembers(DeclContext *const,
806+
NominalTypeDecl *const) override {
807+
return true;
808+
}
809+
810+
#ifndef NDEBUG
811+
void startingNextLookupStep() override {}
812+
void finishingLookup(std::string) const override {}
813+
bool isTargetLookup() const override { return false; }
814+
#endif
815+
};
816+
817+
}
818+
819+
/// Lookup that only finds local declarations and does not trigger
820+
/// interface type computation.
821+
void ASTScope::lookupLocalDecls(SourceFile *sf, DeclName name, SourceLoc loc,
822+
SmallVectorImpl<ValueDecl *> &results) {
823+
ASTScopeDeclConsumerForLocalLookup consumer(results, name);
824+
ASTScope::unqualifiedLookup(sf, loc, consumer);
825+
}
826+
827+
ValueDecl *ASTScope::lookupSingleLocalDecl(SourceFile *sf, DeclName name,
828+
SourceLoc loc) {
829+
SmallVector<ValueDecl *, 1> result;
830+
ASTScope::lookupLocalDecls(sf, name, loc, result);
831+
if (result.size() != 1)
832+
return nullptr;
833+
return result[0];
834+
}
835+
836+
#endif // NDEBUG

0 commit comments

Comments
 (0)