Skip to content

[5.5][CodeCompletion] Keep completion status when parsing postfix types #37876

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1256,17 +1256,18 @@ class Parser {
const TypeAttributes &attrs);

ParserResult<TypeRepr> parseTypeTupleBody();
ParserResult<TypeRepr> parseTypeArray(TypeRepr *Base);
ParserResult<TypeRepr> parseTypeArray(ParserResult<TypeRepr> Base);

/// Parse a collection type.
/// type-simple:
/// '[' type ']'
/// '[' type ':' type ']'
ParserResult<TypeRepr> parseTypeCollection();

ParserResult<TypeRepr> parseTypeOptional(TypeRepr *Base);
ParserResult<TypeRepr> parseTypeOptional(ParserResult<TypeRepr> Base);

ParserResult<TypeRepr> parseTypeImplicitlyUnwrappedOptional(TypeRepr *Base);
ParserResult<TypeRepr>
parseTypeImplicitlyUnwrappedOptional(ParserResult<TypeRepr> Base);

bool isOptionalToken(const Token &T) const;
SourceLoc consumeOptionalToken();
Expand Down
39 changes: 21 additions & 18 deletions lib/Parse/ParseType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,16 +235,16 @@ ParserResult<TypeRepr> Parser::parseTypeSimple(

if (!Tok.isAtStartOfLine()) {
if (isOptionalToken(Tok)) {
ty = parseTypeOptional(ty.get());
ty = parseTypeOptional(ty);
continue;
}
if (isImplicitlyUnwrappedOptionalToken(Tok)) {
ty = parseTypeImplicitlyUnwrappedOptional(ty.get());
ty = parseTypeImplicitlyUnwrappedOptional(ty);
continue;
}
// Parse legacy array types for migration.
if (Tok.is(tok::l_square) && reason != ParseTypeReason::CustomAttribute)
ty = parseTypeArray(ty.get());
ty = parseTypeArray(ty);
}
break;
}
Expand Down Expand Up @@ -1182,12 +1182,11 @@ ParserResult<TypeRepr> Parser::parseTypeTupleBody() {
/// type-array '[' ']'
/// type-array '[' expr ']'
///
ParserResult<TypeRepr> Parser::parseTypeArray(TypeRepr *Base) {
ParserResult<TypeRepr> Parser::parseTypeArray(ParserResult<TypeRepr> Base) {
assert(Tok.isFollowingLSquare());
Parser::StructureMarkerRAII ParsingArrayBound(*this, Tok);
SourceLoc lsquareLoc = consumeToken();
ArrayTypeRepr *ATR = nullptr;


// Handle a postfix [] production, a common typo for a C-like array.

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

SourceLoc rsquareLoc;
if (parseMatchingToken(tok::r_square, rsquareLoc,
diag::expected_rbracket_array_type, lsquareLoc))
return makeParserErrorResult(Base);
diag::expected_rbracket_array_type, lsquareLoc)) {
Base.setIsParseError();
return Base;
}

auto baseTyR = Base.get();

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

// Build a normal array slice type for recovery.
ATR = new (Context) ArrayTypeRepr(Base,
SourceRange(Base->getStartLoc(), rsquareLoc));
return makeParserResult(ATR);
ArrayTypeRepr *ATR = new (Context) ArrayTypeRepr(
baseTyR, SourceRange(baseTyR->getStartLoc(), rsquareLoc));
return makeParserResult(ParserStatus(Base), ATR);
}

ParserResult<TypeRepr> Parser::parseTypeCollection() {
Expand Down Expand Up @@ -1317,22 +1320,22 @@ SourceLoc Parser::consumeImplicitlyUnwrappedOptionalToken() {
/// Parse a single optional suffix, given that we are looking at the
/// question mark.
ParserResult<TypeRepr>
Parser::parseTypeOptional(TypeRepr *base) {
Parser::parseTypeOptional(ParserResult<TypeRepr> base) {
SourceLoc questionLoc = consumeOptionalToken();
auto TyR = new (Context) OptionalTypeRepr(base, questionLoc);
auto TyR = new (Context) OptionalTypeRepr(base.get(), questionLoc);
SyntaxContext->createNodeInPlace(SyntaxKind::OptionalType);
return makeParserResult(TyR);
return makeParserResult(ParserStatus(base), TyR);
}

/// Parse a single implicitly unwrapped optional suffix, given that we
/// are looking at the exclamation mark.
ParserResult<TypeRepr>
Parser::parseTypeImplicitlyUnwrappedOptional(TypeRepr *base) {
Parser::parseTypeImplicitlyUnwrappedOptional(ParserResult<TypeRepr> base) {
SourceLoc exclamationLoc = consumeImplicitlyUnwrappedOptionalToken();
auto TyR =
new (Context) ImplicitlyUnwrappedOptionalTypeRepr(base, exclamationLoc);
new (Context) ImplicitlyUnwrappedOptionalTypeRepr(base.get(), exclamationLoc);
SyntaxContext->createNodeInPlace(SyntaxKind::ImplicitlyUnwrappedOptionalType);
return makeParserResult(TyR);
return makeParserResult(ParserStatus(base), TyR);
}

//===----------------------------------------------------------------------===//
Expand Down
21 changes: 21 additions & 0 deletions test/IDE/complete_type.swift
Original file line number Diff line number Diff line change
Expand Up @@ -790,3 +790,24 @@ struct ContainExtension {
// EXTENSION_INHERITANCE-DAG: Decl[TypeAlias]/CurrNominal: ProtoAlias[#FooProtocol#];
// EXTENSION_INHERITANCE-DAG: Keyword/None: Type[#HasProtoAlias.Type#];
// EXTENSION_INHERITANCE: End completions

var _: (() -> #^IN_POSTFIX_BASE_1?check=WITH_GLOBAL_TYPES^#)?
var _: (() -> #^IN_POSTFIX_BASE_2?check=WITH_GLOBAL_TYPES^#)!
var _: (() -> #^IN_POSTFIX_BASE_3?check=WITH_GLOBAL_TYPES^#)[1]
var _: (() -> #^IN_POSTFIX_BASE_4?check=WITH_GLOBAL_TYPES^#).Protocol
var _: (() -> #^IN_POSTFIX_BASE_5?check=WITH_GLOBAL_TYPES^#).Type

struct HaveNested {
struct Nested {}
}

var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_1?check=POSTFIX_BASE_MEMBER^#?
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_2?check=POSTFIX_BASE_MEMBER^#!
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_3?check=POSTFIX_BASE_MEMBER^#[1]
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_4?check=POSTFIX_BASE_MEMBER^#.Protocol
var _: HaveNested.#^IN_POSTFIX_BASE_MEMBER_5?check=POSTFIX_BASE_MEMBER^#.Type

// POSTFIX_BASE_MEMBER: Begin completions, 2 items
// POSTFIX_BASE_MEMBER-DAG: Decl[Struct]/CurrNominal: Nested[#HaveNested.Nested#];
// POSTFIX_BASE_MEMBER-DAG: Keyword/None: Type[#HaveNested.Type#];
// POSTFIX_BASE_MEMBER: End completions