Skip to content

Commit 461cfcc

Browse files
committed
Add a string-based initializer for ExperimentalFeatures.
Tools (like swift-format) can use this to let users enable experimental features in the parser via interfaces like the command line, without having to handle the translation from string to option set themselves.
1 parent 38459d4 commit 461cfcc

File tree

3 files changed

+74
-10
lines changed

3 files changed

+74
-10
lines changed

CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift

+25-5
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,28 @@ public enum ExperimentalFeature: String, CaseIterable {
2121
case coroutineAccessors
2222
case valueGenerics
2323

24-
/// The name of the feature, which is used in the doc comment.
24+
/// The name of the feature as it is written in the compiler's `Features.def` file.
2525
public var featureName: String {
26+
switch self {
27+
case .referenceBindings:
28+
return "ReferenceBindings"
29+
case .thenStatements:
30+
return "ThenStatements"
31+
case .doExpressions:
32+
return "DoExpressions"
33+
case .nonescapableTypes:
34+
return "NonescapableTypes"
35+
case .trailingComma:
36+
return "TrailingComma"
37+
case .coroutineAccessors:
38+
return "CoroutineAccessors"
39+
case .valueGenerics:
40+
return "ValueGenerics"
41+
}
42+
}
43+
44+
/// A brief description of the feature that is used in the doc comment.
45+
public var documentationDescription: String {
2646
switch self {
2747
case .referenceBindings:
2848
return "reference bindings"
@@ -31,13 +51,13 @@ public enum ExperimentalFeature: String, CaseIterable {
3151
case .doExpressions:
3252
return "'do' expressions"
3353
case .nonescapableTypes:
34-
return "NonEscableTypes"
54+
return "non-escapable types"
3555
case .trailingComma:
36-
return "trailing comma"
56+
return "trailing commas"
3757
case .coroutineAccessors:
38-
return "CoroutineAccessors"
58+
return "coroutine accessors"
3959
case .valueGenerics:
40-
return "ValueGenerics"
60+
return "value generics"
4161
}
4262
}
4363

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/ExperimentalFeaturesFile.swift

+22-1
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,31 @@ let experimentalFeaturesFile = SourceFileSyntax(leadingTrivia: copyrightHeader)
3434
for (i, feature) in ExperimentalFeature.allCases.enumerated() {
3535
DeclSyntax(
3636
"""
37-
/// Whether to enable the parsing of \(raw: feature.featureName).
37+
/// Whether to enable the parsing of \(raw: feature.documentationDescription).
3838
public static let \(feature.token) = Self(rawValue: 1 << \(raw: i))
3939
"""
4040
)
4141
}
42+
43+
try! InitializerDeclSyntax(
44+
"""
45+
/// Creates a new value representing the experimental feature with the
46+
/// given name, or returns nil if the name is not recognized.
47+
public init?(name: String)
48+
"""
49+
) {
50+
try! SwitchExprSyntax("switch name") {
51+
SwitchCaseListSyntax {
52+
for feature in ExperimentalFeature.allCases {
53+
SwitchCaseSyntax(#"case "\#(raw: feature.featureName)":"#) {
54+
ExprSyntax("self = .\(feature.token)")
55+
}
56+
}
57+
SwitchCaseSyntax("default:") {
58+
StmtSyntax("return nil")
59+
}
60+
}
61+
}
62+
}
4263
}
4364
}

Sources/SwiftParser/generated/ExperimentalFeatures.swift

+27-4
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,38 @@ extension Parser.ExperimentalFeatures {
3333
/// Whether to enable the parsing of 'do' expressions.
3434
public static let doExpressions = Self (rawValue: 1 << 2)
3535

36-
/// Whether to enable the parsing of NonEscableTypes.
36+
/// Whether to enable the parsing of non-escapable types.
3737
public static let nonescapableTypes = Self (rawValue: 1 << 3)
3838

39-
/// Whether to enable the parsing of trailing comma.
39+
/// Whether to enable the parsing of trailing commas.
4040
public static let trailingComma = Self (rawValue: 1 << 4)
4141

42-
/// Whether to enable the parsing of CoroutineAccessors.
42+
/// Whether to enable the parsing of coroutine accessors.
4343
public static let coroutineAccessors = Self (rawValue: 1 << 5)
4444

45-
/// Whether to enable the parsing of ValueGenerics.
45+
/// Whether to enable the parsing of value generics.
4646
public static let valueGenerics = Self (rawValue: 1 << 6)
47+
48+
/// Creates a new value representing the experimental feature with the
49+
/// given name, or returns nil if the name is not recognized.
50+
public init?(name: String) {
51+
switch name {
52+
case "ReferenceBindings":
53+
self = .referenceBindings
54+
case "ThenStatements":
55+
self = .thenStatements
56+
case "DoExpressions":
57+
self = .doExpressions
58+
case "NonescapableTypes":
59+
self = .nonescapableTypes
60+
case "TrailingComma":
61+
self = .trailingComma
62+
case "CoroutineAccessors":
63+
self = .coroutineAccessors
64+
case "ValueGenerics":
65+
self = .valueGenerics
66+
default:
67+
return nil
68+
}
69+
}
4770
}

0 commit comments

Comments
 (0)