Skip to content

Commit 57625ba

Browse files
committed
Handle DeinitializerDeclSyntax errors in a single diagnostic
1 parent ad237ff commit 57625ba

File tree

4 files changed

+128
-112
lines changed

4 files changed

+128
-112
lines changed

Sources/SwiftParserDiagnostics/MissingNodesError.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,20 @@ func nodesDescriptionAndCommonParent(_ nodes: [some SyntaxProtocol], format: Boo
161161
}
162162

163163
let partDescriptions = NodesDescriptionPart.descriptionParts(for: missingSyntaxNodes).map({ $0.description(format: format) ?? "syntax" })
164-
switch partDescriptions.count {
164+
165+
return (nil, formatDescriptions(partDescriptions))
166+
}
167+
168+
func formatDescriptions(_ descriptions: [String]) -> String {
169+
switch descriptions.count {
165170
case 0:
166-
return (nil, "syntax")
171+
return "syntax"
167172
case 1:
168-
return (nil, "\(partDescriptions.first!)")
173+
return descriptions.first!
169174
case 2:
170-
return (nil, "\(partDescriptions.first!) and \(partDescriptions.last!)")
175+
return "\(descriptions.first!) and \(descriptions.last!)"
171176
default:
172-
return (nil, "\(partDescriptions[0..<partDescriptions.count - 1].joined(separator: ", ")), and \(partDescriptions.last!)")
177+
return "\(descriptions[0..<descriptions.count - 1].joined(separator: ", ")), and \(descriptions.last!)"
173178
}
174179
}
175180

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -788,40 +788,44 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
788788
if shouldSkip(node) {
789789
return .skipChildren
790790
}
791-
if let unexpected = node.unexpectedBetweenDeinitKeywordAndEffectSpecifiers,
792-
let name = unexpected.presentTokens(satisfying: { $0.tokenKind.isIdentifier == true }).only
793-
{
794-
addDiagnostic(
795-
name,
796-
.deinitCannotHaveName,
797-
fixIts: [
798-
FixIt(message: RemoveNodesFixIt(name), changes: .makeMissing(name))
799-
],
800-
handledNodes: [name.id]
801-
)
791+
792+
var name: TokenSyntax? {
793+
return node.unexpectedBetweenDeinitKeywordAndEffectSpecifiers?.presentTokens(satisfying: { $0.tokenKind.isIdentifier == true }).only
802794
}
803-
if let unexpected = node.unexpectedBetweenDeinitKeywordAndEffectSpecifiers,
804-
let params = unexpected.compactMap({ $0.as(FunctionParameterClauseSyntax.self) }).only
805-
{
806-
addDiagnostic(
807-
params,
808-
.deinitCannotHaveParameters,
809-
fixIts: [
810-
FixIt(message: RemoveNodesFixIt(params), changes: .makeMissing(params))
811-
],
812-
handledNodes: [params.id]
813-
)
795+
796+
var params: FunctionParameterClauseSyntax? {
797+
return node.unexpectedBetweenDeinitKeywordAndEffectSpecifiers?.compactMap({ $0.as(FunctionParameterClauseSyntax.self) }).only
814798
}
815-
if let unexpected = node.unexpectedBetweenEffectSpecifiersAndBody,
816-
let returnType = unexpected.compactMap({ $0.as(ReturnClauseSyntax.self) }).only
817-
{
799+
800+
var returnType: ReturnClauseSyntax? {
801+
return node.unexpectedBetweenEffectSpecifiersAndBody?.compactMap({ $0.as(ReturnClauseSyntax.self) }).only
802+
}
803+
804+
var nodes: [any SyntaxProtocol] = []
805+
806+
if let name {
807+
nodes.append(name)
808+
}
809+
810+
if let params {
811+
nodes.append(params)
812+
}
813+
814+
if let returnType {
815+
nodes.append(returnType)
816+
}
817+
818+
if !nodes.isEmpty {
818819
addDiagnostic(
819-
returnType,
820-
.deinitCannotHaveReturnType,
820+
node,
821+
DeinitializerSignatureError(name: name, params: params, returnClause: returnType),
821822
fixIts: [
822-
FixIt(message: RemoveNodesFixIt(returnType), changes: .makeMissing(returnType))
823+
FixIt(
824+
message: RemoveNodesFixIt(nodes),
825+
changes: nodes.map { .makeMissing($0) }
826+
)
823827
],
824-
handledNodes: [returnType.id]
828+
handledNodes: nodes.map { $0.id }
825829
)
826830
}
827831

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,9 @@ extension DiagnosticMessage where Self == StaticParserError {
120120
public static var defaultOutsideOfSwitch: Self {
121121
.init("'default' label can only appear inside a 'switch' statement")
122122
}
123-
public static var deinitCannotHaveName: Self {
124-
.init("deinitializers cannot have a name")
125-
}
126-
public static var deinitCannotHaveParameters: Self {
127-
.init("deinitializers cannot have parameters")
128-
}
129123
public static var deinitCannotThrow: Self {
130124
.init("deinitializers cannot throw")
131125
}
132-
public static var deinitCannotHaveReturnType: Self {
133-
.init("deinitializers cannot have return type")
134-
}
135126
public static var editorPlaceholderInSourceFile: Self {
136127
.init("editor placeholder in source file")
137128
}
@@ -305,6 +296,30 @@ public struct CannotParseVersionTuple: ParserError {
305296
}
306297
}
307298

299+
public struct DeinitializerSignatureError: ParserError {
300+
public let name: TokenSyntax?
301+
public let params: FunctionParameterClauseSyntax?
302+
public let returnClause: ReturnClauseSyntax?
303+
304+
public var message: String {
305+
var descriptions: [String] = []
306+
307+
if name != nil {
308+
descriptions += ["name"]
309+
}
310+
311+
if params != nil {
312+
descriptions += ["parameters"]
313+
}
314+
315+
if returnClause != nil {
316+
descriptions += ["return clause"]
317+
}
318+
319+
return "deinitializers cannot have \(formatDescriptions(descriptions))"
320+
}
321+
}
322+
308323
public struct DuplicateEffectSpecifiers: ParserError {
309324
public let correctSpecifier: TokenSyntax
310325
public let unexpectedSpecifier: TokenSyntax
@@ -706,7 +721,7 @@ public struct RemoveRedundantFixIt: ParserFixIt {
706721
public struct RemoveNodesFixIt: ParserFixIt {
707722
public let nodesToRemove: [Syntax]
708723

709-
init(_ nodesToRemove: [some SyntaxProtocol]) {
724+
init(_ nodesToRemove: [any SyntaxProtocol]) {
710725
self.nodesToRemove = nodesToRemove.map(Syntax.init)
711726
}
712727

0 commit comments

Comments
 (0)