Skip to content

Commit e7ef875

Browse files
authored
Merge pull request #1818 from ahoppen/ahoppen/basic-format-bug-template
Add a GitHub issue template to file actionable BasicFormat bugs
2 parents 49b3bbd + e2211be commit e7ef875

File tree

12 files changed

+225
-12
lines changed

12 files changed

+225
-12
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: BasicFormat Bug
2+
description: A bug in the BasicFormat module
3+
labels: [bug, BasicFormat]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: Thanks for taking the time to fill out this bug report! We would really appreciate if you could take the time to reduce the issue as described in [Filing BasicFormat Bug Reports](https://swiftpackageindex.com/apple/swift-syntax/main/documentation/swiftbasicformat/filingbugreports).
8+
- type: textarea
9+
id: source
10+
attributes:
11+
label: Source Code
12+
description: The source code that, when formatted, produces incorrectly formatted code.
13+
value: |
14+
```swift
15+
```
16+
- type: textarea
17+
id: source
18+
attributes:
19+
label: Actual Formatted Code
20+
description: The way that `BasicFormat` formats the above code
21+
value: |
22+
```swift
23+
```
24+
- type: textarea
25+
id: source
26+
attributes:
27+
label: Expected Formatted Code
28+
description: The way that you think `BasicFormat` should format the code
29+
value: |
30+
```swift
31+
```
32+
- type: textarea
33+
id: description
34+
attributes:
35+
label: Description
36+
description: |
37+
Any additional information you can provide for this issue, like
38+
- Has this issue started occurring recently?
39+
- Is the issue only happening under certain circumstances?

.github/ISSUE_TEMPLATE/PARSER_BUG.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ labels: [bug, SwiftParser]
44
body:
55
- type: markdown
66
attributes:
7-
value: Thanks for taking the time to fill out this bug report! If you could take the time to reduce the issue as described in [FilingBugReports.md](https://github.com/apple/swift-syntax/blob/main/Sources/SwiftParser/SwiftParser.docc/FilingBugReports.md), we would really appreciate that.
7+
value: Thanks for taking the time to fill out this bug report! We would really appreciate if you could take the time to reduce the issue as described in [Filing Parser Bug Reports](https://swiftpackageindex.com/apple/swift-syntax/main/documentation/swiftparser/filingbugreports).
88
- type: dropdown
99
id: issue-type
1010
attributes:
1111
label: Issue Kind
12-
description: What kind of issue is this? See [FilingBugReports.md](https://github.com/apple/swift-syntax/blob/main/Sources/SwiftParser/SwiftParser.docc/FilingBugReports.md) for more details.
12+
description: What kind of issue is this? See [Filing Parser Bug Reports](https://swiftpackageindex.com/apple/swift-syntax/main/documentation/swiftparser/filingbugreports) for more details.
1313
options:
1414
- Round-Trip Failure
1515
- Parser Crash

CodeGeneration/Sources/generate-swiftsyntax/templates/swiftsyntax/SyntaxKindFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ let syntaxKindFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
1919
try! EnumDeclSyntax(
2020
"""
2121
/// Enumerates the known kinds of Syntax represented in the Syntax tree.
22-
public enum SyntaxKind
22+
public enum SyntaxKind: CaseIterable
2323
"""
2424
) {
2525
DeclSyntax("case token")

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ let package = Package(
263263
.executableTarget(
264264
name: "swift-parser-cli",
265265
dependencies: [
266-
"_InstructionCounter", "SwiftDiagnostics", "SwiftOperators", "SwiftParser", "SwiftParserDiagnostics", "SwiftSyntax",
266+
"_InstructionCounter", "SwiftBasicFormat", "SwiftDiagnostics", "SwiftOperators", "SwiftParser", "SwiftParserDiagnostics", "SwiftSyntax",
267267
.product(name: "ArgumentParser", package: "swift-argument-parser"),
268268
]
269269
),
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Filing BasicFormat Bug Reports
2+
3+
Guide to provide steps for filing actionable bug reports for `BasicFormat` failures.
4+
5+
- Attention: Keep in mind that the primary goal of BasicFormat is to add trivia to a SwiftSyntax tree in a way that allows the parser to parse the same tree again, e.g. making sure that a keyword and an identifier are separated by a space. BasicFormat intentionally has no functionality to e.g. split lines.
6+
7+
Reducing a failure requires the `swift-parser-cli` utility that you can build by checking out `swift-syntax` and running
8+
```
9+
swift build --product swift-parser-cli
10+
```
11+
or building the `swift-parser-cli` target in Xcode.
12+
13+
1. After you have built `swift-parse-cli`, you can format a single source file using BasicFormat by running the following command. If you are only experiencing the issue while formatting a single node, e.g. while creating an `AccessorDeclSyntax` inside a macro, you can additionally pass the type of the node as `--node-type AccessorDeclSyntax`
14+
```
15+
swift-parser-cli basic-format /path/to/file/that/formats/incorrectly.swift
16+
```
17+
2. Remove as much code from your source file while still experiencing the formatting issue.
18+
3. File a bug report on <https://github.com/apple/swift-syntax/issues/new/choose> with the reduced source code.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>CFBundleName</key>
6+
<string>SwiftBasicFormat</string>
7+
<key>CFBundleDisplayName</key>
8+
<string>SwiftBasicFormat</string>
9+
<key>CFBundleIdentifier</key>
10+
<string>com.apple.swift-basic-format</string>
11+
<key>CFBundleDevelopmentRegion</key>
12+
<string>en</string>
13+
<key>CFBundleIconFile</key>
14+
<string>DocumentationIcon</string>
15+
<key>CFBundleIconName</key>
16+
<string>DocumentationIcon</string>
17+
<key>CFBundlePackageType</key>
18+
<string>DOCS</string>
19+
<key>CFBundleShortVersionString</key>
20+
<string>0.1.0</string>
21+
<key>CDDefaultCodeListingLanguage</key>
22+
<string>swift</string>
23+
<key>CFBundleVersion</key>
24+
<string>0.1.0</string>
25+
<key>CDAppleDefaultAvailability</key>
26+
<dict>
27+
<key>SwiftParser</key>
28+
<array>
29+
<dict>
30+
<key>name</key>
31+
<string>macOS</string>
32+
<key>version</key>
33+
<string>10.15</string>
34+
</dict>
35+
<dict>
36+
<key>name</key>
37+
<string>Mac Catalyst</string>
38+
<key>version</key>
39+
<string>13.0</string>
40+
</dict>
41+
<dict>
42+
<key>name</key>
43+
<string>iOS</string>
44+
<key>version</key>
45+
<string>13.0</string>
46+
</dict>
47+
<dict>
48+
<key>name</key>
49+
<string>tvOS</string>
50+
<key>version</key>
51+
<string>13.0</string>
52+
</dict>
53+
<dict>
54+
<key>name</key>
55+
<string>watchOS</string>
56+
<key>version</key>
57+
<string>6.0</string>
58+
</dict>
59+
</array>
60+
</dict>
61+
</dict>
62+
</plist>

Sources/SwiftSyntax/generated/SyntaxKind.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
/// Enumerates the known kinds of Syntax represented in the Syntax tree.
16-
public enum SyntaxKind {
16+
public enum SyntaxKind: CaseIterable {
1717
case token
1818
case accessesEffect
1919
case accessorBlock
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import ArgumentParser
14+
import SwiftBasicFormat
15+
import SwiftDiagnostics
16+
import SwiftSyntax
17+
import SwiftParser
18+
import SwiftParserDiagnostics
19+
20+
struct BasicFormat: ParsableCommand, ParseCommand {
21+
enum Error: Swift.Error, CustomStringConvertible {
22+
case unknownSyntaxNodeType(nodeType: String, parsableTypes: [String])
23+
24+
var description: String {
25+
switch self {
26+
case .unknownSyntaxNodeType(nodeType: let nodeType, parsableTypes: let parsableTypes):
27+
return """
28+
'\(nodeType)' is not a SwiftSyntax node type that conforms to SyntaxParsable. Possible options are:
29+
\(parsableTypes.map {" - \($0)" }.joined(separator: "\n"))
30+
"""
31+
}
32+
}
33+
}
34+
35+
static var configuration = CommandConfiguration(
36+
commandName: "basic-format",
37+
abstract: "Format a source file using BasicFormat"
38+
)
39+
40+
@OptionGroup
41+
var arguments: ParseArguments
42+
43+
@Option(help: "The number of spaces to use for indentation")
44+
var indentationWidth: Int = 4
45+
46+
@Option(help: "The type that the node should be parsed as")
47+
var nodeType: String = "SourceFileSyntax"
48+
49+
func run() throws {
50+
let parsableMetatypes = SyntaxKind.allCases.compactMap {
51+
$0.syntaxNodeType as? SyntaxParseable.Type
52+
}
53+
let parsableMetatypesByName = Dictionary(
54+
parsableMetatypes.map {
55+
(String(reflecting: $0).replacingOccurrences(of: "SwiftSyntax.", with: ""), $0)
56+
},
57+
uniquingKeysWith: { l, r in l }
58+
)
59+
60+
guard let parseType = parsableMetatypesByName[nodeType] else {
61+
throw Error.unknownSyntaxNodeType(nodeType: nodeType, parsableTypes: parsableMetatypesByName.keys.sorted())
62+
}
63+
64+
let tree = try sourceFileContents.withUnsafeBufferPointer { sourceBuffer in
65+
var parser = Parser(sourceBuffer)
66+
return parseType.parse(from: &parser)
67+
}
68+
69+
let resultTree: Syntax
70+
if foldSequences {
71+
resultTree = foldAllSequences(tree).0
72+
} else {
73+
resultTree = Syntax(tree)
74+
}
75+
76+
if resultTree.hasError {
77+
let diags = ParseDiagnosticsGenerator.diagnostics(for: tree)
78+
printerr(
79+
"""
80+
Source input contained syntax errors. Formatting might be incorrect due to these errors:
81+
\(DiagnosticsFormatter(colorize: TerminalHelper.isConnectedToTerminal).annotatedSource(tree: tree, diags: diags))
82+
----------------------------------------
83+
"""
84+
)
85+
}
86+
87+
let formattedTree = resultTree.formatted(using: SwiftBasicFormat.BasicFormat(indentationWidth: .spaces(indentationWidth)))
88+
89+
print(formattedTree.description)
90+
}
91+
}

Sources/swift-parser-cli/Commands/Reduce.swift

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ import Foundation
1616
import WinSDK
1717
#endif
1818

19-
/// Print the given message to stderr
20-
fileprivate func printerr(_ message: String, terminator: String = "\n") {
21-
FileHandle.standardError.write((message + terminator).data(using: .utf8)!)
22-
}
23-
2419
fileprivate func withTemporaryFile<T>(contents: [UInt8], body: (URL) throws -> T) throws -> T {
2520
var tempFileURL = FileManager.default.temporaryDirectory
2621
tempFileURL.appendPathComponent("swift-parser-cli-\(UUID().uuidString).swift")

Sources/swift-parser-cli/SyntaxUtils.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ import SwiftOperators
1515
import SwiftSyntax
1616

1717
/// Fold all of the sequences in the given source file.
18-
func foldAllSequences(_ tree: SourceFileSyntax) -> (Syntax, [Diagnostic]) {
18+
func foldAllSequences(_ tree: some SyntaxProtocol) -> (Syntax, [Diagnostic]) {
1919
var diags: [Diagnostic] = []
2020

2121
let recordOperatorError: (OperatorError) -> Void = { error in
2222
diags.append(error.asDiagnostic)
2323
}
2424
var operatorTable = OperatorTable.standardOperators
25-
operatorTable.addSourceFile(tree, errorHandler: recordOperatorError)
25+
if let sourceFile = tree as? SourceFileSyntax {
26+
operatorTable.addSourceFile(sourceFile, errorHandler: recordOperatorError)
27+
}
2628
let resultTree = operatorTable.foldAll(tree, errorHandler: recordOperatorError)
2729
return (resultTree, diags)
2830
}

0 commit comments

Comments
 (0)