Skip to content

Add validation that all syntax collections end with ListSyntax #1913

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
merged 3 commits into from
Jul 24, 2023
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
12 changes: 6 additions & 6 deletions CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public let ATTRIBUTE_NODES: [Node] = [
),
Child(
name: "ObjCName",
kind: .node(kind: .objCSelector)
kind: .node(kind: .objCSelectorPieceList)
),
Child(
name: "ImplementsArguments",
Expand Down Expand Up @@ -132,11 +132,11 @@ public let ATTRIBUTE_NODES: [Node] = [
),
Child(
name: "EffectsArguments",
kind: .node(kind: .effectsArguments)
kind: .node(kind: .effectsArgumentList)
),
Child(
name: "DocumentationArguments",
kind: .node(kind: .documentationAttributeArguments)
kind: .node(kind: .documentationAttributeArgumentList)
),
]),
documentation: "The arguments of the attribute. In case the attribute takes multiple arguments, they are gather in the appropriate takes first.",
Expand Down Expand Up @@ -562,7 +562,7 @@ public let ATTRIBUTE_NODES: [Node] = [
),

Node(
kind: .documentationAttributeArguments,
kind: .documentationAttributeArgumentList,
base: .syntaxCollection,
nameForDiagnostics: "@_documentation arguments",
documentation: "The arguments of the '@_documentation' attribute",
Expand Down Expand Up @@ -592,7 +592,7 @@ public let ATTRIBUTE_NODES: [Node] = [
),

Node(
kind: .effectsArguments,
kind: .effectsArgumentList,
base: .syntaxCollection,
nameForDiagnostics: "@_effects arguments",
documentation: "The arguments of the '@_effect' attribute. These will be parsed during the SIL stage.",
Expand Down Expand Up @@ -719,7 +719,7 @@ public let ATTRIBUTE_NODES: [Node] = [

// objc-selector -> objc-selector-piece objc-selector?
Node(
kind: .objCSelector,
kind: .objCSelectorPieceList,
base: .syntaxCollection,
nameForDiagnostics: "Objective-C selector",
elementChoices: [.objCSelectorPiece]
Expand Down
4 changes: 2 additions & 2 deletions CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public let DECL_NODES: [Node] = [
),

Node(
kind: .importPath,
kind: .importPathComponentList,
base: .syntaxCollection,
nameForDiagnostics: nil,
elementChoices: [.importPathComponent]
Expand Down Expand Up @@ -1246,7 +1246,7 @@ public let DECL_NODES: [Node] = [
),
Child(
name: "Path",
kind: .collection(kind: .importPath, collectionElementName: "PathComponent"),
kind: .collection(kind: .importPathComponentList, collectionElementName: "PathComponent"),
documentation: "The path to the module, submodule or symbol being imported."
),
]
Expand Down
4 changes: 2 additions & 2 deletions CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1488,7 +1488,7 @@ public let EXPR_NODES: [Node] = [
),
Child(
name: "Segments",
kind: .collection(kind: .stringLiteralSegments, collectionElementName: "Segment")
kind: .collection(kind: .stringLiteralSegmentList, collectionElementName: "Segment")
),
Child(
name: "CloseQuote",
Expand All @@ -1503,7 +1503,7 @@ public let EXPR_NODES: [Node] = [
),

Node(
kind: .stringLiteralSegments,
kind: .stringLiteralSegmentList,
base: .syntaxCollection,
nameForDiagnostics: nil,
elementChoices: [.stringSegment, .expressionSegment]
Expand Down
29 changes: 24 additions & 5 deletions CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ public enum SyntaxNodeKind: String, CaseIterable {
case discardStmt
case doStmt
case documentationAttributeArgument
case documentationAttributeArguments
case documentationAttributeArgumentList
case dynamicReplacementArguments
case editorPlaceholderDecl
case editorPlaceholderExpr
case effectsArguments
case effectsArgumentList
case enumCaseDecl
case enumCaseElementList
case enumCaseElement
Expand Down Expand Up @@ -164,7 +164,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
case implicitlyUnwrappedOptionalType
case importDecl
case importPathComponent
case importPath
case importPathComponentList
case inOutExpr
case infixOperatorExpr
case inheritedTypeList
Expand Down Expand Up @@ -207,7 +207,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
case namedOpaqueReturnType
case nilLiteralExpr
case objCSelectorPiece
case objCSelector
case objCSelectorPieceList
case opaqueReturnTypeOfAttributeArguments
case operatorDecl
case operatorPrecedenceAndTypes
Expand Down Expand Up @@ -252,7 +252,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
case specializeExpr
case stmt
case stringLiteralExpr
case stringLiteralSegments
case stringLiteralSegmentList
case stringSegment
case structDecl
case subscriptDecl
Expand Down Expand Up @@ -369,4 +369,23 @@ public enum SyntaxNodeKind: String, CaseIterable {
return "Raw\(raw: rawValue.withFirstCharacterUppercased)SyntaxNodeProtocol"
}
}

public var deprecatedRawValue: String? {
switch self {
case .importPathComponentList:
return "accessPath"
case .importPathComponent:
return "accessPathComponent"
case .documentationAttributeArgumentList:
return "documentationAttributeArguments"
case .effectsArgumentList:
return "effectsArguments"
case .objCSelectorPieceList:
return "objCSelector"
case .stringLiteralSegmentList:
return "stringLiteralSegments"
default:
return nil
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ struct GenerateSwiftSyntax: ParsableCommand {
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["raw", "RawSyntaxNodes.swift"], rawSyntaxNodesFile),
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["raw", "RawSyntaxValidation.swift"], rawSyntaxValidationFile),
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["RenamedChildrenCompatibility.swift"], renamedChildrenCompatibilityFile),
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["RenamedNodesCompatibility.swift"], renamedSyntaxNodesFile),
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["SyntaxAnyVisitor.swift"], syntaxAnyVisitorFile),
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["SyntaxBaseNodes.swift"], syntaxBaseNodesFile),
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["SyntaxCollections.swift"], syntaxCollectionsFile),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import SwiftSyntax
import SwiftSyntaxBuilder
import SyntaxSupport
import Utils

let renamedSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
for syntaxKind in SyntaxNodeKind.allCases.sorted(by: { $0.deprecatedRawValue ?? "" < $1.deprecatedRawValue ?? "" }) {
if let deprecatedName = syntaxKind.deprecatedRawValue {
DeclSyntax(
"""
@available(*, deprecated, renamed: "\(syntaxKind.syntaxType)")
public typealias \(raw: deprecatedName.withFirstCharacterUppercased)Syntax = \(syntaxKind.syntaxType)
"""
)
}
}

try! ExtensionDeclSyntax("public extension SyntaxKind") {
for syntaxKind in SyntaxNodeKind.allCases.sorted(by: { $0.deprecatedRawValue ?? "" < $1.deprecatedRawValue ?? "" }) {
if let deprecatedName = syntaxKind.deprecatedRawValue {
DeclSyntax(
"""
static var \(raw: deprecatedName): Self {
return .\(syntaxKind.varOrCaseName)
}
"""
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,28 @@ class ValidateSyntaxNodes: XCTestCase {
)
}

func testSyntaxCollectionsShouldEndWithList() {
var failures: [ValidationFailure] = []

for node in SYNTAX_NODES.compactMap(\.collectionNode) {
if !node.kind.syntaxType.description.hasSuffix("ListSyntax") {
failures.append(
ValidationFailure(
node: node.kind,
message: "is a collection but does not end with ListSyntax"
)
)
}
}

assertFailuresMatchXFails(
failures,
expectedFailures: [
ValidationFailure(node: .unexpectedNodes, message: "is a collection but does not end with ListSyntax")
]
)
}

/// Implementation detail of `testSingleTokenChoiceChildNaming`, validating a single child.
///
/// - Returns: A failure message if validation failed, otherwise `nil`
Expand Down
10 changes: 5 additions & 5 deletions Sources/SwiftParser/Attributes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ extension Parser {
while !parser.at(.rightParen, .endOfFile) {
tokens.append(parser.consumeAnyToken())
}
return .effectsArguments(RawEffectsArgumentsSyntax(elements: tokens, arena: parser.arena))
return .effectsArguments(RawEffectsArgumentListSyntax(elements: tokens, arena: parser.arena))
}
case ._cdecl:
return parseAttribute(argumentMode: .required) { parser in
Expand Down Expand Up @@ -591,7 +591,7 @@ extension Parser {
}

extension Parser {
mutating func parseObjectiveCSelector() -> RawObjCSelectorSyntax {
mutating func parseObjectiveCSelector() -> RawObjCSelectorPieceListSyntax {
var elements = [RawObjCSelectorPieceSyntax]()
var loopProgress = LoopProgressCondition()
while self.hasProgressed(&loopProgress) {
Expand Down Expand Up @@ -633,7 +633,7 @@ extension Parser {
break
}
}
return RawObjCSelectorSyntax(elements: elements, arena: self.arena)
return RawObjCSelectorPieceListSyntax(elements: elements, arena: self.arena)
}
}

Expand Down Expand Up @@ -1069,7 +1069,7 @@ extension Parser {
}

extension Parser {
mutating func parseDocumentationAttributeArguments() -> RawDocumentationAttributeArgumentsSyntax {
mutating func parseDocumentationAttributeArguments() -> RawDocumentationAttributeArgumentListSyntax {
var arguments: [RawDocumentationAttributeArgumentSyntax] = []

var keepGoing: RawTokenSyntax? = nil
Expand Down Expand Up @@ -1138,7 +1138,7 @@ extension Parser {
)
} while keepGoing != nil

return RawDocumentationAttributeArgumentsSyntax(elements: arguments, arena: self.arena)
return RawDocumentationAttributeArgumentListSyntax(elements: arguments, arena: self.arena)
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/SwiftParser/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ extension Parser {
return self.consume(ifAnyIn: ImportDeclSyntax.ImportKindSpecifierOptions.self)
}

mutating func parseImportPath() -> RawImportPathSyntax {
mutating func parseImportPath() -> RawImportPathComponentListSyntax {
var elements = [RawImportPathComponentSyntax]()
var keepGoing: RawTokenSyntax? = nil
var loopProgress = LoopProgressCondition()
Expand All @@ -357,7 +357,7 @@ extension Parser {
)
)
} while keepGoing != nil && self.hasProgressed(&loopProgress)
return RawImportPathSyntax(elements: elements, arena: self.arena)
return RawImportPathComponentListSyntax(elements: elements, arena: self.arena)
}
}

Expand Down
14 changes: 7 additions & 7 deletions Sources/SwiftParser/StringLiterals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ extension Parser {
private func reclassifyNewlineOfLastSegmentAsTrivia(
rawStringDelimitersToken: RawTokenSyntax?,
openQuoteHasTrailingNewline: Bool,
middleSegments: inout [RawStringLiteralSegmentsSyntax.Element]
middleSegments: inout [RawStringLiteralSegmentListSyntax.Element]
) -> Bool {
switch middleSegments.last {
case .stringSegment(let lastMiddleSegment):
Expand Down Expand Up @@ -229,7 +229,7 @@ extension Parser {
/// attached to the string segment token.
private func postProcessIndentationAndEscapedNewlineOfMiddleSegments(
rawStringDelimitersToken: RawTokenSyntax?,
middleSegments: inout [RawStringLiteralSegmentsSyntax.Element],
middleSegments: inout [RawStringLiteralSegmentListSyntax.Element],
isFirstSegmentOnNewLine: Bool,
indentation: SyntaxText
) {
Expand Down Expand Up @@ -303,12 +303,12 @@ extension Parser {
private func postProcessMultilineStringLiteral(
rawStringDelimitersToken: RawTokenSyntax?,
openQuote: RawTokenSyntax,
segments allSegments: [RawStringLiteralSegmentsSyntax.Element],
segments allSegments: [RawStringLiteralSegmentListSyntax.Element],
closeQuote: RawTokenSyntax
) -> (
unexpectedBeforeOpenQuote: [RawTokenSyntax],
openQuote: RawTokenSyntax,
segments: [RawStringLiteralSegmentsSyntax.Element],
segments: [RawStringLiteralSegmentListSyntax.Element],
unexpectedBeforeCloseQuote: [RawTokenSyntax],
closeQuote: RawTokenSyntax
) {
Expand Down Expand Up @@ -485,7 +485,7 @@ extension Parser {
}

/// Parse segments.
var segments: [RawStringLiteralSegmentsSyntax.Element] = []
var segments: [RawStringLiteralSegmentListSyntax.Element] = []
var loopProgress = LoopProgressCondition()
while self.hasProgressed(&loopProgress) {
// If we encounter a token with leading trivia, we're no longer in the
Expand Down Expand Up @@ -574,7 +574,7 @@ extension Parser {
openDelimiter: openDelimiter,
RawUnexpectedNodesSyntax(combining: unexpectedBeforeOpenQuote, postProcessed.unexpectedBeforeOpenQuote, arena: self.arena),
openQuote: postProcessed.openQuote,
segments: RawStringLiteralSegmentsSyntax(elements: postProcessed.segments, arena: self.arena),
segments: RawStringLiteralSegmentListSyntax(elements: postProcessed.segments, arena: self.arena),
RawUnexpectedNodesSyntax(combining: postProcessed.unexpectedBeforeCloseQuote, unexpectedBeforeCloseQuote, arena: self.arena),
closeQuote: postProcessed.closeQuote,
unexpectedBeforeCloseDelimiter,
Expand All @@ -586,7 +586,7 @@ extension Parser {
openDelimiter: openDelimiter,
unexpectedBeforeOpenQuote,
openQuote: openQuote,
segments: RawStringLiteralSegmentsSyntax(elements: segments, arena: self.arena),
segments: RawStringLiteralSegmentListSyntax(elements: segments, arena: self.arena),
unexpectedBeforeCloseQuote,
closeQuote: closeQuote,
unexpectedBeforeCloseDelimiter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ public struct MissingAttributeArgument: ParserError {
}

public struct MissingBothStringQuotesOfStringSegments: ParserError {
public let stringSegments: StringLiteralSegmentsSyntax
public let stringSegments: StringLiteralSegmentListSyntax

public var message: String {
return #"expected \#(stringSegments.shortSingleLineContentDescription) to be surrounded by '"'"#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,17 @@ extension SyntaxKind {
return "'discard' statement"
case .doStmt:
return "'do' statement"
case .documentationAttributeArgumentList:
return "@_documentation arguments"
case .documentationAttributeArgument:
return "@_documentation argument"
case .documentationAttributeArguments:
return "@_documentation arguments"
case .dynamicReplacementArguments:
return "@_dynamicReplacement argument"
case .editorPlaceholderDecl:
return "editor placeholder"
case .editorPlaceholderExpr:
return "editor placeholder"
case .effectsArguments:
case .effectsArgumentList:
return "@_effects arguments"
case .enumCaseDecl:
return "enum case"
Expand Down Expand Up @@ -287,10 +287,10 @@ extension SyntaxKind {
return "trailing closure"
case .namedOpaqueReturnType:
return "named opaque return type"
case .objCSelectorPieceList:
return "Objective-C selector"
case .objCSelectorPiece:
return "Objective-C selector piece"
case .objCSelector:
return "Objective-C selector"
case .opaqueReturnTypeOfAttributeArguments:
return "opaque return type arguments"
case .operatorDecl:
Expand Down
Loading