Skip to content

Commit a3cdd02

Browse files
committed
Move Format to a separate package
This way we can use `Format` to format Fix-Its in the parser
1 parent 889eadf commit a3cdd02

25 files changed

+495
-334
lines changed

Code-Generation/Package.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,32 @@ let package = Package(
88
.macOS(.v10_15),
99
],
1010
products: [
11+
.executable(name: "generate-swiftbasicformat", targets: ["generate-swiftbasicformat"]),
1112
.executable(name: "generate-swiftsyntaxbuilder", targets: ["generate-swiftsyntaxbuilder"]),
1213
],
1314
dependencies: [
1415
.package(url: "https://github.com/apple/swift-syntax.git", revision: "dcd692d759e09730098e45ba7276d0d96d004bac"),
1516
.package(url: "https://github.com/apple/swift-argument-parser.git", .upToNextMinor(from: "1.1.4")),
1617
],
1718
targets: [
19+
.executableTarget(
20+
name: "generate-swiftbasicformat",
21+
dependencies: [
22+
.product(name: "SwiftSyntax", package: "swift-syntax"),
23+
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
24+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
25+
"SyntaxSupport",
26+
"Utils"
27+
]
28+
),
1829
.executableTarget(
1930
name: "generate-swiftsyntaxbuilder",
2031
dependencies: [
32+
.product(name: "SwiftSyntax", package: "swift-syntax"),
2133
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
2234
.product(name: "ArgumentParser", package: "swift-argument-parser"),
23-
"SyntaxSupport"
35+
"SyntaxSupport",
36+
"Utils"
2437
]
2538
),
2639
.target(
@@ -46,5 +59,13 @@ let package = Package(
4659
"TypeNodes.swift.gyb"
4760
]
4861
),
62+
.target(
63+
name: "Utils",
64+
dependencies: [
65+
.product(name: "SwiftSyntax", package: "swift-syntax"),
66+
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
67+
"SyntaxSupport"
68+
]
69+
),
4970
]
5071
)

Code-Generation/Sources/generate-swiftsyntaxbuilder/String+Extensions.swift renamed to Code-Generation/Sources/Utils/String+Extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import Foundation
1414

15-
extension StringProtocol {
15+
public extension StringProtocol {
1616
var withFirstCharacterLowercased: String { prefix(1).lowercased() + dropFirst() }
1717
var withFirstCharacterUppercased: String { prefix(1).uppercased() + dropFirst() }
1818
var backticked: String { "`\(self)`" }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import SyntaxSupport
1616

1717
/// Extension to the `Child` type to provide functionality specific to
1818
/// SwiftSyntaxBuilder.
19-
extension Child {
19+
public extension Child {
2020
/// The type of this child, represented by a `SyntaxBuildableType`, which can
2121
/// be used to create the corresponding `Buildable` and `ExpressibleAs` types.
2222
var type: SyntaxBuildableType {

Code-Generation/Sources/generate-swiftsyntaxbuilder/SyntaxBuildableNode.swift renamed to Code-Generation/Sources/Utils/SyntaxBuildableNode.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SyntaxSupport
1414

1515
/// Extension to the `Node` type to provide functionality specific to
1616
/// SwiftSyntaxBuilder.
17-
extension Node {
17+
public extension Node {
1818
/// The node's syntax kind as `SyntaxBuildableType`.
1919
var type: SyntaxBuildableType {
2020
SyntaxBuildableType(syntaxKind: syntaxKind)

Code-Generation/Sources/generate-swiftsyntaxbuilder/SyntaxBuildableType.swift renamed to Code-Generation/Sources/Utils/SyntaxBuildableType.swift

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,31 @@ import SyntaxSupport
1818
/// SwiftSyntaxBuilder. In particular, this includes the functionality to create
1919
/// the `*Buildable`, `ExpressibleAs*` and `*Syntax` Swift types from the syntax
2020
/// kind.
21-
struct SyntaxBuildableType: Hashable {
22-
let syntaxKind: String
23-
let tokenKind: String?
24-
let isOptional: Bool
21+
public struct SyntaxBuildableType: Hashable {
22+
public let syntaxKind: String
23+
public let tokenKind: String?
24+
public let isOptional: Bool
2525

2626
/// Whether this is a token.
27-
var isToken: Bool {
27+
public var isToken: Bool {
2828
syntaxKind == "Token"
2929
}
3030

3131
/// This type with `isOptional` set to false.
32-
var nonOptional: Self {
32+
public var nonOptional: Self {
3333
tokenKind.map { Self(syntaxKind: $0) } ?? Self(syntaxKind: syntaxKind)
3434
}
3535

3636
/// The token if this is a token.
37-
var token: TokenSpec? {
37+
public var token: TokenSpec? {
3838
tokenKind.flatMap { SYNTAX_TOKEN_MAP[$0] }
3939
}
4040

4141
/// If the type has a default value (because it is optional or a token
4242
/// with fixed test), return an expression of the form ` = defaultValue`
4343
/// that can be used as the default value for a function parameter.
4444
/// Otherwise, return the empty string.
45-
var defaultInitialization: ExpressibleAsExprBuildable? {
45+
public var defaultInitialization: ExpressibleAsExprBuildable? {
4646
if isOptional {
4747
return NilLiteralExpr()
4848
} else if isToken {
@@ -56,14 +56,14 @@ struct SyntaxBuildableType: Hashable {
5656
}
5757

5858
/// Whether the type is a syntax collection.
59-
var isSyntaxCollection: Bool {
59+
public var isSyntaxCollection: Bool {
6060
syntaxKind == "SyntaxCollection"
6161
|| (baseType.map(\.isSyntaxCollection) ?? false)
6262
}
6363

6464
/// The raw base name of this kind. Used for the `build*` methods in the
6565
/// defined in the buildable types.
66-
var baseName: String {
66+
public var baseName: String {
6767
syntaxKind
6868
}
6969

@@ -75,20 +75,20 @@ struct SyntaxBuildableType: Hashable {
7575
/// - For base kinds: `<BaseKind>Buildable`, e.g. `ExprBuildable` (these are implemented as protocols)
7676
/// - For token: `TokenSyntax` (tokens don't have a dedicated type in SwiftSyntaxBuilder)
7777
/// If the type is optional, the type is wrapped in an `OptionalType`.
78-
var buildable: ExpressibleAsTypeBuildable {
78+
public var buildable: ExpressibleAsTypeBuildable {
7979
optionalWrapped(type: buildableBaseName)
8080
}
8181

8282
/// Whether parameters of this type should be initializable by a result builder.
8383
/// Used for certain syntax collections and block-like structures (e.g. `CodeBlock`,
8484
/// `MemberDeclList`).
85-
var isBuilderInitializable: Bool {
85+
public var isBuilderInitializable: Bool {
8686
BUILDER_INITIALIZABLE_TYPES.keys.contains(buildableBaseName)
8787
}
8888

8989
/// A type suitable for initializing this type through a result builder (e.g.
9090
/// returns `CodeBlockItemList` for `CodeBlock`) and otherwise itself.
91-
var builderInitializableType: Self {
91+
public var builderInitializableType: Self {
9292
Self(
9393
syntaxKind: BUILDER_INITIALIZABLE_TYPES[buildableBaseName].flatMap { $0 } ?? buildableBaseName,
9494
isOptional: isOptional
@@ -97,7 +97,7 @@ struct SyntaxBuildableType: Hashable {
9797

9898
/// The type from `buildable()` without any question marks attached.
9999
/// This is used for the `create*` methods defined in the `ExpressibleAs*` protocols.
100-
var buildableBaseName: String {
100+
public var buildableBaseName: String {
101101
if SYNTAX_BASE_KINDS.contains(syntaxKind) {
102102
return "\(syntaxKind)Buildable"
103103
} else {
@@ -107,7 +107,7 @@ struct SyntaxBuildableType: Hashable {
107107

108108
/// The `ExpressibleAs*` Swift type for this syntax kind without any
109109
/// question marks attached.
110-
var expressibleAsBaseName: String {
110+
public var expressibleAsBaseName: String {
111111
if isToken {
112112
// Tokens don't have a dedicated ExpressibleAs type.
113113
return buildableBaseName
@@ -119,13 +119,13 @@ struct SyntaxBuildableType: Hashable {
119119
/// The `ExpressibleAs*` Swift type for this syntax kind. Tokens don't
120120
/// have an `ExpressibleAs*` type, so for those this method just returns
121121
/// `TokenSyntax`. If the type is optional, this terminates with a `?`.
122-
var expressibleAs: ExpressibleAsTypeBuildable {
122+
public var expressibleAs: ExpressibleAsTypeBuildable {
123123
optionalWrapped(type: expressibleAsBaseName)
124124
}
125125

126126
/// The corresponding `*Syntax` type defined in the `SwiftSyntax` module,
127127
/// without any question marks attached.
128-
var syntaxBaseName: String {
128+
public var syntaxBaseName: String {
129129
if syntaxKind == "Syntax" {
130130
return "Syntax"
131131
} else {
@@ -136,60 +136,60 @@ struct SyntaxBuildableType: Hashable {
136136
/// The corresponding `*Syntax` type defined in the `SwiftSyntax` module,
137137
/// which will eventually get built from `SwiftSyntaxBuilder`. If the type
138138
/// is optional, this terminates with a `?`.
139-
var syntax: ExpressibleAsTypeBuildable {
139+
public var syntax: ExpressibleAsTypeBuildable {
140140
optionalWrapped(type: syntaxBaseName)
141141
}
142142

143143
/// Assuming that this is a base kind, return the corresponding `*ListBuildable` type
144144
/// without any question marks attached.
145-
var listBuildableBaseName: String {
145+
public var listBuildableBaseName: String {
146146
assert(SYNTAX_BASE_KINDS.contains(syntaxKind), "ListBuildable types only exist for syntax base kinds")
147147
return "\(syntaxKind)ListBuildable"
148148
}
149149

150150
/// Assuming that this is a base kind, return the corresponding `*ListBuildable` type.
151-
var listBuildable: ExpressibleAsTypeBuildable {
151+
public var listBuildable: ExpressibleAsTypeBuildable {
152152
optionalWrapped(type: listBuildableBaseName)
153153
}
154154

155155
/// Assuming that this is a collection type, the non-optional type of the result builder
156156
/// that can be used to build the collection.
157-
var resultBuilderBaseName: String {
157+
public var resultBuilderBaseName: String {
158158
"\(syntaxKind)Builder"
159159
}
160160

161161
/// Assuming that this is a collection type, the type of the result builder
162162
/// that can be used to build the collection.
163-
var resultBuilder: ExpressibleAsTypeBuildable {
163+
public var resultBuilder: ExpressibleAsTypeBuildable {
164164
optionalWrapped(type: resultBuilderBaseName)
165165
}
166166

167167
/// The collection types in which this type occurs as an element.
168168
/// We automatically make the `ExpressibleAs*` protocols conform to the
169169
/// `ExpressibleAs*` protocol of the collection they occur in.
170-
var elementInCollections: [Self] {
170+
public var elementInCollections: [Self] {
171171
SYNTAX_NODES
172172
.filter { $0.isSyntaxCollection && $0.collectionElementType == self }
173173
.map { $0.type }
174174
}
175175

176176
/// Whether this type has the `WithTrailingComma` trait.
177-
var hasWithTrailingCommaTrait: Bool {
177+
public var hasWithTrailingCommaTrait: Bool {
178178
SYNTAX_NODES.contains { $0.type == self && $0.traits.contains("WithTrailingComma") }
179179
}
180180

181181
/// Types that take a single non-optional parameter of this types
182182
/// and to which this type is thus convertible. We automatically
183183
/// make the `ExpressibleAs*` of this type conform to the `ExpressibleAs*`
184184
/// protocol of the convertible types.
185-
var convertibleToTypes: [Self] {
185+
public var convertibleToTypes: [Self] {
186186
(SYNTAX_BUILDABLE_EXPRESSIBLE_AS_CONFORMANCES[buildableBaseName] ?? [])
187187
.map { Self(syntaxKind: $0) }
188188
}
189189

190190
/// If this type is not a base kind, its base type (see `SyntaxBuildableNode.base_type()`),
191191
/// otherwise `nil`.
192-
var baseType: Self? {
192+
public var baseType: Self? {
193193
if !SYNTAX_BASE_KINDS.contains(syntaxKind) && !isToken {
194194
return Node.from(type: self).baseType
195195
} else {
@@ -199,7 +199,7 @@ struct SyntaxBuildableType: Hashable {
199199

200200
/// The types to which this `ExpressibleAs*` type conforms to via
201201
/// automatically generated conformances.
202-
var generatedExpressibleAsConformances: [Self] {
202+
public var generatedExpressibleAsConformances: [Self] {
203203
var conformances = elementInCollections + convertibleToTypes
204204
if let baseType = baseType, baseType.baseName != "SyntaxCollection" {
205205
conformances.append(baseType)
@@ -209,7 +209,7 @@ struct SyntaxBuildableType: Hashable {
209209

210210
/// The types to which this `ExpressibleAs*` type conforms to via
211211
/// automatically generated conformances, including transitive conformances.
212-
var transitiveExpressibleAsConformances: [Self] {
212+
public var transitiveExpressibleAsConformances: [Self] {
213213
generatedExpressibleAsConformances.flatMap { conformance in
214214
[conformance] + conformance.transitiveExpressibleAsConformances
215215
}
@@ -218,13 +218,13 @@ struct SyntaxBuildableType: Hashable {
218218
/// The types to which this `ExpressibleAs*` type implicitly conforms
219219
/// to via transitive conformances. These conformances don't need to be
220220
/// spelled out explicitly in the source code.
221-
var impliedExpressibleAsConformances: [Self] {
221+
public var impliedExpressibleAsConformances: [Self] {
222222
generatedExpressibleAsConformances.flatMap { conformance in
223223
conformance.transitiveExpressibleAsConformances
224224
}
225225
}
226226

227-
init(syntaxKind: String, isOptional: Bool = false) {
227+
public init(syntaxKind: String, isOptional: Bool = false) {
228228
self.isOptional = isOptional
229229
if syntaxKind.hasSuffix("Token") {
230230
// There are different token kinds but all of them are represented by `Token` in the Swift source (see `kind_to_type` in `gyb_syntax_support`).
@@ -237,7 +237,7 @@ struct SyntaxBuildableType: Hashable {
237237
}
238238

239239
/// Wraps a type in an optional depending on whether `isOptional` is true.
240-
func optionalWrapped(type: ExpressibleAsTypeBuildable) -> ExpressibleAsTypeBuildable {
240+
public func optionalWrapped(type: ExpressibleAsTypeBuildable) -> ExpressibleAsTypeBuildable {
241241
if isOptional {
242242
return OptionalType(wrappedType: type)
243243
} else {
@@ -246,7 +246,7 @@ struct SyntaxBuildableType: Hashable {
246246
}
247247

248248
/// Wraps a type in an optional chaining depending on whether `isOptional` is true.
249-
func optionalChained(expr: ExpressibleAsExprBuildable) -> ExpressibleAsExprBuildable {
249+
public func optionalChained(expr: ExpressibleAsExprBuildable) -> ExpressibleAsExprBuildable {
250250
if isOptional {
251251
return OptionalChainingExpr(expression: expr)
252252
} else {
@@ -255,7 +255,7 @@ struct SyntaxBuildableType: Hashable {
255255
}
256256

257257
/// Wraps a type in a force unwrap expression depending on whether `isOptional` is true.
258-
func forceUnwrappedIfNeeded(expr: ExpressibleAsExprBuildable) -> ExpressibleAsExprBuildable {
258+
public func forceUnwrappedIfNeeded(expr: ExpressibleAsExprBuildable) -> ExpressibleAsExprBuildable {
259259
if isOptional {
260260
return ForcedValueExpr(expression: expr)
261261
} else {
@@ -265,7 +265,7 @@ struct SyntaxBuildableType: Hashable {
265265

266266
/// Generate an expression that converts a variable named `varName`
267267
/// which is of `expressibleAs` type to an object of type `buildable`.
268-
func generateExprConvertParamTypeToStorageType(varName: String) -> ExpressibleAsExprBuildable {
268+
public func generateExprConvertParamTypeToStorageType(varName: String) -> ExpressibleAsExprBuildable {
269269
if isToken {
270270
return varName
271271
} else {

Code-Generation/Sources/generate-swiftsyntaxbuilder/Utils.swift renamed to Code-Generation/Sources/Utils/Utils.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@
1313
import Foundation
1414

1515
/// Trims leading and trailing whitespace from each line.
16-
func dedented<Lines: Sequence>(lines: Lines) -> [String] where Lines.Element: StringProtocol {
16+
public func dedented<Lines: Sequence>(lines: Lines) -> [String] where Lines.Element: StringProtocol {
1717
lines.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
1818
}
1919

2020
/// Trims leading and trailing whitespace from each line.
21-
func dedented(string: String) -> String {
21+
public func dedented(string: String) -> String {
2222
dedented(lines: string.split(separator: "\n"))
2323
.joined(separator: "\n")
2424
}
2525

2626
/// Creates a single-line documentation string from indented
2727
/// documentation as written in `gyb_syntax_support`.
28-
func flattened(indentedDocumentation: String) -> String {
28+
public func flattened(indentedDocumentation: String) -> String {
2929
dedented(string: indentedDocumentation)
3030
.replacingOccurrences(of: "\n", with: "")
3131
.trimmingCharacters(in: .whitespacesAndNewlines)

Code-Generation/Sources/generate-swiftsyntaxbuilder/FormatFile.swift renamed to Code-Generation/Sources/generate-swiftbasicformat/FormatFile.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import Foundation
1414
import SwiftSyntax
1515
import SwiftSyntaxBuilder
16+
import SyntaxSupport
17+
import Utils
1618

1719
let formatFile = SourceFile {
1820
ImportDecl(
@@ -136,6 +138,7 @@ private func createFormatFunctionSignature(type: SyntaxBuildableType) -> Functio
136138
/// Generate the format implementation for a buildable node.
137139
private func createBuildableNodeFormatFunction(node: Node) -> FunctionDecl {
138140
FunctionDecl(
141+
modifiers: Token.public,
139142
identifier: .identifier("format"),
140143
signature: createFormatFunctionSignature(type: node.type)
141144
) {
@@ -191,6 +194,7 @@ private func createBuildableNodeFormatFunction(node: Node) -> FunctionDecl {
191194
/// The implementation updates the leading trivia of the elements with their indentation.
192195
private func createBuildableCollectionNodeFormatFunction(node: Node) -> FunctionDecl {
193196
FunctionDecl(
197+
modifiers: Token.public,
194198
identifier: .identifier("format"),
195199
signature: createFormatFunctionSignature(type: node.type)
196200
) {
@@ -229,6 +233,7 @@ private func createBuildableCollectionNodeFormatFunction(node: Node) -> Function
229233
private func createTokenFormatFunction() -> FunctionDecl {
230234
let tokenType = SyntaxBuildableType(syntaxKind: "Token")
231235
return FunctionDecl(
236+
modifiers: Token.public,
232237
identifier: .identifier("format"),
233238
signature: createFormatFunctionSignature(type: tokenType)
234239
) {

0 commit comments

Comments
 (0)