diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index 72a89ea2762a7..38672aa3f9492 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -928,9 +928,8 @@ class Parser { std::pair, Optional> parseDeclListDelayed(IterableDeclContext *IDC); - bool parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc, - SourceLoc PosBeforeLB, - Diag<> ErrorDiag, + bool parseMemberDeclList(SourceLoc &LBLoc, SourceLoc &RBLoc, + Diag<> LBraceDiag, Diag<> RBraceDiag, IterableDeclContext *IDC); bool canDelayMemberDeclParsing(bool &HasOperatorDeclarations, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index cff3408235418..09010264d323f 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -4422,10 +4422,18 @@ ParserStatus Parser::parseDeclItem(bool &PreviousHadSemi, return Result; } -bool Parser::parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc, - SourceLoc PosBeforeLB, - Diag<> ErrorDiag, +bool Parser::parseMemberDeclList(SourceLoc &LBLoc, SourceLoc &RBLoc, + Diag<> LBraceDiag, Diag<> RBraceDiag, IterableDeclContext *IDC) { + if (parseToken(tok::l_brace, LBLoc, LBraceDiag)) { + LBLoc = RBLoc = PreviousLoc; + + // Cache the empty result to prevent delayed parsing. + Context.evaluator.cacheOutput( + ParseMembersRequest{IDC}, FingerprintAndMembers{None, {}}); + return true; + } + bool HasOperatorDeclarations; bool HasNestedClassDeclarations; @@ -4444,7 +4452,7 @@ bool Parser::parseMemberDeclList(SourceLoc LBLoc, SourceLoc &RBLoc, bool hadError = false; ParseDeclOptions Options = getMemberParseDeclOptions(IDC); auto membersAndHash = - parseDeclList(LBLoc, RBLoc, ErrorDiag, Options, IDC, hadError); + parseDeclList(LBLoc, RBLoc, RBraceDiag, Options, IDC, hadError); IDC->setMaybeHasOperatorDeclarations(); IDC->setMaybeHasNestedClassDeclarations(); Context.evaluator.cacheOutput( @@ -4614,16 +4622,12 @@ Parser::parseDeclExtension(ParseDeclOptions Flags, DeclAttributes &Attributes) { SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock); SourceLoc LBLoc, RBLoc; - auto PosBeforeLB = Tok.getLoc(); - if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_extension)) { - LBLoc = PreviousLoc; - RBLoc = LBLoc; - status.setIsParseError(); - } else { + { ContextChange CC(*this, ext); Scope S(this, ScopeKind::Extension); - if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB, + if (parseMemberDeclList(LBLoc, RBLoc, + diag::expected_lbrace_extension, diag::expected_rbrace_extension, ext)) status.setIsParseError(); @@ -6576,15 +6580,11 @@ ParserResult Parser::parseDeclEnum(ParseDeclOptions Flags, SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock); SourceLoc LBLoc, RBLoc; - SourceLoc PosBeforeLB = Tok.getLoc(); - if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_enum)) { - LBLoc = PreviousLoc; - RBLoc = LBLoc; - Status.setIsParseError(); - } else { + { Scope S(this, ScopeKind::EnumBody); - if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB, + if (parseMemberDeclList(LBLoc, RBLoc, + diag::expected_lbrace_enum, diag::expected_rbrace_enum, ED)) Status.setIsParseError(); @@ -6862,16 +6862,12 @@ ParserResult Parser::parseDeclStruct(ParseDeclOptions Flags, // Make the entities of the struct as a code block. SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock); SourceLoc LBLoc, RBLoc; - SourceLoc PosBeforeLB = Tok.getLoc(); - if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_struct)) { - LBLoc = PreviousLoc; - RBLoc = LBLoc; - Status.setIsParseError(); - } else { + { // Parse the body. Scope S(this, ScopeKind::StructBody); - if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB, + if (parseMemberDeclList(LBLoc, RBLoc, + diag::expected_lbrace_struct, diag::expected_rbrace_struct, SD)) Status.setIsParseError(); @@ -6978,16 +6974,12 @@ ParserResult Parser::parseDeclClass(ParseDeclOptions Flags, SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock); SourceLoc LBLoc, RBLoc; - auto PosBeforeLB = Tok.getLoc(); - if (parseToken(tok::l_brace, LBLoc, diag::expected_lbrace_class)) { - LBLoc = PreviousLoc; - RBLoc = LBLoc; - Status.setIsParseError(); - } else { + { // Parse the body. Scope S(this, ScopeKind::ClassBody); - if (parseMemberDeclList(LBLoc, RBLoc, PosBeforeLB, + if (parseMemberDeclList(LBLoc, RBLoc, + diag::expected_lbrace_class, diag::expected_rbrace_class, CD)) Status.setIsParseError(); @@ -7079,14 +7071,10 @@ parseDeclProtocol(ParseDeclOptions Flags, DeclAttributes &Attributes) { SyntaxParsingContext BlockContext(SyntaxContext, SyntaxKind::MemberDeclBlock); SourceLoc LBraceLoc; SourceLoc RBraceLoc; - SourceLoc PosBeforeLB = Tok.getLoc(); - if (parseToken(tok::l_brace, LBraceLoc, diag::expected_lbrace_protocol)) { - LBraceLoc = PreviousLoc; - RBraceLoc = LBraceLoc; - Status.setIsParseError(); - } else { + { // Parse the members. - if (parseMemberDeclList(LBraceLoc, RBraceLoc, PosBeforeLB, + if (parseMemberDeclList(LBraceLoc, RBraceLoc, + diag::expected_lbrace_protocol, diag::expected_rbrace_protocol, Proto)) Status.setIsParseError(); diff --git a/test/SourceKit/CodeComplete/complete_sequence_innertype.swift b/test/SourceKit/CodeComplete/complete_sequence_innertype.swift new file mode 100644 index 0000000000000..e6d114e5654b5 --- /dev/null +++ b/test/SourceKit/CodeComplete/complete_sequence_innertype.swift @@ -0,0 +1,10 @@ +func test() { + class C: +} + +// RUN: %sourcekitd-test \ +// RUN: -req=complete -pos=2:11 -repeat-request=2 %s -- %s -parse-as-library \ +// RUN: | %FileCheck %s + +// CHECK: key.results: [ +// CHECK: description: "Int",