From 99dff46e29e25d1d25c31ded95ad8b7f924f4edb Mon Sep 17 00:00:00 2001 From: Karolina Groszewska Date: Tue, 17 Oct 2023 21:35:51 -0500 Subject: [PATCH] Complete testRecovery28 Suggested changes + fixes from swift run Handle generic parameter on enum case Breaking things is fun Revert "Breaking things is fun" This reverts commit f5f14f2ea4397d992b947c60227ec05ebfb7f9bb. Revert "Revert "Breaking things is fun"" This reverts commit 4bf67d4c0469e62fad4ad902aa4127d50e4cfb4e. Revert "Suggested changes + fixes from swift run" This reverts commit 21e849826bd39f99805332ffcbeb0591d531e2b8. Revert "Add in documentation for AttributeNodes" This reverts commit 80e91bd78d9ba796673d931dcf017d41d4108b50. complete testRecovery28 complete testRecovery28 aaaaaaa --- Sources/SwiftParser/Declarations.swift | 9 ++ .../ParseDiagnosticsGenerator.swift | 18 +++ .../ParserDiagnosticMessages.swift | 3 + Tests/SwiftParserTest/DeclarationTests.swift | 113 ++++++++++++++++++ .../translated/RecoveryTests.swift | 13 +- 5 files changed, 152 insertions(+), 4 deletions(-) diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index 7075fcb0d7e..6cd0a74cb34 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -808,6 +808,14 @@ extension Parser { let unexpectedPeriod = self.consume(if: .period) let (unexpectedBeforeName, name) = self.expectIdentifier(keywordRecovery: true) + let unexpectedGenericParameters: RawUnexpectedNodesSyntax? + if self.at(prefix: "<") { + let genericParameters = self.parseGenericParameters() + unexpectedGenericParameters = RawUnexpectedNodesSyntax([genericParameters], arena: self.arena) + } else { + unexpectedGenericParameters = nil + } + let parameterClause: RawEnumCaseParameterClauseSyntax? if self.at(TokenSpec(.leftParen)) { parameterClause = self.parseParameterClause(RawEnumCaseParameterClauseSyntax.self) { parser in @@ -836,6 +844,7 @@ extension Parser { RawEnumCaseElementSyntax( RawUnexpectedNodesSyntax(combining: unexpectedPeriod, unexpectedBeforeName, arena: self.arena), name: name, + unexpectedGenericParameters, parameterClause: parameterClause, rawValue: rawValue, trailingComma: keepGoing, diff --git a/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift b/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift index 067ae580b55..ed1d63a6e75 100644 --- a/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift +++ b/Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift @@ -1074,6 +1074,24 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor { return .visitChildren } + public override func visit(_ node: EnumCaseElementSyntax) -> SyntaxVisitorContinueKind { + if shouldSkip(node) { + return .skipChildren + } + + if let unexpectedBetweenNameAndParameterClause = node.unexpectedBetweenNameAndParameterClause, + let genericParameter = unexpectedBetweenNameAndParameterClause.compactMap({ $0.as(GenericParameterClauseSyntax.self) }).only + { + addDiagnostic( + genericParameter, + .genericParamCantBeUsedInEnumCaseDecl, + handledNodes: [unexpectedBetweenNameAndParameterClause.id] + ) + } + + return .visitChildren + } + public override func visit(_ node: IfConfigClauseSyntax) -> SyntaxVisitorContinueKind { if shouldSkip(node) { return .skipChildren diff --git a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift index 0f2f5916a04..75955a37219 100644 --- a/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift +++ b/Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift @@ -167,6 +167,9 @@ extension DiagnosticMessage where Self == StaticParserError { public static var forbiddenInterpolatedString: Self { return .init("argument cannot be an interpolated string literal") } + public static var genericParamCantBeUsedInEnumCaseDecl: Self { + return .init("generic signature cannot be declared in enum 'case'") + } public static var initializerInPattern: Self { .init("unexpected initializer in pattern; did you mean to use '='?") } diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index de2bd77be3e..ee24ab0d121 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -2946,4 +2946,117 @@ final class DeclarationTests: ParserTestCase { ] ) } + + // https://github.com/apple/swift-syntax/issues/2273 + func testEnumCaseWithGenericParameter() { + assertParse( + """ + enum Foo { + case foo1️⃣(T) + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "generic signature cannot be declared in enum 'case'" + ) + ] + ) + + assertParse( + """ + enum Foo { + case bar1️⃣(param: T) + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "generic signature cannot be declared in enum 'case'" + ) + ] + ) + + assertParse( + """ + enum Foo { + case baz1️⃣ + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "generic signature cannot be declared in enum 'case'" + ) + ] + ) + + assertParse( + """ + enum Foo { + case one, two1️⃣ + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "generic signature cannot be declared in enum 'case'" + ) + ] + ) + + assertParse( + """ + enum Foo { + case three1️⃣, four + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "generic signature cannot be declared in enum 'case'" + ) + ] + ) + + assertParse( + """ + enum Foo { + case five1️⃣(param: T), six + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "generic signature cannot be declared in enum 'case'" + ) + ] + ) + + assertParse( + """ + enum Foo { + case seven1️⃣, eight2️⃣ + } + """, + diagnostics: [ + DiagnosticSpec( + locationMarker: "1️⃣", + message: "generic signature cannot be declared in enum 'case'" + ), + DiagnosticSpec( + locationMarker: "2️⃣", + message: "generic signature cannot be declared in enum 'case'" + ), + ] + ) + + assertParse( + """ + enum Foo { + case five(param: T), six + } + """ + ) + } } diff --git a/Tests/SwiftParserTest/translated/RecoveryTests.swift b/Tests/SwiftParserTest/translated/RecoveryTests.swift index 1f2f9428685..ba13cb8160e 100644 --- a/Tests/SwiftParserTest/translated/RecoveryTests.swift +++ b/Tests/SwiftParserTest/translated/RecoveryTests.swift @@ -429,10 +429,15 @@ final class RecoveryTests: ParserTestCase { } while { true }() """, diagnostics: [ - // TODO: Old parser expected error on line 2: missing condition in 'while' statement - // TODO: Old parser expected error on line 2: consecutive statements on a line must be separated by ';', Fix-It replacements: 10 - 10 = ';' - // TODO: Old parser expected warning on line 2: result of call to closure returning 'Bool' is unused - ] + DiagnosticSpec(message: "missing condition in 'while' statement"), + DiagnosticSpec(message: "consecutive statements on a line must be separated by newline or ';'", + fixIts: ["insert newline", "insert ';'"]), + DiagnosticSpec(message: "result of call to closure returning 'Bool' is unused", severity: .warning) + ], + fixedSource: """ + repeat { + } while <#expression#> + """ ) }