Skip to content

Commit dfe962f

Browse files
authored
Merge pull request #27508 from rintaro/syntaxparse-expridentifier
[SyntaxParse] Parse IdentifierExpr syntax
2 parents 04ce7bf + 597538c commit dfe962f

File tree

7 files changed

+386
-201
lines changed

7 files changed

+386
-201
lines changed

include/swift/Parse/ASTGen.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ class ASTGen {
7979
//===--------------------------------------------------------------------===//
8080
// Expressions.
8181

82+
Expr *generate(const syntax::ExprSyntax &Expr, const SourceLoc Loc);
83+
Expr *generate(const syntax::IdentifierExprSyntax &Expr, const SourceLoc Loc);
84+
Expr *generate(const syntax::EditorPlaceholderExprSyntax &Expr,
85+
const SourceLoc Loc);
86+
Expr *generate(const syntax::SpecializeExprSyntax &Expr, const SourceLoc Loc);
8287
Expr *generate(const syntax::IntegerLiteralExprSyntax &Expr,
8388
const SourceLoc Loc);
8489
Expr *generate(const syntax::FloatLiteralExprSyntax &Expr,
@@ -96,7 +101,13 @@ class ASTGen {
96101
const SourceLoc Loc);
97102
Expr *generate(const syntax::UnknownExprSyntax &Expr, const SourceLoc Loc);
98103

104+
std::pair<DeclName, DeclNameLoc> generateUnqualifiedDeclName(
105+
const syntax::TokenSyntax &idTok,
106+
const Optional<syntax::DeclNameArgumentsSyntax> &args,
107+
const SourceLoc Loc);
108+
99109
private:
110+
100111
Expr *generateMagicIdentifierLiteralExpression(
101112
const syntax::TokenSyntax &PoundToken, const SourceLoc Loc);
102113

@@ -168,10 +179,9 @@ class ASTGen {
168179
//===--------------------------------------------------------------------===//
169180
// Generics.
170181

171-
TypeRepr *generate(const syntax::GenericArgumentSyntax &Arg,
172-
const SourceLoc Loc);
173-
llvm::SmallVector<TypeRepr *, 4>
174-
generate(const syntax::GenericArgumentListSyntax &Args, const SourceLoc Loc);
182+
void generate(const syntax::GenericArgumentClauseSyntax &Arg,
183+
const SourceLoc Loc, SourceLoc &lAngleLoc, SourceLoc &rAngleLoc,
184+
SmallVectorImpl<TypeRepr *> &args);
175185

176186
GenericParamList *
177187
generate(const syntax::GenericParameterClauseListSyntax &clause,

include/swift/Parse/Parser.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,8 @@ class Parser {
14801480
/// _)
14811481
/// \param loc The location of the label (empty if it doesn't exist)
14821482
void parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc);
1483+
bool parseOptionalArgumentLabelSyntax(Optional<ParsedTokenSyntax> &name,
1484+
Optional<ParsedTokenSyntax> &colon);
14831485

14841486
/// Parse an unqualified-decl-name.
14851487
///
@@ -1498,10 +1500,20 @@ class Parser {
14981500
bool allowOperators=false,
14991501
bool allowZeroArgCompoundNames=false,
15001502
bool allowDeinitAndSubscript=false);
1503+
ParserStatus
1504+
parseUnqualifiedDeclNameSyntax(Optional<ParsedTokenSyntax> &identTok,
1505+
Optional<ParsedDeclNameArgumentsSyntax> &declNameArg,
1506+
bool afterDot, const Diagnostic &diag,
1507+
bool allowOperators=false,
1508+
bool allowZeroArgCompoundNames=false,
1509+
bool allowDeinitAndSubscript=false);
1510+
1511+
ParsedSyntaxResult<ParsedExprSyntax> parseExprIdentifierSyntax();
1512+
ParsedSyntaxResult<ParsedExprSyntax>
1513+
parseExprSpecializeSyntax(ParsedExprSyntax &&);
15011514

15021515
Expr *parseExprIdentifier();
1503-
Expr *parseExprEditorPlaceholder(Token PlaceholderTok,
1504-
Identifier PlaceholderId);
1516+
Expr *parseExprEditorPlaceholder(SourceLoc loc, StringRef text);
15051517

15061518
/// Parse a closure expression after the opening brace.
15071519
///

lib/Parse/ASTGen.cpp

Lines changed: 178 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,166 @@ TrailingWhereClause *ASTGen::generate(const GenericWhereClauseSyntax &syntax,
229229
return TrailingWhereClause::create(Context, whereLoc, requirements);
230230
}
231231

232+
Expr *ASTGen::generate(const ExprSyntax &E, const SourceLoc Loc) {
233+
Expr *result = nullptr;
234+
235+
if (auto identifierExpr = E.getAs<IdentifierExprSyntax>())
236+
result = generate(*identifierExpr, Loc);
237+
else if (auto specializeExpr = E.getAs<SpecializeExprSyntax>())
238+
result = generate(*specializeExpr, Loc);
239+
else if (auto editorPlaceHolderExpr = E.getAs<EditorPlaceholderExprSyntax>())
240+
result = generate(*editorPlaceHolderExpr, Loc);
241+
else if (auto integerLiteralExpr = E.getAs<IntegerLiteralExprSyntax>())
242+
result = generate(*integerLiteralExpr, Loc);
243+
else if (auto floatLiteralExpr = E.getAs<FloatLiteralExprSyntax>())
244+
result = generate(*floatLiteralExpr, Loc);
245+
else if (auto nilLiteral = E.getAs<NilLiteralExprSyntax>())
246+
result = generate(*nilLiteral, Loc);
247+
else if (auto boolLiteral = E.getAs<BooleanLiteralExprSyntax>())
248+
result = generate(*boolLiteral, Loc);
249+
else if (auto poundFileExpr = E.getAs<PoundFileExprSyntax>())
250+
result = generate(*poundFileExpr, Loc);
251+
else if (auto poundLineExpr = E.getAs<PoundLineExprSyntax>())
252+
result = generate(*poundLineExpr, Loc);
253+
else if (auto poundColumnExpr = E.getAs<PoundColumnExprSyntax>())
254+
result = generate(*poundColumnExpr, Loc);
255+
else if (auto poundFunctionExpr = E.getAs<PoundFunctionExprSyntax>())
256+
result = generate(*poundFunctionExpr, Loc);
257+
else if (auto poundDsohandleExpr = E.getAs<PoundDsohandleExprSyntax>())
258+
result = generate(*poundDsohandleExpr, Loc);
259+
else
260+
llvm_unreachable("unsupported expression");
261+
262+
return result;
263+
}
264+
265+
std::pair<DeclName, DeclNameLoc> ASTGen::generateUnqualifiedDeclName(
266+
const TokenSyntax &idTok, const Optional<DeclNameArgumentsSyntax> &args,
267+
const SourceLoc Loc) {
268+
SourceLoc baseNameLoc = advanceLocBegin(Loc, idTok);
269+
270+
DeclBaseName baseName;
271+
if (idTok.getTokenKind() == tok::kw_init)
272+
baseName = DeclBaseName::createConstructor();
273+
else if (idTok.getTokenKind() == tok::kw_deinit)
274+
baseName = DeclBaseName::createDestructor();
275+
else if (idTok.getTokenKind() == tok::kw_subscript)
276+
baseName = DeclBaseName::createSubscript();
277+
else
278+
baseName = Context.getIdentifier(idTok.getIdentifierText());
279+
280+
if (!args)
281+
return {DeclName(baseName), DeclNameLoc(baseNameLoc)};
282+
283+
// FIXME: Remove this block and use 'Loc'.
284+
// This is needed for the case 'idTok' and 'args' are not in the same tree.
285+
// i.e. Call from parseUnqualifiedDeclName().
286+
SourceLoc argsLeadingLoc = Loc;
287+
if (!args->getParent()) {
288+
argsLeadingLoc = Loc.getAdvancedLoc(idTok.getTextLength());
289+
} else {
290+
assert(idTok.getData().getParent() == args->getData().getParent() &&
291+
idTok.getIndexInParent() + 1 == args->getIndexInParent() &&
292+
"'idTok' must be immediately followed by 'args'");
293+
}
294+
295+
SmallVector<Identifier, 2> argumentLabels;
296+
SmallVector<SourceLoc, 2> argumentLabelLocs;
297+
for (auto arg : args->getArguments()) {
298+
Identifier label;
299+
if (!arg.getName().isMissing() &&
300+
arg.getName().getTokenKind() != tok::kw__) {
301+
label = Context.getIdentifier(arg.getName().getIdentifierText());
302+
}
303+
argumentLabels.push_back(label);
304+
argumentLabelLocs.push_back(advanceLocBegin(argsLeadingLoc,
305+
*arg.getFirstToken()));
306+
}
307+
SourceLoc lParenLoc = advanceLocBegin(argsLeadingLoc, args->getLeftParen());
308+
SourceLoc rParenLoc = advanceLocBegin(argsLeadingLoc, args->getRightParen());
309+
310+
DeclName name(Context, baseName, argumentLabels);
311+
DeclNameLoc nameLoc;
312+
if (argumentLabelLocs.empty())
313+
nameLoc = DeclNameLoc(baseNameLoc);
314+
else
315+
nameLoc = DeclNameLoc(Context, baseNameLoc, lParenLoc, argumentLabelLocs,
316+
rParenLoc);
317+
return {name, nameLoc};
318+
}
319+
320+
Expr *ASTGen::generate(const IdentifierExprSyntax &E, const SourceLoc Loc) {
321+
auto idTok = E.getIdentifier();
322+
DeclName name;
323+
DeclNameLoc nameLoc;
324+
std::tie(name, nameLoc) = generateUnqualifiedDeclName(
325+
E.getIdentifier(), E.getDeclNameArguments(), Loc);
326+
327+
ValueDecl *D = nullptr;
328+
if (!P.InPoundIfEnvironment) {
329+
D = lookupInScope(name);
330+
// FIXME: We want this to work: "var x = { x() }", but for now it's better
331+
// to disallow it than to crash.
332+
if (D) {
333+
for (auto activeVar : P.DisabledVars) {
334+
if (activeVar != D)
335+
continue;
336+
P.diagnose(nameLoc.getBaseNameLoc(), P.DisabledVarReason);
337+
return new (Context) ErrorExpr(nameLoc.getSourceRange());
338+
}
339+
} else {
340+
for (auto activeVar : P.DisabledVars) {
341+
if (activeVar->getFullName() != name)
342+
continue;
343+
P.diagnose(nameLoc.getBaseNameLoc(), P.DisabledVarReason);
344+
return new (Context) ErrorExpr(nameLoc.getSourceRange());
345+
}
346+
}
347+
}
348+
349+
if (!D) {
350+
return new (Context)
351+
UnresolvedDeclRefExpr(name, DeclRefKind::Ordinary, nameLoc);
352+
}
353+
354+
if (auto TD = dyn_cast<TypeDecl>(D)) {
355+
// When parsing default argument expressions for generic functions,
356+
// we haven't built a FuncDecl or re-parented the GenericTypeParamDecls
357+
// to the FuncDecl yet. Other than that, we should only ever find
358+
// global or local declarations here.
359+
assert(!TD->getDeclContext()->isTypeContext() ||
360+
isa<GenericTypeParamDecl>(TD));
361+
return TypeExpr::createForDecl(nameLoc.getBaseNameLoc(), TD,
362+
/*DeclContext=*/nullptr,
363+
/*inplicit=*/false);
364+
}
365+
366+
return new (Context) DeclRefExpr(D, nameLoc, /*implicit=*/false);
367+
}
368+
369+
Expr *ASTGen::generate(const EditorPlaceholderExprSyntax &E, const SourceLoc Loc) {
370+
assert(!E.getIdentifier().isMissing());
371+
372+
auto text = E.getIdentifier().getText();
373+
auto tokLoc = advanceLocBegin(Loc, E.getIdentifier());
374+
return P.parseExprEditorPlaceholder(tokLoc, text);
375+
}
376+
377+
Expr *ASTGen::generate(const SpecializeExprSyntax &E, const SourceLoc Loc) {
378+
auto base = generate(E.getExpression(), Loc);
379+
380+
SourceLoc lAngleLoc, rAngleLoc;
381+
SmallVector<TypeRepr *, 4> argTyRs;
382+
generate(E.getGenericArgumentClause(), Loc, lAngleLoc, rAngleLoc, argTyRs);
383+
if (argTyRs.empty())
384+
return base;
385+
386+
SmallVector<TypeLoc, 4> args;
387+
args.assign(argTyRs.begin(), argTyRs.end());
388+
return UnresolvedSpecializeExpr::create(Context, base, lAngleLoc, args,
389+
rAngleLoc);
390+
}
391+
232392
Expr *ASTGen::generate(const IntegerLiteralExprSyntax &Expr,
233393
const SourceLoc Loc) {
234394
auto Digits = Expr.getDigits();
@@ -661,15 +821,12 @@ ComponentIdentTypeRepr *ASTGen::generateIdentifier(const T &Type,
661821
auto IdentifierLoc = advanceLocBegin(Loc, Type.getName());
662822
auto Identifier = Context.getIdentifier(Type.getName().getIdentifierText());
663823
if (auto Clause = Type.getGenericArgumentClause()) {
664-
auto Args = Clause->getArguments();
665-
if (!Args.empty()) {
666-
auto LAngleLoc = advanceLocBegin(Loc, Clause->getLeftAngleBracket());
667-
auto RAngleLoc = advanceLocBegin(Loc, Clause->getRightAngleBracket());
668-
SourceRange Range{LAngleLoc, RAngleLoc};
669-
auto ArgsAST = generate(Args, Loc);
824+
SourceLoc lAngleLoc, rAngleLoc;
825+
SmallVector<TypeRepr *, 4> args;
826+
generate(*Clause, Loc, lAngleLoc, rAngleLoc, args);
827+
if (!args.empty())
670828
return GenericIdentTypeRepr::create(Context, IdentifierLoc, Identifier,
671-
ArgsAST, Range);
672-
}
829+
args, {lAngleLoc, rAngleLoc});
673830
}
674831
return new (Context) SimpleIdentTypeRepr(IdentifierLoc, Identifier);
675832
}
@@ -798,13 +955,11 @@ TypeRepr *ASTGen::generate(const SILBoxTypeSyntax &Type, const SourceLoc Loc,
798955
auto RBraceLoc = advanceLocBegin(Loc, Type.getRightBrace());
799956

800957
SourceLoc LAngleLoc, RAngleLoc;
801-
SmallVector<TypeRepr*, 4> Args;
958+
SmallVector<TypeRepr *, 4> Args;
802959
if (auto genericArgs = Type.getGenericArgumentClause()) {
803960
if (genericArgs->getRightAngleBracket().isMissing())
804961
return nullptr;
805-
LAngleLoc = advanceLocBegin(Loc, genericArgs->getLeftAngleBracket());
806-
RAngleLoc = advanceLocBegin(Loc, genericArgs->getRightAngleBracket());
807-
Args = generate(genericArgs->getArguments(), Loc);
962+
generate(*genericArgs, Loc, LAngleLoc, RAngleLoc, Args);
808963
}
809964

810965
auto SILType = SILBoxTypeRepr::create(Context, generics, LBraceLoc, Fields,
@@ -920,22 +1075,20 @@ TypeRepr *ASTGen::generate(const UnknownTypeSyntax &Type, const SourceLoc Loc) {
9201075
return nullptr;
9211076
}
9221077

923-
SmallVector<TypeRepr *, 4>
924-
ASTGen::generate(const GenericArgumentListSyntax &Args, const SourceLoc Loc) {
925-
SmallVector<TypeRepr *, 4> Types;
926-
for (auto Arg : Args) {
927-
auto tyR = generate(Arg, Loc);
1078+
void
1079+
ASTGen::generate(const GenericArgumentClauseSyntax &clause, const SourceLoc Loc,
1080+
SourceLoc &lAngleLoc, SourceLoc &rAngleLoc,
1081+
SmallVectorImpl<TypeRepr *> &args) {
1082+
lAngleLoc = advanceLocBegin(Loc, clause.getLeftAngleBracket());
1083+
rAngleLoc = advanceLocBegin(Loc, clause.getRightAngleBracket());
1084+
1085+
assert(args.empty());
1086+
for (auto Arg : clause.getArguments()) {
1087+
auto tyR = generate(Arg.getArgumentType(), Loc);
9281088
if (!tyR)
9291089
tyR = new (Context) ErrorTypeRepr(advanceLocBegin(Loc, Arg));
930-
Types.push_back(tyR);
1090+
args.push_back(tyR);
9311091
}
932-
933-
return Types;
934-
}
935-
936-
TypeRepr *ASTGen::generate(const GenericArgumentSyntax &Arg,
937-
const SourceLoc Loc) {
938-
return generate(Arg.getArgumentType(), Loc);
9391092
}
9401093

9411094
StringRef ASTGen::copyAndStripUnderscores(StringRef Orig, ASTContext &Context) {

0 commit comments

Comments
 (0)