Skip to content

Commit dc3f110

Browse files
committed
[SyntaxParse] Modify parseTypeCollection()
Now we always construct Array/DictionaryTypeSyntax even if ']' is missing.
1 parent 0b61cc6 commit dc3f110

File tree

3 files changed

+46
-37
lines changed

3 files changed

+46
-37
lines changed

lib/Parse/ASTGen.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -616,25 +616,37 @@ TypeRepr *ASTGen::generate(const DictionaryTypeSyntax &Type,
616616
const SourceLoc Loc) {
617617
TypeRepr *ValueType = generate(Type.getValueType(), Loc);
618618
TypeRepr *KeyType = generate(Type.getKeyType(), Loc);
619-
auto LBraceLoc = advanceLocBegin(Loc, Type.getLeftSquareBracket());
619+
if (!ValueType || !KeyType)
620+
return nullptr;
620621
auto ColonLoc = advanceLocBegin(Loc, Type.getColon());
621-
auto RBraceLoc = advanceLocBegin(Loc, Type.getRightSquareBracket());
622-
SourceRange Range{LBraceLoc, RBraceLoc};
622+
623+
SourceLoc LBracketLoc, RBracketLoc;
624+
if (Type.getLeftSquareBracket().isPresent())
625+
LBracketLoc = advanceLocBegin(Loc, Type.getLeftSquareBracket());
626+
else
627+
LBracketLoc = advanceLocBegin(Loc, *Type.getFirstToken());
628+
if (Type.getRightSquareBracket().isPresent())
629+
RBracketLoc = advanceLocBegin(Loc, Type.getRightSquareBracket());
630+
else
631+
RBracketLoc = advanceLocBegin(Loc, *Type.getLastToken());
632+
SourceRange Range{LBracketLoc, RBracketLoc};
623633
return new (Context) DictionaryTypeRepr(KeyType, ValueType, ColonLoc, Range);
624634
}
625635

626636
TypeRepr *ASTGen::generate(const ArrayTypeSyntax &Type, SourceLoc Loc) {
627637
TypeRepr *ElementType = generate(Type.getElementType(), Loc);
628-
SourceLoc LBraceLoc, RBraceLoc;
638+
if (!ElementType)
639+
return nullptr;
640+
SourceLoc LBracketLoc, RBracketLoc;
629641
if (Type.getLeftSquareBracket().isPresent())
630-
LBraceLoc = advanceLocBegin(Loc, Type.getLeftSquareBracket());
642+
LBracketLoc = advanceLocBegin(Loc, Type.getLeftSquareBracket());
631643
else
632-
LBraceLoc = advanceLocBegin(Loc, Type.getElementType());
633-
if (Type.getLeftSquareBracket().isPresent())
634-
RBraceLoc = advanceLocBegin(Loc, Type.getRightSquareBracket());
644+
LBracketLoc = advanceLocBegin(Loc, *Type.getFirstToken());
645+
if (Type.getRightSquareBracket().isPresent())
646+
RBracketLoc = advanceLocBegin(Loc, Type.getRightSquareBracket());
635647
else
636-
RBraceLoc = advanceLocBegin(Loc, *Type.getLastToken());
637-
return new (Context) ArrayTypeRepr(ElementType, {LBraceLoc, RBraceLoc});
648+
RBracketLoc = advanceLocBegin(Loc, *Type.getLastToken());
649+
return new (Context) ArrayTypeRepr(ElementType, {LBracketLoc, RBracketLoc});
638650
}
639651

640652
TypeRepr *ASTGen::generate(const MetatypeTypeSyntax &Type,

lib/Parse/ParseType.cpp

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,51 +1276,48 @@ ParsedSyntaxResult<ParsedTypeSyntax> Parser::parseTypeCollection() {
12761276
auto ElementTypeResult = parseTypeSyntax(diag::expected_element_type);
12771277
Status |= ElementTypeResult.getStatus();
12781278
auto ElementType = ElementTypeResult.getOrNull();
1279+
if (!ElementType)
1280+
ElementType = ParsedSyntaxRecorder::makeUnknownType({}, *SyntaxContext);
12791281

12801282
Optional<ParsedTokenSyntax> Colon;
12811283
Optional<ParsedTypeSyntax> ValueType;
12821284

12831285
if (Tok.is(tok::colon)) {
12841286
Colon = consumeTokenSyntax(tok::colon);
1285-
auto ValueTypeResult = parseTypeSyntax(diag::expected_dictionary_value_type);
1287+
auto ValueTypeResult =
1288+
parseTypeSyntax(diag::expected_dictionary_value_type);
12861289
ValueType = ValueTypeResult.getOrNull();
1290+
if (!ValueType)
1291+
ValueType = ParsedSyntaxRecorder::makeUnknownType({}, *SyntaxContext);
12871292
Status |= ValueTypeResult.getStatus();
12881293
}
12891294

12901295
auto Diag = Colon ? diag::expected_rbracket_dictionary_type
12911296
: diag::expected_rbracket_array_type;
12921297

12931298
SourceLoc RSquareLoc;
1294-
auto RSquare = parseMatchingTokenSyntax(tok::r_square, RSquareLoc, Diag,
1295-
LSquareLoc);
1299+
auto RSquare =
1300+
parseMatchingTokenSyntax(tok::r_square, RSquareLoc, Diag, LSquareLoc);
12961301
if (!RSquare)
12971302
Status.setIsParseError();
12981303

1299-
if (!Status.isSuccess()) {
1300-
SmallVector<ParsedSyntax, 0> Pieces;
1301-
Pieces.push_back(std::move(LSquare));
1302-
if (ElementType)
1303-
Pieces.push_back(std::move(*ElementType));
1304-
if (Colon)
1305-
Pieces.push_back(std::move(*Colon));
1306-
if (ValueType)
1307-
Pieces.push_back(std::move(*ValueType));
1304+
if (Colon) {
1305+
ParsedDictionaryTypeSyntaxBuilder builder(*SyntaxContext);
1306+
builder.useLeftSquareBracket(std::move(LSquare));
1307+
builder.useKeyType(std::move(*ElementType));
1308+
builder.useColon(std::move(*Colon));
1309+
builder.useValueType(std::move(*ValueType));
13081310
if (RSquare)
1309-
Pieces.push_back(std::move(*RSquare));
1310-
1311-
ParsedTypeSyntax ty =
1312-
ParsedSyntaxRecorder::makeUnknownType(Pieces, *SyntaxContext);
1313-
return makeParsedResult(std::move(ty), Status);
1311+
builder.useRightSquareBracket(std::move(*RSquare));
1312+
return makeParsedResult(builder.build(), Status);
1313+
} else {
1314+
ParsedArrayTypeSyntaxBuilder builder(*SyntaxContext);
1315+
builder.useLeftSquareBracket(std::move(LSquare));
1316+
builder.useElementType(std::move(*ElementType));
1317+
if (RSquare)
1318+
builder.useRightSquareBracket(std::move(*RSquare));
1319+
return makeParsedResult(builder.build(), Status);
13141320
}
1315-
1316-
if (Colon)
1317-
return makeParsedResult(ParsedSyntaxRecorder::makeDictionaryType(
1318-
std::move(LSquare), std::move(*ElementType), std::move(*Colon),
1319-
std::move(*ValueType), std::move(*RSquare), *SyntaxContext));
1320-
1321-
return makeParsedResult(ParsedSyntaxRecorder::makeArrayType(
1322-
std::move(LSquare), std::move(*ElementType), std::move(*RSquare),
1323-
*SyntaxContext));
13241321
}
13251322

13261323
ParsedSyntaxResult<ParsedTypeSyntax>

test/Syntax/Outputs/round_trip_invalid.swift.withkinds

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// RUN: %swift-syntax-test -deserialize-raw-tree -input-source-filename %t.dump -output-filename %t
1010
// RUN: diff -u %s %t
1111

12-
let <PatternBinding><IdentifierPattern>strings</IdentifierPattern><TypeAnnotation>: [<ArrayType><SimpleTypeIdentifier>Strin</SimpleTypeIdentifier></ArrayType></TypeAnnotation></PatternBinding></VariableDecl><IdentifierExpr>[g</IdentifierExpr>]?<FunctionDecl>
12+
let <PatternBinding><IdentifierPattern>strings</IdentifierPattern><TypeAnnotation>: <ArrayType>[<ArrayType><SimpleTypeIdentifier>Strin</SimpleTypeIdentifier></ArrayType></ArrayType></TypeAnnotation></PatternBinding></VariableDecl><IdentifierExpr>[g</IdentifierExpr>]?<FunctionDecl>
1313

1414
// Function body without closing brace token.
1515
func foo<FunctionSignature><ParameterClause>() </ParameterClause></FunctionSignature><CodeBlock>{<VariableDecl>

0 commit comments

Comments
 (0)