Skip to content

Commit 75ab0a5

Browse files
committed
[AST] Break dependency cycle between swiftAST and swiftSema
AST/LookupVisibleDecls.cpp has a dependency on swiftSema by having doGlobalExtensionLookup call into swift::isExtensionApplied, and doGlobalExtensionLookup is ultimately used by the other global functions in that file. Break the cycle by moving the file into the swiftSema library.
1 parent 9694851 commit 75ab0a5

File tree

7 files changed

+280
-268
lines changed

7 files changed

+280
-268
lines changed

include/swift/AST/NameLookup.h

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "llvm/ADT/SmallPtrSet.h"
2121
#include "llvm/ADT/SmallVector.h"
22+
#include "swift/AST/ASTVisitor.h"
2223
#include "swift/AST/Identifier.h"
2324
#include "swift/AST/Module.h"
2425
#include "swift/Basic/SourceLoc.h"
@@ -381,6 +382,85 @@ getDirectlyInheritedNominalTypeDecls(
381382
SelfBounds getSelfBoundsFromWhereClause(
382383
llvm::PointerUnion<TypeDecl *, ExtensionDecl *> decl);
383384

385+
namespace namelookup {
386+
387+
/// Performs a qualified lookup into the given module and, if necessary, its
388+
/// reexports, observing proper shadowing rules.
389+
void
390+
lookupVisibleDeclsInModule(ModuleDecl *M, ModuleDecl::AccessPathTy accessPath,
391+
SmallVectorImpl<ValueDecl *> &decls,
392+
NLKind lookupKind,
393+
ResolutionKind resolutionKind,
394+
LazyResolver *typeResolver,
395+
const DeclContext *moduleScopeContext,
396+
ArrayRef<ModuleDecl::ImportedModule> extraImports = {});
397+
398+
/// Searches through statements and patterns for local variable declarations.
399+
class FindLocalVal : public StmtVisitor<FindLocalVal> {
400+
friend class ASTVisitor<FindLocalVal>;
401+
402+
const SourceManager &SM;
403+
SourceLoc Loc;
404+
VisibleDeclConsumer &Consumer;
405+
406+
public:
407+
FindLocalVal(const SourceManager &SM, SourceLoc Loc,
408+
VisibleDeclConsumer &Consumer)
409+
: SM(SM), Loc(Loc), Consumer(Consumer) {}
410+
411+
void checkValueDecl(ValueDecl *D, DeclVisibilityKind Reason) {
412+
Consumer.foundDecl(D, Reason);
413+
}
414+
415+
void checkPattern(const Pattern *Pat, DeclVisibilityKind Reason);
416+
417+
void checkParameterList(const ParameterList *params);
418+
419+
void checkGenericParams(GenericParamList *Params);
420+
421+
void checkSourceFile(const SourceFile &SF);
422+
423+
private:
424+
bool isReferencePointInRange(SourceRange R) {
425+
return SM.rangeContainsTokenLoc(R, Loc);
426+
}
427+
428+
void visitBreakStmt(BreakStmt *) {}
429+
void visitContinueStmt(ContinueStmt *) {}
430+
void visitFallthroughStmt(FallthroughStmt *) {}
431+
void visitFailStmt(FailStmt *) {}
432+
void visitReturnStmt(ReturnStmt *) {}
433+
void visitYieldStmt(YieldStmt *) {}
434+
void visitThrowStmt(ThrowStmt *) {}
435+
void visitPoundAssertStmt(PoundAssertStmt *) {}
436+
void visitDeferStmt(DeferStmt *DS) {
437+
// Nothing in the defer is visible.
438+
}
439+
440+
void checkStmtCondition(const StmtCondition &Cond);
441+
442+
void visitIfStmt(IfStmt *S);
443+
void visitGuardStmt(GuardStmt *S);
444+
445+
void visitWhileStmt(WhileStmt *S);
446+
void visitRepeatWhileStmt(RepeatWhileStmt *S);
447+
void visitDoStmt(DoStmt *S);
448+
449+
void visitForEachStmt(ForEachStmt *S);
450+
451+
void visitBraceStmt(BraceStmt *S, bool isTopLevelCode = false);
452+
453+
void visitSwitchStmt(SwitchStmt *S);
454+
455+
void visitCaseStmt(CaseStmt *S);
456+
457+
void visitDoCatchStmt(DoCatchStmt *S);
458+
void visitCatchClauses(ArrayRef<CatchStmt*> clauses);
459+
void visitCatchStmt(CatchStmt *S);
460+
461+
};
462+
463+
} // end namespace namelookup
384464
} // end namespace swift
385465

386466
#endif

lib/AST/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ add_swift_host_library(swiftAST STATIC
3737
Identifier.cpp
3838
InlinableText.cpp
3939
LayoutConstraint.cpp
40-
LookupVisibleDecls.cpp
4140
Module.cpp
4241
ModuleLoader.cpp
4342
ModuleNameLookup.cpp

lib/AST/ModuleNameLookup.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "NameLookupImpl.h"
1413
#include "swift/AST/NameLookup.h"
1514
#include "swift/AST/ASTContext.h"
1615
#include "swift/AST/LazyResolver.h"

lib/AST/NameLookup.cpp

Lines changed: 199 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#include "NameLookupImpl.h"
1817
#include "swift/AST/NameLookup.h"
1918
#include "swift/AST/ASTContext.h"
2019
#include "swift/AST/ASTScope.h"
@@ -25,6 +24,7 @@
2524
#include "swift/AST/LazyResolver.h"
2625
#include "swift/AST/Initializer.h"
2726
#include "swift/AST/NameLookupRequests.h"
27+
#include "swift/AST/ParameterList.h"
2828
#include "swift/AST/ReferencedNameTracker.h"
2929
#include "swift/Basic/SourceManager.h"
3030
#include "swift/Basic/Statistic.h"
@@ -38,6 +38,10 @@
3838

3939
using namespace swift;
4040

41+
void VisibleDeclConsumer::anchor() {}
42+
void VectorDeclConsumer::anchor() {}
43+
void NamedDeclConsumer::anchor() {}
44+
4145
ValueDecl *LookupResultEntry::getBaseDecl() const {
4246
if (BaseDC == nullptr)
4347
return nullptr;
@@ -2690,3 +2694,197 @@ swift::getDirectlyInheritedNominalTypeDecls(
26902694

26912695
return result;
26922696
}
2697+
2698+
namespace swift {
2699+
namespace namelookup {
2700+
2701+
void FindLocalVal::checkPattern(const Pattern *Pat, DeclVisibilityKind Reason) {
2702+
switch (Pat->getKind()) {
2703+
case PatternKind::Tuple:
2704+
for (auto &field : cast<TuplePattern>(Pat)->getElements())
2705+
checkPattern(field.getPattern(), Reason);
2706+
return;
2707+
case PatternKind::Paren:
2708+
case PatternKind::Typed:
2709+
case PatternKind::Var:
2710+
return checkPattern(Pat->getSemanticsProvidingPattern(), Reason);
2711+
case PatternKind::Named:
2712+
return checkValueDecl(cast<NamedPattern>(Pat)->getDecl(), Reason);
2713+
case PatternKind::EnumElement: {
2714+
auto *OP = cast<EnumElementPattern>(Pat);
2715+
if (OP->hasSubPattern())
2716+
checkPattern(OP->getSubPattern(), Reason);
2717+
return;
2718+
}
2719+
case PatternKind::OptionalSome:
2720+
checkPattern(cast<OptionalSomePattern>(Pat)->getSubPattern(), Reason);
2721+
return;
2722+
2723+
case PatternKind::Is: {
2724+
auto *isPat = cast<IsPattern>(Pat);
2725+
if (isPat->hasSubPattern())
2726+
checkPattern(isPat->getSubPattern(), Reason);
2727+
return;
2728+
}
2729+
2730+
// Handle non-vars.
2731+
case PatternKind::Bool:
2732+
case PatternKind::Expr:
2733+
case PatternKind::Any:
2734+
return;
2735+
}
2736+
}
2737+
2738+
void FindLocalVal::checkParameterList(const ParameterList *params) {
2739+
for (auto param : *params) {
2740+
checkValueDecl(param, DeclVisibilityKind::FunctionParameter);
2741+
}
2742+
}
2743+
2744+
void FindLocalVal::checkGenericParams(GenericParamList *Params) {
2745+
if (!Params)
2746+
return;
2747+
2748+
for (auto P : *Params)
2749+
checkValueDecl(P, DeclVisibilityKind::GenericParameter);
2750+
}
2751+
2752+
void FindLocalVal::checkSourceFile(const SourceFile &SF) {
2753+
for (Decl *D : SF.Decls)
2754+
if (auto *TLCD = dyn_cast<TopLevelCodeDecl>(D))
2755+
visitBraceStmt(TLCD->getBody(), /*isTopLevel=*/true);
2756+
}
2757+
2758+
void FindLocalVal::checkStmtCondition(const StmtCondition &Cond) {
2759+
SourceLoc start = SourceLoc();
2760+
for (auto entry : Cond) {
2761+
if (start.isInvalid())
2762+
start = entry.getStartLoc();
2763+
if (auto *P = entry.getPatternOrNull()) {
2764+
SourceRange previousConditionsToHere = SourceRange(start, entry.getEndLoc());
2765+
if (!isReferencePointInRange(previousConditionsToHere))
2766+
checkPattern(P, DeclVisibilityKind::LocalVariable);
2767+
}
2768+
}
2769+
}
2770+
2771+
void FindLocalVal::visitIfStmt(IfStmt *S) {
2772+
if (!isReferencePointInRange(S->getSourceRange()))
2773+
return;
2774+
2775+
if (!S->getElseStmt() ||
2776+
!isReferencePointInRange(S->getElseStmt()->getSourceRange())) {
2777+
checkStmtCondition(S->getCond());
2778+
}
2779+
2780+
visit(S->getThenStmt());
2781+
if (S->getElseStmt())
2782+
visit(S->getElseStmt());
2783+
}
2784+
2785+
void FindLocalVal::visitGuardStmt(GuardStmt *S) {
2786+
if (SM.isBeforeInBuffer(Loc, S->getStartLoc()))
2787+
return;
2788+
2789+
// Names in the guard aren't visible until after the body.
2790+
if (!isReferencePointInRange(S->getBody()->getSourceRange()))
2791+
checkStmtCondition(S->getCond());
2792+
2793+
visit(S->getBody());
2794+
}
2795+
2796+
void FindLocalVal::visitWhileStmt(WhileStmt *S) {
2797+
if (!isReferencePointInRange(S->getSourceRange()))
2798+
return;
2799+
2800+
checkStmtCondition(S->getCond());
2801+
visit(S->getBody());
2802+
}
2803+
void FindLocalVal::visitRepeatWhileStmt(RepeatWhileStmt *S) {
2804+
visit(S->getBody());
2805+
}
2806+
void FindLocalVal::visitDoStmt(DoStmt *S) {
2807+
visit(S->getBody());
2808+
}
2809+
2810+
void FindLocalVal::visitForEachStmt(ForEachStmt *S) {
2811+
if (!isReferencePointInRange(S->getSourceRange()))
2812+
return;
2813+
visit(S->getBody());
2814+
if (!isReferencePointInRange(S->getSequence()->getSourceRange()))
2815+
checkPattern(S->getPattern(), DeclVisibilityKind::LocalVariable);
2816+
}
2817+
2818+
void FindLocalVal::visitBraceStmt(BraceStmt *S, bool isTopLevelCode) {
2819+
if (isTopLevelCode) {
2820+
if (SM.isBeforeInBuffer(Loc, S->getStartLoc()))
2821+
return;
2822+
} else {
2823+
if (!isReferencePointInRange(S->getSourceRange()))
2824+
return;
2825+
}
2826+
2827+
for (auto elem : S->getElements()) {
2828+
if (auto *S = elem.dyn_cast<Stmt*>())
2829+
visit(S);
2830+
}
2831+
for (auto elem : S->getElements()) {
2832+
if (auto *D = elem.dyn_cast<Decl*>()) {
2833+
if (auto *VD = dyn_cast<ValueDecl>(D))
2834+
checkValueDecl(VD, DeclVisibilityKind::LocalVariable);
2835+
}
2836+
}
2837+
}
2838+
2839+
void FindLocalVal::visitSwitchStmt(SwitchStmt *S) {
2840+
if (!isReferencePointInRange(S->getSourceRange()))
2841+
return;
2842+
for (CaseStmt *C : S->getCases()) {
2843+
visit(C);
2844+
}
2845+
}
2846+
2847+
void FindLocalVal::visitCaseStmt(CaseStmt *S) {
2848+
if (!isReferencePointInRange(S->getSourceRange()))
2849+
return;
2850+
// Pattern names aren't visible in the patterns themselves,
2851+
// just in the body or in where guards.
2852+
bool inPatterns = isReferencePointInRange(S->getLabelItemsRange());
2853+
auto items = S->getCaseLabelItems();
2854+
if (inPatterns) {
2855+
for (const auto &CLI : items) {
2856+
auto guard = CLI.getGuardExpr();
2857+
if (guard && isReferencePointInRange(guard->getSourceRange())) {
2858+
checkPattern(CLI.getPattern(), DeclVisibilityKind::LocalVariable);
2859+
break;
2860+
}
2861+
}
2862+
}
2863+
if (!inPatterns && !items.empty())
2864+
checkPattern(items[0].getPattern(), DeclVisibilityKind::LocalVariable);
2865+
visit(S->getBody());
2866+
}
2867+
2868+
void FindLocalVal::visitDoCatchStmt(DoCatchStmt *S) {
2869+
if (!isReferencePointInRange(S->getSourceRange()))
2870+
return;
2871+
visit(S->getBody());
2872+
visitCatchClauses(S->getCatches());
2873+
}
2874+
void FindLocalVal::visitCatchClauses(ArrayRef<CatchStmt*> clauses) {
2875+
// TODO: some sort of binary search?
2876+
for (auto clause : clauses) {
2877+
visitCatchStmt(clause);
2878+
}
2879+
}
2880+
void FindLocalVal::visitCatchStmt(CatchStmt *S) {
2881+
if (!isReferencePointInRange(S->getSourceRange()))
2882+
return;
2883+
// Names in the pattern aren't visible until after the pattern.
2884+
if (!isReferencePointInRange(S->getErrorPattern()->getSourceRange()))
2885+
checkPattern(S->getErrorPattern(), DeclVisibilityKind::LocalVariable);
2886+
visit(S->getBody());
2887+
}
2888+
2889+
} // end namespace namelookup
2890+
} // end namespace swift

0 commit comments

Comments
 (0)