diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h index c96c773f6fab8..bbc39e23ed5fc 100644 --- a/include/swift/Parse/Parser.h +++ b/include/swift/Parse/Parser.h @@ -929,9 +929,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 b4fd7a1e6ce3e..57d75efd4f17f 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -4425,10 +4425,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; @@ -4447,7 +4455,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( @@ -4617,16 +4625,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(); @@ -6578,15 +6582,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(); @@ -6864,16 +6864,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(); @@ -6980,16 +6976,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(); @@ -7081,14 +7073,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",