Skip to content

Commit da74978

Browse files
committed
[Parse] Parse string interpolations as args
Now that we manipulate the argument list to correct strange interpolations in Sema, we can parse interpolations directly as argument lists, simplifying the parser. By itself, this refactoring causes a code completion regression; a subsequent commit will fix that.
1 parent a4e5bce commit da74978

File tree

2 files changed

+21
-38
lines changed

2 files changed

+21
-38
lines changed

lib/Parse/ParseExpr.cpp

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,30 +1888,12 @@ parseStringSegments(SmallVectorImpl<Lexer::StringSegment> &Segments,
18881888
TokReceiver->registerTokenKindChange(Tok.getLoc(),
18891889
tok::string_interpolation_anchor);
18901890

1891-
SourceLoc lParen, rParen;
1892-
SmallVector<Expr *, 4> args;
1893-
SmallVector<Identifier, 4> argLabels;
1894-
SmallVector<SourceLoc, 4> argLabelLocs;
1895-
Expr *trailingClosureNeverPresent;
1896-
ParserStatus S =
1897-
parseExprList(tok::l_paren, tok::r_paren,
1898-
/*isPostfix=*/false, /*isExprBasic=*/true,
1899-
lParen, args, argLabels, argLabelLocs, rParen,
1900-
trailingClosureNeverPresent,
1901-
SyntaxKind::FunctionCallArgumentList);
1902-
assert(!trailingClosureNeverPresent);
1903-
1904-
Status |= S;
1905-
// If there was an error parsing a parameter, add an ErrorExpr to
1906-
// represent it. Prevents spurious errors about a nonexistent
1907-
// appendInterpolation() overload.
1908-
if (S.isError() && args.size() == 0)
1909-
args.push_back(new (Context) ErrorExpr(SourceRange(lParen, rParen)));
1910-
1911-
while (argLabels.size() < args.size())
1912-
argLabels.push_back(Identifier());
1913-
while (argLabelLocs.size() < args.size())
1914-
argLabelLocs.push_back(SourceLoc());
1891+
auto callee = new (Context) UnresolvedDotExpr(InterpolationVarRef,
1892+
/*dotloc=*/SourceLoc(),
1893+
appendInterpolation,
1894+
/*nameloc=*/DeclNameLoc(),
1895+
/*Implicit=*/true);
1896+
auto S = parseExprCallSuffix(makeParserResult(callee), true);
19151897

19161898
// If we stopped parsing the expression before the expression segment is
19171899
// over, eat the remaining tokens into a token list
@@ -1925,20 +1907,14 @@ parseStringSegments(SmallVectorImpl<Lexer::StringSegment> &Segments,
19251907
L->getLocForEndOfToken(SourceMgr, Tok.getLoc()));
19261908
}
19271909

1910+
Expr *call = S.getPtrOrNull();
1911+
if (!call)
1912+
call = new (Context) ErrorExpr(SourceRange(Segment.Loc,
1913+
Segment.getEndLoc()));
1914+
19281915
InterpolationCount += 1;
1929-
1930-
auto AppendInterpolationRef =
1931-
new (Context) UnresolvedDotExpr(InterpolationVarRef,
1932-
/*dotloc=*/SourceLoc(),
1933-
appendInterpolation,
1934-
/*nameloc=*/DeclNameLoc(),
1935-
/*Implicit=*/true);
1936-
auto AppendInterpolationCall =
1937-
CallExpr::create(Context, AppendInterpolationRef,
1938-
lParen, args, argLabels, argLabelLocs, rParen,
1939-
/*trailingClosure=*/nullptr, /*implicit=*/false);
1940-
1941-
Stmts.push_back(AppendInterpolationCall);
1916+
Stmts.push_back(call);
1917+
Status |= S;
19421918

19431919
if (!Tok.is(tok::eof)) {
19441920
diagnose(Tok, diag::string_interpolation_extra);

test/IDE/complete_at_top_level.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ func fooFunc2(_ a: Int, _ b: Double) {}
167167

168168
func erroneous1(_ x: Undeclared) {}
169169

170+
// FIXME: Hides all other string interpolation completion.
171+
//extension DefaultStringInterpolation {
172+
// mutating func appendInterpolation(interpolate: Double) {}
173+
//}
174+
170175
//===--- Test code completions of expressions that can be typechecked.
171176

172177
// Although the parser can recover in most of these test cases, we resync it
@@ -465,8 +470,10 @@ func resyncParserB14() {}
465470
var stringInterp = "\(#^STRING_INTERP_3^#)"
466471
_ = "" + "\(#^STRING_INTERP_4^#)" + ""
467472
// 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: _
468475
// STRING_INTERP-DAG: Decl[Struct]/CurrModule: FooStruct[#FooStruct#];
469-
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule/NotRecommended/TypeRelation[Invalid]: fooFunc1()[#Void#];
476+
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule: fooFunc1()[#Void#];
470477
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule: optStr()[#String?#];
471478
// STRING_INTERP-DAG: Decl[GlobalVar]/Local: fooObject[#FooStruct#];
472479
// STRING_INTERP: End completions

0 commit comments

Comments
 (0)