Skip to content

Update swift-syntax #1273

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 1 commit into from
Jan 30, 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
2 changes: 1 addition & 1 deletion CodeGeneration/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ let package = Package(
.executable(name: "generate-swiftsyntax", targets: ["generate-swiftsyntax"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-syntax.git", revision: "05916332d79994097ed7780f2fe34d33b16ddd31"),
.package(url: "https://github.com/apple/swift-syntax.git", revision: "06de1fa52ab79fba2d540b6a62fa3c2a1e7133f5"),
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMinor(from: "1.1.4")),
],
targets: [
Expand Down
4 changes: 2 additions & 2 deletions CodeGeneration/Sources/Utils/CodeGenerationFormat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public class CodeGenerationFormat: BasicFormat {

public func ensuringTwoLeadingNewlines<NodeType: SyntaxProtocol>(node: NodeType) -> NodeType {
if node.leadingTrivia?.first?.isNewline ?? false {
return node.withLeadingTrivia(indentedNewline + (node.leadingTrivia ?? []))
return node.with(\.leadingTrivia, indentedNewline + (node.leadingTrivia ?? []))
} else {
return node.withLeadingTrivia(indentedNewline + indentedNewline + (node.leadingTrivia ?? []))
return node.with(\.leadingTrivia, indentedNewline + indentedNewline + (node.leadingTrivia ?? []))
}
}

Expand Down
51 changes: 22 additions & 29 deletions CodeGeneration/Sources/generate-swiftsyntax/KeywordFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ let lookupTable = ArrayExprSyntax(leftSquare: .leftSquareBracketToken(trailingTr
}

let keywordFile = SourceFileSyntax {
ExtensionDeclSyntax(
DeclSyntax(
"""
\(raw: generateCopyrightHeader(for: "generate-swiftparser"))
Expand All @@ -35,19 +35,19 @@ let keywordFile = SourceFileSyntax {
"""
)

EnumDeclSyntax("""
try! EnumDeclSyntax("""
@frozen // FIXME: Not actually stable, works around a miscompile
public enum Keyword: UInt8, Hashable
""") {
for (index, keyword) in KEYWORDS.enumerated() {
EnumCaseDeclSyntax("case \(raw: keyword.escapedName)")
DeclSyntax("case \(raw: keyword.escapedName)")
}

InitializerDeclSyntax("@_spi(RawSyntax) public init?(_ text: SyntaxText)") {
SwitchStmtSyntax(expression: ExprSyntax("text.count")) {
try! InitializerDeclSyntax("@_spi(RawSyntax) public init?(_ text: SyntaxText)") {
try! SwitchStmtSyntax("switch text.count") {
for (length, keywords) in keywordsByLength() {
SwitchCaseSyntax("case \(raw: length):") {
SwitchStmtSyntax(expression: ExprSyntax("text")) {
try! SwitchStmtSyntax("switch text") {
for keyword in keywords {
SwitchCaseSyntax(#"case "\#(raw: keyword.name)":"#) {
ExprSyntax("self = .\(raw: keyword.escapedName)")
Expand All @@ -61,17 +61,12 @@ let keywordFile = SourceFileSyntax {
}
}

VariableDeclSyntax(
leadingTrivia: [
.docLineComment("/// Whether the token kind is switched from being an identifier to being an identifier to a keyword in the lexer."),
.newlines(1),
.docLineComment("/// This is true for keywords that used to be considered non-contextual."),
.newlines(1)
],
modifiers: [DeclModifierSyntax(name: .keyword(.public))],
name: "isLexerClassified",
type: TypeAnnotationSyntax(type: TypeSyntax("Bool"))) {
SwitchStmtSyntax(expression: ExprSyntax("self")) {
try! VariableDeclSyntax("""
/// Whether the token kind is switched from being an identifier to being an identifier to a keyword in the lexer.
/// This is true for keywords that used to be considered non-contextual.
public var isLexerClassified: Bool
""") {
try! SwitchStmtSyntax("switch self") {
for keyword in KEYWORDS {
if keyword.isLexerClassified {
SwitchCaseSyntax("case .\(raw: keyword.escapedName): return true")
Expand All @@ -81,22 +76,20 @@ let keywordFile = SourceFileSyntax {
}
}

VariableDeclSyntax("""
/// This is really unfortunate. Really, we should have a `switch` in
/// `Keyword.defaultText` to return the keyword's kind but the constant lookup
/// table is significantly faster. Ideally, we could also get the compiler to
/// constant-evaluate `Keyword.spi.defaultText` to a `SyntaxText` but I don't
/// see how that's possible right now.
private static let keywordTextLookupTable: [SyntaxText] = \(lookupTable)
""")
DeclSyntax("""
/// This is really unfortunate. Really, we should have a `switch` in
/// `Keyword.defaultText` to return the keyword's kind but the constant lookup
/// table is significantly faster. Ideally, we could also get the compiler to
/// constant-evaluate `Keyword.spi.defaultText` to a `SyntaxText` but I don't
/// see how that's possible right now.
private static let keywordTextLookupTable: [SyntaxText] = \(lookupTable)
""")

VariableDeclSyntax(
"""
DeclSyntax("""
@_spi(RawSyntax)
public var defaultText: SyntaxText {
return Keyword.keywordTextLookupTable[Int(self.rawValue)]
}
"""
)
""")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ import SyntaxSupport
import Utils

let basicFormatFile = SourceFileSyntax {
ImportDeclSyntax(
leadingTrivia: .docLineComment(generateCopyrightHeader(for: "generate-swiftbasicformat")),
path: [AccessPathComponentSyntax(name: "SwiftSyntax")]
)
DeclSyntax("""
\(raw: generateCopyrightHeader(for: "generate-swiftbasicformat"))
import SwiftSyntax
""")

ClassDeclSyntax("open class BasicFormat: SyntaxRewriter") {
VariableDeclSyntax("public var indentationLevel: Int = 0")
VariableDeclSyntax("open var indentation: TriviaPiece { .spaces(indentationLevel * 4) }")
VariableDeclSyntax("public var indentedNewline: Trivia { Trivia(pieces: [.newlines(1), indentation]) }")
VariableDeclSyntax("private var lastRewrittenToken: TokenSyntax?")
VariableDeclSyntax("private var putNextTokenOnNewLine: Bool = false")
try! ClassDeclSyntax("open class BasicFormat: SyntaxRewriter") {
DeclSyntax("public var indentationLevel: Int = 0")
DeclSyntax("open var indentation: TriviaPiece { .spaces(indentationLevel * 4) }")
DeclSyntax("public var indentedNewline: Trivia { Trivia(pieces: [.newlines(1), indentation]) }")
DeclSyntax("private var lastRewrittenToken: TokenSyntax?")
DeclSyntax("private var putNextTokenOnNewLine: Bool = false")

FunctionDeclSyntax("""
DeclSyntax("""
open override func visitPre(_ node: Syntax) {
if let keyPath = getKeyPath(node), shouldIndent(keyPath) {
indentationLevel += 1
Expand All @@ -39,7 +39,7 @@ let basicFormatFile = SourceFileSyntax {
}
"""
)
FunctionDeclSyntax("""
DeclSyntax("""
open override func visitPost(_ node: Syntax) {
if let keyPath = getKeyPath(node), shouldIndent(keyPath) {
indentationLevel -= 1
Expand All @@ -48,7 +48,7 @@ let basicFormatFile = SourceFileSyntax {
"""
)

FunctionDeclSyntax("""
DeclSyntax("""
open override func visit(_ node: TokenSyntax) -> TokenSyntax {
var leadingTrivia = node.leadingTrivia
var trailingTrivia = node.trailingTrivia
Expand Down Expand Up @@ -76,53 +76,53 @@ let basicFormatFile = SourceFileSyntax {
"""
)

FunctionDeclSyntax("open func shouldIndent(_ keyPath: AnyKeyPath) -> Bool") {
SwitchStmtSyntax(expression: ExprSyntax("keyPath")) {
try FunctionDeclSyntax("open func shouldIndent(_ keyPath: AnyKeyPath) -> Bool") {
try SwitchStmtSyntax("switch keyPath") {
for node in SYNTAX_NODES where !node.isBase {
for child in node.children where child.isIndented {
SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") {
ReturnStmtSyntax("return true")
StmtSyntax("return true")
}
}
}
SwitchCaseSyntax("default:") {
ReturnStmtSyntax("return false")
StmtSyntax("return false")
}
}
}

FunctionDeclSyntax("open func requiresLeadingNewline(_ keyPath: AnyKeyPath) -> Bool") {
SwitchStmtSyntax(expression: ExprSyntax("keyPath")) {
try FunctionDeclSyntax("open func requiresLeadingNewline(_ keyPath: AnyKeyPath) -> Bool") {
try SwitchStmtSyntax("switch keyPath") {
for node in SYNTAX_NODES where !node.isBase {
for child in node.children where child.requiresLeadingNewline {
SwitchCaseSyntax("case \\\(raw: node.type.syntaxBaseName).\(raw: child.swiftName):") {
ReturnStmtSyntax("return true")
StmtSyntax("return true")
}
}
}
SwitchCaseSyntax("default:") {
ReturnStmtSyntax("return putNextTokenOnNewLine")
StmtSyntax("return putNextTokenOnNewLine")
}
}
}

FunctionDeclSyntax("open func childrenSeparatedByNewline(_ node: Syntax) -> Bool") {
SwitchStmtSyntax(expression: ExprSyntax("node.as(SyntaxEnum.self)")) {
try FunctionDeclSyntax("open func childrenSeparatedByNewline(_ node: Syntax) -> Bool") {
try SwitchStmtSyntax("switch node.as(SyntaxEnum.self)") {
for node in SYNTAX_NODES where !node.isBase {
if node.elementsSeparatedByNewline {
SwitchCaseSyntax("case .\(raw: node.swiftSyntaxKind):") {
ReturnStmtSyntax("return true")
StmtSyntax("return true")
}
}
}
SwitchCaseSyntax("default:") {
ReturnStmtSyntax("return false")
StmtSyntax("return false")
}
}
}

FunctionDeclSyntax("open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool") {
SwitchStmtSyntax("""
try FunctionDeclSyntax("open func requiresLeadingSpace(_ token: TokenSyntax) -> Bool") {
StmtSyntax("""
switch (token.previousToken(viewMode: .sourceAccurate)?.tokenKind, token.tokenKind) {
case (.leftParen, .binaryOperator): // Ensures there is no space in @available(*, deprecated)
return false
Expand All @@ -131,27 +131,27 @@ let basicFormatFile = SourceFileSyntax {
}
""")

SwitchStmtSyntax(expression: ExprSyntax("token.tokenKind")) {
try SwitchStmtSyntax("switch token.tokenKind") {
for token in SYNTAX_TOKENS {
if token.requiresLeadingSpace {
SwitchCaseSyntax("case .\(raw: token.swiftKind):") {
ReturnStmtSyntax("return true")
StmtSyntax("return true")
}
}
}
for keyword in KEYWORDS where keyword.requiresLeadingSpace {
SwitchCaseSyntax("case .keyword(.\(raw: keyword.escapedName)):") {
ReturnStmtSyntax("return true")
StmtSyntax("return true")
}
}
SwitchCaseSyntax("default:") {
ReturnStmtSyntax("return false")
StmtSyntax("return false")
}
}
}

FunctionDeclSyntax("open func requiresTrailingSpace(_ token: TokenSyntax) -> Bool") {
SwitchStmtSyntax("""
try FunctionDeclSyntax("open func requiresTrailingSpace(_ token: TokenSyntax) -> Bool") {
StmtSyntax("""
switch (token.tokenKind, token.parent?.kind) {
case (.colon, .dictionaryExpr): // Ensures there is not space in `[:]`
return false
Expand All @@ -163,7 +163,7 @@ let basicFormatFile = SourceFileSyntax {
}
""")

SwitchStmtSyntax("""
StmtSyntax("""
switch (token.tokenKind, token.nextToken(viewMode: .sourceAccurate)?.tokenKind) {
case (.keyword(.as), .exclamationMark), // Ensures there is not space in `as!`
(.keyword(.as), .postfixQuestionMark), // Ensures there is not space in `as?`
Expand All @@ -183,26 +183,26 @@ let basicFormatFile = SourceFileSyntax {
}
""")

SwitchStmtSyntax(expression: ExprSyntax("token.tokenKind")) {
try SwitchStmtSyntax("switch token.tokenKind") {
for token in SYNTAX_TOKENS {
if token.requiresTrailingSpace {
SwitchCaseSyntax("case .\(raw: token.swiftKind):") {
ReturnStmtSyntax("return true")
StmtSyntax("return true")
}
}
}
for keyword in KEYWORDS where keyword.requiresTrailingSpace {
SwitchCaseSyntax("case .keyword(.\(raw: keyword.escapedName)):") {
ReturnStmtSyntax("return true")
StmtSyntax("return true")
}
}
SwitchCaseSyntax("default:") {
ReturnStmtSyntax("return false")
StmtSyntax("return false")
}
}
}

FunctionDeclSyntax("""
DeclSyntax("""
private func getKeyPath(_ node: Syntax) -> AnyKeyPath? {
guard let parent = node.parent else {
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,22 @@ fileprivate var node_child_classifications: [ChildClassification] {
}

let syntaxClassificationFile = SourceFileSyntax {
ImportDeclSyntax(
"""
DeclSyntax("""
\(raw: generateCopyrightHeader(for: "generate-ideutils"))
@_spi(RawSyntax) import SwiftSyntax
"""
)
""")

EnumDeclSyntax("public enum SyntaxClassification") {
try! EnumDeclSyntax("public enum SyntaxClassification") {
for classification in SYNTAX_CLASSIFICATIONS {
EnumCaseDeclSyntax(
"""
DeclSyntax("""
/// \(raw: classification.description)
case \(raw: classification.swiftName)
"""
)
""")
}
}

ExtensionDeclSyntax("extension SyntaxClassification") {
FunctionDeclSyntax(
try! ExtensionDeclSyntax("extension SyntaxClassification") {
try FunctionDeclSyntax(
"""
/// Checks if a node has a classification attached via its syntax definition.
/// - Parameters:
Expand All @@ -62,24 +58,24 @@ let syntaxClassificationFile = SourceFileSyntax {
parentKind: SyntaxKind, indexInParent: Int, childKind: SyntaxKind
) -> (SyntaxClassification, Bool)?
""") {
IfStmtSyntax("""
try IfStmtSyntax("""
// Separate checks for token nodes (most common checks) versus checks for layout nodes.
if childKind == .token
""") {
SwitchStmtSyntax(expression: ExprSyntax("(parentKind, indexInParent)")) {
try SwitchStmtSyntax("switch (parentKind, indexInParent)") {
for childClassification in node_child_classifications where childClassification.isToken {
SwitchCaseSyntax("case (.\(raw: childClassification.parent.swiftSyntaxKind), \(raw: childClassification.childIndex)):") {
ReturnStmtSyntax("return (.\(raw: childClassification.classification!.swiftName), \(raw: childClassification.force))")
StmtSyntax("return (.\(raw: childClassification.classification!.swiftName), \(raw: childClassification.force))")
}
}

SwitchCaseSyntax("default: return nil")
}
} else: {
SwitchStmtSyntax(expression: ExprSyntax("(parentKind, indexInParent)")) {
try SwitchStmtSyntax("switch (parentKind, indexInParent)") {
for childClassification in node_child_classifications where !childClassification.isToken {
SwitchCaseSyntax("case (.\(raw: childClassification.parent.swiftSyntaxKind), \(raw: childClassification.childIndex)):") {
ReturnStmtSyntax("return (.\(raw: childClassification.classification!.swiftName), \(raw: childClassification.force))")
StmtSyntax("return (.\(raw: childClassification.classification!.swiftName), \(raw: childClassification.force))")
}
}

Expand All @@ -89,23 +85,20 @@ let syntaxClassificationFile = SourceFileSyntax {
}
}

ExtensionDeclSyntax("extension RawTokenKind") {
VariableDeclSyntax(
modifiers: [DeclModifierSyntax(name: .keyword(.internal))],
name: IdentifierPatternSyntax("classification"),
type: TypeAnnotationSyntax(type: TypeSyntax("SyntaxClassification"))) {
SwitchStmtSyntax(expression: ExprSyntax("self.base")) {
try! ExtensionDeclSyntax("extension RawTokenKind") {
try VariableDeclSyntax("internal var classification: SyntaxClassification") {
try SwitchStmtSyntax("switch self.base") {
for token in SYNTAX_TOKENS {
SwitchCaseSyntax("case .\(raw: token.swiftKind):") {
if let classification = token.classification {
ReturnStmtSyntax("return .\(raw: classification.swiftName)")
StmtSyntax("return .\(raw: classification.swiftName)")
} else {
ReturnStmtSyntax("return .none)")
StmtSyntax("return .none)")
}
}
}
SwitchCaseSyntax("case .eof:") {
ReturnStmtSyntax("return .none")
StmtSyntax("return .none")
}
}
}
Expand Down
Loading