Skip to content

Commit 6048d81

Browse files
committed
[CodeCompletion] Keep completion status when parsing postfix types
e.g. optional type. rdar://78779049
1 parent 3b6d605 commit 6048d81

File tree

3 files changed

+46
-21
lines changed

3 files changed

+46
-21
lines changed

include/swift/Parse/Parser.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,17 +1253,18 @@ class Parser {
12531253
const TypeAttributes &attrs);
12541254

12551255
ParserResult<TypeRepr> parseTypeTupleBody();
1256-
ParserResult<TypeRepr> parseTypeArray(TypeRepr *Base);
1256+
ParserResult<TypeRepr> parseTypeArray(ParserResult<TypeRepr> Base);
12571257

12581258
/// Parse a collection type.
12591259
/// type-simple:
12601260
/// '[' type ']'
12611261
/// '[' type ':' type ']'
12621262
ParserResult<TypeRepr> parseTypeCollection();
12631263

1264-
ParserResult<TypeRepr> parseTypeOptional(TypeRepr *Base);
1264+
ParserResult<TypeRepr> parseTypeOptional(ParserResult<TypeRepr> Base);
12651265

1266-
ParserResult<TypeRepr> parseTypeImplicitlyUnwrappedOptional(TypeRepr *Base);
1266+
ParserResult<TypeRepr>
1267+
parseTypeImplicitlyUnwrappedOptional(ParserResult<TypeRepr> Base);
12671268

12681269
bool isOptionalToken(const Token &T) const;
12691270
SourceLoc consumeOptionalToken();

lib/Parse/ParseType.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -234,16 +234,16 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(Diag<> MessageID) {
234234

235235
if (!Tok.isAtStartOfLine()) {
236236
if (isOptionalToken(Tok)) {
237-
ty = parseTypeOptional(ty.get());
237+
ty = parseTypeOptional(ty);
238238
continue;
239239
}
240240
if (isImplicitlyUnwrappedOptionalToken(Tok)) {
241-
ty = parseTypeImplicitlyUnwrappedOptional(ty.get());
241+
ty = parseTypeImplicitlyUnwrappedOptional(ty);
242242
continue;
243243
}
244244
// Parse legacy array types for migration.
245245
if (Tok.is(tok::l_square)) {
246-
ty = parseTypeArray(ty.get());
246+
ty = parseTypeArray(ty);
247247
continue;
248248
}
249249
}
@@ -1183,12 +1183,11 @@ ParserResult<TypeRepr> Parser::parseTypeTupleBody() {
11831183
/// type-array '[' ']'
11841184
/// type-array '[' expr ']'
11851185
///
1186-
ParserResult<TypeRepr> Parser::parseTypeArray(TypeRepr *Base) {
1186+
ParserResult<TypeRepr> Parser::parseTypeArray(ParserResult<TypeRepr> Base) {
11871187
assert(Tok.isFollowingLSquare());
11881188
Parser::StructureMarkerRAII ParsingArrayBound(*this, Tok);
11891189
SourceLoc lsquareLoc = consumeToken();
1190-
ArrayTypeRepr *ATR = nullptr;
1191-
1190+
11921191
// Handle a postfix [] production, a common typo for a C-like array.
11931192

11941193
// If we have something that might be an array size expression, parse it as
@@ -1201,19 +1200,23 @@ ParserResult<TypeRepr> Parser::parseTypeArray(TypeRepr *Base) {
12011200

12021201
SourceLoc rsquareLoc;
12031202
if (parseMatchingToken(tok::r_square, rsquareLoc,
1204-
diag::expected_rbracket_array_type, lsquareLoc))
1205-
return makeParserErrorResult(Base);
1203+
diag::expected_rbracket_array_type, lsquareLoc)) {
1204+
Base.setIsParseError();
1205+
return Base;
1206+
}
1207+
1208+
auto baseTyR = Base.get();
12061209

12071210
// If we parsed something valid, diagnose it with a fixit to rewrite it to
12081211
// Swift syntax.
12091212
diagnose(lsquareLoc, diag::new_array_syntax)
1210-
.fixItInsert(Base->getStartLoc(), "[")
1213+
.fixItInsert(baseTyR->getStartLoc(), "[")
12111214
.fixItRemove(lsquareLoc);
12121215

12131216
// Build a normal array slice type for recovery.
1214-
ATR = new (Context) ArrayTypeRepr(Base,
1215-
SourceRange(Base->getStartLoc(), rsquareLoc));
1216-
return makeParserResult(ATR);
1217+
ArrayTypeRepr *ATR = new (Context) ArrayTypeRepr(
1218+
baseTyR, SourceRange(baseTyR->getStartLoc(), rsquareLoc));
1219+
return makeParserResult(ParserStatus(Base), ATR);
12171220
}
12181221

12191222
ParserResult<TypeRepr> Parser::parseTypeCollection() {
@@ -1318,22 +1321,22 @@ SourceLoc Parser::consumeImplicitlyUnwrappedOptionalToken() {
13181321
/// Parse a single optional suffix, given that we are looking at the
13191322
/// question mark.
13201323
ParserResult<TypeRepr>
1321-
Parser::parseTypeOptional(TypeRepr *base) {
1324+
Parser::parseTypeOptional(ParserResult<TypeRepr> base) {
13221325
SourceLoc questionLoc = consumeOptionalToken();
1323-
auto TyR = new (Context) OptionalTypeRepr(base, questionLoc);
1326+
auto TyR = new (Context) OptionalTypeRepr(base.get(), questionLoc);
13241327
SyntaxContext->createNodeInPlace(SyntaxKind::OptionalType);
1325-
return makeParserResult(TyR);
1328+
return makeParserResult(ParserStatus(base), TyR);
13261329
}
13271330

13281331
/// Parse a single implicitly unwrapped optional suffix, given that we
13291332
/// are looking at the exclamation mark.
13301333
ParserResult<TypeRepr>
1331-
Parser::parseTypeImplicitlyUnwrappedOptional(TypeRepr *base) {
1334+
Parser::parseTypeImplicitlyUnwrappedOptional(ParserResult<TypeRepr> base) {
13321335
SourceLoc exclamationLoc = consumeImplicitlyUnwrappedOptionalToken();
13331336
auto TyR =
1334-
new (Context) ImplicitlyUnwrappedOptionalTypeRepr(base, exclamationLoc);
1337+
new (Context) ImplicitlyUnwrappedOptionalTypeRepr(base.get(), exclamationLoc);
13351338
SyntaxContext->createNodeInPlace(SyntaxKind::ImplicitlyUnwrappedOptionalType);
1336-
return makeParserResult(TyR);
1339+
return makeParserResult(ParserStatus(base), TyR);
13371340
}
13381341

13391342
//===----------------------------------------------------------------------===//

test/IDE/complete_type.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,3 +790,24 @@ struct ContainExtension {
790790
// EXTENSION_INHERITANCE-DAG: Decl[TypeAlias]/CurrNominal: ProtoAlias[#FooProtocol#];
791791
// EXTENSION_INHERITANCE-DAG: Keyword/None: Type[#HasProtoAlias.Type#];
792792
// EXTENSION_INHERITANCE: End completions
793+
794+
var _: (() -> #^IN_POSTFIX_BASE_1?check=WITH_GLOBAL_TYPES^#)?
795+
var _: (() -> #^IN_POSTFIX_BASE_2?check=WITH_GLOBAL_TYPES^#)!
796+
var _: (() -> #^IN_POSTFIX_BASE_3?check=WITH_GLOBAL_TYPES^#)[1]
797+
var _: (() -> #^IN_POSTFIX_BASE_4?check=WITH_GLOBAL_TYPES^#).Protocol
798+
var _: (() -> #^IN_POSTFIX_BASE_5?check=WITH_GLOBAL_TYPES^#).Type
799+
800+
struct HaveNested {
801+
struct Nested {}
802+
}
803+
804+
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_1?check=POSTFIX_BASE_MEMBER^#?
805+
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_2?check=POSTFIX_BASE_MEMBER^#!
806+
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_3?check=POSTFIX_BASE_MEMBER^#[1]
807+
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_4?check=POSTFIX_BASE_MEMBER^#.Protocol
808+
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_5?check=POSTFIX_BASE_MEMBER^#.Type
809+
810+
// POSTFIX_BASE_MEMBER: Begin completions, 2 items
811+
// POSTFIX_BASE_MEMBER-DAG: Decl[Struct]/CurrNominal: Nested[#HaveNested.Nested#];
812+
// POSTFIX_BASE_MEMBER-DAG: Keyword/None: Type[#HaveNested.Type#];
813+
// POSTFIX_BASE_MEMBER: End completions

0 commit comments

Comments
 (0)