Skip to content

Commit 0712b42

Browse files
authored
Merge pull request #36867 from ahoppen/pr/string-interpolation-in-switch-case
[CodeComplete] Fix issue with completion in string literal as last token in case stmt
2 parents 312ec16 + cfe92f8 commit 0712b42

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

lib/AST/NameLookup.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,7 +2842,19 @@ void FindLocalVal::visitBraceStmt(BraceStmt *S, bool isTopLevelCode) {
28422842
if (SM.isBeforeInBuffer(Loc, S->getStartLoc()))
28432843
return;
28442844
} else {
2845-
if (!isReferencePointInRange(S->getSourceRange()))
2845+
SourceRange CheckRange = S->getSourceRange();
2846+
if (S->isImplicit()) {
2847+
// If the brace statement is implicit, it doesn't have an explicit '}'
2848+
// token. Thus, the last token in the brace stmt could be a string
2849+
// literal token, which can *contain* its interpolation segments.
2850+
// If one of these interpolation segments is the reference point, we'd
2851+
// return false from `isReferencePointInRange` because the string
2852+
// literal token's start location is before the interpolation token.
2853+
// To fix this, adjust the range we are checking to range until the end of
2854+
// the potential string interpolation token.
2855+
CheckRange.End = Lexer::getLocForEndOfToken(SM, CheckRange.End);
2856+
}
2857+
if (!isReferencePointInRange(CheckRange))
28462858
return;
28472859
}
28482860

@@ -2867,7 +2879,16 @@ void FindLocalVal::visitSwitchStmt(SwitchStmt *S) {
28672879
}
28682880

28692881
void FindLocalVal::visitCaseStmt(CaseStmt *S) {
2870-
if (!isReferencePointInRange(S->getSourceRange()))
2882+
// The last token in a case stmt can be a string literal token, which can
2883+
// *contain* its interpolation segments. If one of these interpolation
2884+
// segments is the reference point, we'd return false from
2885+
// `isReferencePointInRange` because the string literal token's start location
2886+
// is before the interpolation token. To fix this, adjust the range we are
2887+
// checking to range until the end of the potential string interpolation
2888+
// token.
2889+
SourceRange CheckRange = {S->getStartLoc(),
2890+
Lexer::getLocForEndOfToken(SM, S->getEndLoc())};
2891+
if (!isReferencePointInRange(CheckRange))
28712892
return;
28722893
// Pattern names aren't visible in the patterns themselves,
28732894
// just in the body or in where guards.

test/IDE/complete_sr14455.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %swift-ide-test -code-completion -source-filename %s -code-completion-token=COMPLETE | %FileCheck %s
2+
3+
public enum Endpoint {
4+
  case movieDetail
5+
6+
7+
  func path() -> String {
8+
    switch self {
9+
    case .movieDetail:
10+
      let myInt: Int = 2
11+
      return "\(#^COMPLETE^#)"
12+
    }
13+
  }
14+
}
15+
// CHECK: Begin completions
16+
// CHECK: Decl[LocalVar]/Local/TypeRelation[Convertible]: myInt[#Int#];
17+
// CHECK: End completions

0 commit comments

Comments
 (0)