Skip to content

Commit 4f1e05c

Browse files
committed
[AST] Give appendInterpolation refs a SourceLoc
This change permits UnresolvedDotExpr to have both a name and a base that are implicit, but a valid DotLoc, and to treat that DotLoc as the node’s location. It then changes the generation of string interpolation code so that `$stringInterpolation.appendInterpolation` references have a DotLoc corresponding to the backslash in the string literal. This makes it possible for `ExprContextAnalyzer` in IDE to correctly detect when you are code-completing in a string interpolation and treat it as an `appendInterpolation` call.
1 parent da74978 commit 4f1e05c

File tree

3 files changed

+25
-10
lines changed

3 files changed

+25
-10
lines changed

include/swift/AST/Expr.h

+20-4
Original file line numberDiff line numberDiff line change
@@ -2377,14 +2377,30 @@ class UnresolvedDotExpr : public Expr {
23772377
: FunctionRefKind::Unapplied);
23782378
}
23792379

2380-
SourceLoc getLoc() const { return NameLoc.getBaseNameLoc(); }
2380+
SourceLoc getLoc() const {
2381+
if (NameLoc.isValid())
2382+
return NameLoc.getBaseNameLoc();
2383+
else if (DotLoc.isValid())
2384+
return DotLoc;
2385+
else
2386+
return SubExpr->getEndLoc();
2387+
}
23812388

23822389
SourceLoc getStartLoc() const {
2383-
return (DotLoc.isInvalid() ? NameLoc.getSourceRange().End
2384-
: SubExpr->getStartLoc());
2390+
if (SubExpr->getStartLoc().isValid())
2391+
return SubExpr->getStartLoc();
2392+
else if (DotLoc.isValid())
2393+
return DotLoc;
2394+
else
2395+
return NameLoc.getSourceRange().Start;
23852396
}
23862397
SourceLoc getEndLoc() const {
2387-
return NameLoc.getSourceRange().End;
2398+
if (NameLoc.isValid())
2399+
return NameLoc.getSourceRange().End;
2400+
else if (DotLoc.isValid())
2401+
return DotLoc;
2402+
else
2403+
return SubExpr->getEndLoc();
23882404
}
23892405

23902406
SourceLoc getDotLoc() const { return DotLoc; }

lib/Parse/ParseExpr.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1863,8 +1863,8 @@ parseStringSegments(SmallVectorImpl<Lexer::StringSegment> &Segments,
18631863
SyntaxKind::ExpressionSegment);
18641864

18651865
// Backslash is part of an expression segment.
1866-
Token BackSlash(tok::backslash,
1867-
CharSourceRange(Segment.Loc.getAdvancedLoc(-1), 1).str());
1866+
SourceLoc BackSlashLoc = Segment.Loc.getAdvancedLoc(-1);
1867+
Token BackSlash(tok::backslash, CharSourceRange(BackSlashLoc, 1).str());
18681868
ExprContext.addToken(BackSlash, EmptyTrivia, EmptyTrivia);
18691869
// Create a temporary lexer that lexes from the body of the string.
18701870
LexerState BeginState =
@@ -1889,7 +1889,7 @@ parseStringSegments(SmallVectorImpl<Lexer::StringSegment> &Segments,
18891889
tok::string_interpolation_anchor);
18901890

18911891
auto callee = new (Context) UnresolvedDotExpr(InterpolationVarRef,
1892-
/*dotloc=*/SourceLoc(),
1892+
/*dotloc=*/BackSlashLoc,
18931893
appendInterpolation,
18941894
/*nameloc=*/DeclNameLoc(),
18951895
/*Implicit=*/true);

test/IDE/complete_at_top_level.swift

+2-3
Original file line numberDiff line numberDiff line change
@@ -470,10 +470,9 @@ func resyncParserB14() {}
470470
var stringInterp = "\(#^STRING_INTERP_3^#)"
471471
_ = "" + "\(#^STRING_INTERP_4^#)" + ""
472472
// STRING_INTERP: Begin completions
473-
// FIXME: Why is this TypeRelation[Invalid] in STRING_INTERP_4?
474-
// STRING_INTERP-DAG: Decl[InstanceMethod]/CurrNominal{{(/NotRecommended/TypeRelation\[Invalid\])?}}: ['(']{#(value): _#}[')'][#Void#]; name=value: _
473+
// STRING_INTERP-DAG: Decl[InstanceMethod]/CurrNominal: ['(']{#(value): _#}[')'][#Void#]; name=value: _
475474
// STRING_INTERP-DAG: Decl[Struct]/CurrModule: FooStruct[#FooStruct#];
476-
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule: fooFunc1()[#Void#];
475+
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule/NotRecommended/TypeRelation[Invalid]: fooFunc1()[#Void#];
477476
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule: optStr()[#String?#];
478477
// STRING_INTERP-DAG: Decl[GlobalVar]/Local: fooObject[#FooStruct#];
479478
// STRING_INTERP: End completions

0 commit comments

Comments
 (0)