[Refactoring] Fix local rename missing occurrences in string interpolations

NameMatcher checked if a StringLiteralExpr was a string segment in an
interpolated string by checking if the parent expression was an
InterpolatedStringLiteralExpr. That's only true pre-type-checking, and unlike
global rename, local rename  uses the type-checked AST.
This commit is contained in:
Nathan Hawes
2017-11-17 20:16:59 -08:00
parent fcc27f04ee
commit c4e87f0861
8 changed files with 27 additions and 27 deletions

View File

@@ -564,35 +564,21 @@ void NameMatcher::skipLocsBefore(SourceLoc Start) {
} }
bool NameMatcher::shouldSkip(Expr *E) { bool NameMatcher::shouldSkip(Expr *E) {
if (!isa<StringLiteralExpr>(E) || !Parent.getAsExpr() || if (isa<StringLiteralExpr>(E) && Parent.getAsExpr()) {
!isa<InterpolatedStringLiteralExpr>(Parent.getAsExpr())) // Attempting to get the CharSourceRange from the SourceRange of a
return shouldSkip(E->getSourceRange()); // StringLiteralExpr that is a segment of an interpolated string gives
// incorrect ranges. Use the CharSourceRange of the corresponding token
// instead.
// The lexer treats interpolated strings as a single token when computing the auto ExprStart = E->getStartLoc();
// CharSourceRange, so when we try to get the CharSourceRange of its first auto RemaingTokens = TokensToCheck.drop_while([&](const Token &tok) -> bool {
// child StringLiteralExpr (at the same SourceLoc) it goes beyond any return getSourceMgr().isBeforeInBuffer(tok.getRange().getStart(), ExprStart);
// interpolated values. Use the StartLoc of the next sibling to bound it. });
StringLiteralExpr *SL = cast<StringLiteralExpr>(E); if (!RemaingTokens.empty() && RemaingTokens.front().getLoc() == ExprStart)
InterpolatedStringLiteralExpr *ISL = return shouldSkip(RemaingTokens.front().getRange());
cast<InterpolatedStringLiteralExpr>(Parent.getAsExpr());
SourceLoc Start = SL->getStartLoc();
ArrayRef<Expr*> Segments = ISL->getSegments();
Segments = Segments.drop_until([&](Expr *Item){ return Item == SL; })
.drop_front();
CharSourceRange Range;
if (Segments.empty()) {
Range = Lexer::getCharSourceRangeFromSourceRange(getSourceMgr(),
SourceRange(Start));
} else {
SourceLoc NextSiblingLoc = Segments.front()->getStartLoc();
unsigned Length = getSourceMgr().getByteDistance(Start, NextSiblingLoc);
Range = CharSourceRange(Start, Length);
} }
return shouldSkip(E->getSourceRange());
return shouldSkip(Range);
} }
bool NameMatcher::shouldSkip(SourceRange Range) { bool NameMatcher::shouldSkip(SourceRange Range) {

View File

@@ -25,3 +25,5 @@ source.edit.kind.active:
26:28-26:29 source.refactoring.range.kind.call-argument-colon arg-index=0 26:28-26:29 source.refactoring.range.kind.call-argument-colon arg-index=0
source.edit.kind.string: source.edit.kind.string:
26:33-26:36 source.refactoring.range.kind.basename 26:33-26:36 source.refactoring.range.kind.basename
source.edit.kind.string:
26:43-26:46 source.refactoring.range.kind.basename

View File

@@ -4,3 +4,5 @@ source.edit.kind.active:
3:3-3:5 source.refactoring.range.kind.basename 3:3-3:5 source.refactoring.range.kind.basename
source.edit.kind.active: source.edit.kind.active:
3:8-3:10 source.refactoring.range.kind.basename 3:8-3:10 source.refactoring.range.kind.basename
source.edit.kind.active:
4:17-4:19 source.refactoring.range.kind.basename

View File

@@ -1,6 +1,7 @@
func foo() { func foo() {
var aa = 3 var aa = 3
aa = aa + 1 aa = aa + 1
_ = "before \(aa) after"
return 1 return 1
} }

View File

@@ -4,3 +4,5 @@ source.edit.kind.active:
3:3-3:5 "new_name" 3:3-3:5 "new_name"
source.edit.kind.active: source.edit.kind.active:
3:8-3:10 "new_name" 3:8-3:10 "new_name"
source.edit.kind.active:
4:17-4:19 "new_name"

View File

@@ -23,7 +23,7 @@ let s = "a foo is here"
#selector(AStruct.foo(a:)) #selector(AStruct.foo(a:))
#selector(AStruct.foo()) #selector(AStruct.foo())
#selector(AStruct.foo) #selector(AStruct.foo)
let y = "before foo \(foo(a:1)) foo after" let y = "before foo \(foo(a:1)) foo after foo"
func bar(a/* a comment */: Int, b c: Int, _: Int, _ d: Int) {} func bar(a/* a comment */: Int, b c: Int, _: Int, _ d: Int) {}
bar(a: 1, b: 2, 3, 4) bar(a: 1, b: 2, 3, 4)

View File

@@ -54,6 +54,11 @@
"key.line": 26, "key.line": 26,
"key.column": 33, "key.column": 33,
"key.nametype": source.syntacticrename.unknown "key.nametype": source.syntacticrename.unknown
},
{
"key.line": 26,
"key.column": 43,
"key.nametype": source.syntacticrename.unknown
} }
] ]
} }

View File

@@ -22,3 +22,5 @@ source.edit.kind.active:
26:27-26:28 "first" 26:27-26:28 "first"
source.edit.kind.string: source.edit.kind.string:
26:33-26:36 "bar" 26:33-26:36 "bar"
source.edit.kind.string:
26:43-26:46 "bar"