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