Skip to content

Commit b5b764c

Browse files
rintarobeccadax
authored andcommitted
[Parser] Always enable abiAttribute feature
`ABIAttributeArgumentsSyntax` is still under `@_spi(ExperimentalLanguageFeatures)`. Not parsing the interior of `@abi` attribute causes catastrophic breakage to the tree. Having "unknown" syntax kind in the tree is better than dealing with structually broken trees.
1 parent f51c6cb commit b5b764c

File tree

5 files changed

+57
-55
lines changed

5 files changed

+57
-55
lines changed

CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift

+11
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ public enum ExperimentalFeature: String, CaseIterable {
8181
}
8282
}
8383

84+
public var isAlwaysEnabledInParser: Bool {
85+
switch self {
86+
case .abiAttribute:
87+
// `@abi` attributes should be always parsed because not parsing its interior
88+
// breaks the tree catastrophically.
89+
return true
90+
default:
91+
return false
92+
}
93+
}
94+
8495
/// The token that represents the experimental feature case name.
8596
public var token: TokenSyntax {
8697
.identifier(rawValue)

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

+13
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ let experimentalFeaturesFile = SourceFileSyntax(leadingTrivia: copyrightHeader)
4040
)
4141
}
4242

43+
try! VariableDeclSyntax(
44+
"""
45+
/// Set of features always enabled.
46+
static var alwaysEnabledFeatures: Self
47+
"""
48+
) {
49+
ArrayExprSyntax {
50+
for feature in ExperimentalFeature.allCases where feature.isAlwaysEnabledInParser {
51+
ArrayElementSyntax(expression: ExprSyntax(".\(feature.token)"))
52+
}
53+
}
54+
}
55+
4356
try! InitializerDeclSyntax(
4457
"""
4558
/// Creates a new value representing the experimental feature with the

Sources/SwiftParser/Parser.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ public struct Parser {
237237

238238
self.maximumNestingLevel = maximumNestingLevel ?? Self.defaultMaximumNestingLevel
239239
self.swiftVersion = swiftVersion ?? Self.defaultSwiftVersion
240-
self.experimentalFeatures = experimentalFeatures
240+
self.experimentalFeatures = experimentalFeatures.union(.alwaysEnabledFeatures)
241241
self.lookaheadTrackerOwner = LookaheadTrackerOwner()
242242

243243
self.lexemes = Lexer.tokenize(input, lookaheadTracker: lookaheadTrackerOwner.lookaheadTracker)

Sources/SwiftParser/generated/ExperimentalFeatures.swift

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tests/SwiftParserTest/AttributeTests.swift

+27-54
Original file line numberDiff line numberDiff line change
@@ -960,74 +960,64 @@ final class AttributeTests: ParserTestCase {
960960
parameterClause: FunctionParameterClauseSyntax {},
961961
returnClause: ReturnClauseSyntax(type: TypeSyntax("Int"))
962962
)
963-
) {},
964-
experimentalFeatures: [.abiAttribute]
963+
) {}
965964
)
966965

967966
assertParse(
968967
"""
969968
@abi(associatedtype AssocTy)
970969
associatedtype AssocTy
971-
""",
972-
experimentalFeatures: [.abiAttribute]
970+
"""
973971
)
974972
assertParse(
975973
"""
976974
@abi(deinit)
977975
deinit {}
978-
""",
979-
experimentalFeatures: [.abiAttribute]
976+
"""
980977
)
981978
assertParse(
982979
"""
983980
enum EnumCaseDeclNotParsedAtTopLevel {
984981
@abi(case someCase)
985982
case someCase
986983
}
987-
""",
988-
experimentalFeatures: [.abiAttribute]
984+
"""
989985
)
990986
assertParse(
991987
"""
992988
@abi(func fn())
993989
func fn()
994-
""",
995-
experimentalFeatures: [.abiAttribute]
990+
"""
996991
)
997992
assertParse(
998993
"""
999994
@abi(init())
1000995
init() {}
1001-
""",
1002-
experimentalFeatures: [.abiAttribute]
996+
"""
1003997
)
1004998
assertParse(
1005999
"""
10061000
@abi(subscript(i: Int) -> Element)
10071001
subscript(i: Int) -> Element {}
1008-
""",
1009-
experimentalFeatures: [.abiAttribute]
1002+
"""
10101003
)
10111004
assertParse(
10121005
"""
10131006
@abi(typealias Typealias = @escaping () -> Void)
10141007
typealias Typealias = () -> Void
1015-
""",
1016-
experimentalFeatures: [.abiAttribute]
1008+
"""
10171009
)
10181010
assertParse(
10191011
"""
10201012
@abi(let c1, c2)
10211013
let c1, c2
1022-
""",
1023-
experimentalFeatures: [.abiAttribute]
1014+
"""
10241015
)
10251016
assertParse(
10261017
"""
10271018
@abi(var v1, v2)
10281019
var v1, v2
1029-
""",
1030-
experimentalFeatures: [.abiAttribute]
1020+
"""
10311021
)
10321022

10331023
assertParse(
@@ -1042,8 +1032,7 @@ final class AttributeTests: ParserTestCase {
10421032
),
10431033
diagnostics: [
10441034
DiagnosticSpec(locationMarker: "1️⃣", message: "editor placeholder in source file")
1045-
],
1046-
experimentalFeatures: [.abiAttribute]
1035+
]
10471036
)
10481037

10491038
assertParse(
@@ -1067,8 +1056,7 @@ final class AttributeTests: ParserTestCase {
10671056
),
10681057
diagnostics: [
10691058
DiagnosticSpec(locationMarker: "1️⃣", message: "import is not permitted as ABI-providing declaration")
1070-
],
1071-
experimentalFeatures: [.abiAttribute]
1059+
]
10721060
)
10731061

10741062
//
@@ -1079,66 +1067,57 @@ final class AttributeTests: ParserTestCase {
10791067
"""
10801068
@abi(associatedtype AssocTy = T)
10811069
associatedtype AssocTy
1082-
""",
1083-
experimentalFeatures: [.abiAttribute]
1070+
"""
10841071
)
10851072
assertParse(
10861073
"""
10871074
@abi(deinit {})
10881075
deinit {}
1089-
""",
1090-
experimentalFeatures: [.abiAttribute]
1076+
"""
10911077
)
10921078
assertParse(
10931079
"""
10941080
enum EnumCaseDeclNotParsedAtTopLevel {
10951081
@abi(case someCase = 42)
10961082
case someCase
10971083
}
1098-
""",
1099-
experimentalFeatures: [.abiAttribute]
1084+
"""
11001085
)
11011086
assertParse(
11021087
"""
11031088
@abi(func fn() {})
11041089
func fn()
1105-
""",
1106-
experimentalFeatures: [.abiAttribute]
1090+
"""
11071091
)
11081092
assertParse(
11091093
"""
11101094
@abi(init() {})
11111095
init() {}
1112-
""",
1113-
experimentalFeatures: [.abiAttribute]
1096+
"""
11141097
)
11151098
assertParse(
11161099
"""
11171100
@abi(subscript(i: Int) -> Element { get {} set {} })
11181101
subscript(i: Int) -> Element {}
1119-
""",
1120-
experimentalFeatures: [.abiAttribute]
1102+
"""
11211103
)
11221104
assertParse(
11231105
"""
11241106
@abi(let c1 = 1, c2 = 2)
11251107
let c1, c2
1126-
""",
1127-
experimentalFeatures: [.abiAttribute]
1108+
"""
11281109
)
11291110
assertParse(
11301111
"""
11311112
@abi(var v1 = 1, v2 = 2)
11321113
var v1, v2
1133-
""",
1134-
experimentalFeatures: [.abiAttribute]
1114+
"""
11351115
)
11361116
assertParse(
11371117
"""
11381118
@abi(var v3 { get {} set {} })
11391119
var v3
1140-
""",
1141-
experimentalFeatures: [.abiAttribute]
1120+
"""
11421121
)
11431122

11441123
//
@@ -1160,8 +1139,7 @@ final class AttributeTests: ParserTestCase {
11601139
fixedSource: """
11611140
@abi(var <#pattern#>)
11621141
var v1
1163-
""",
1164-
experimentalFeatures: [.abiAttribute]
1142+
"""
11651143
)
11661144
assertParse(
11671145
"""
@@ -1184,8 +1162,7 @@ final class AttributeTests: ParserTestCase {
11841162
fixedSource: """
11851163
@abi(var v2)
11861164
var v2
1187-
""",
1188-
experimentalFeatures: [.abiAttribute]
1165+
"""
11891166
)
11901167
assertParse(
11911168
"""
@@ -1203,8 +1180,7 @@ final class AttributeTests: ParserTestCase {
12031180
fixedSource: """
12041181
@abi(<#declaration#>)
12051182
func fn2() {}
1206-
""",
1207-
experimentalFeatures: [.abiAttribute]
1183+
"""
12081184
)
12091185
assertParse(
12101186
"""
@@ -1221,8 +1197,7 @@ final class AttributeTests: ParserTestCase {
12211197
fixedSource: """
12221198
@abi(<#declaration#>)
12231199
func fn3() {}
1224-
""",
1225-
experimentalFeatures: [.abiAttribute]
1200+
"""
12261201
)
12271202
assertParse(
12281203
"""
@@ -1244,8 +1219,7 @@ final class AttributeTests: ParserTestCase {
12441219
fixedSource: """
12451220
@abi(<#declaration#>) func fn4_abi())
12461221
func fn4() {}
1247-
""",
1248-
experimentalFeatures: [.abiAttribute]
1222+
"""
12491223
)
12501224

12511225
// `#if` is banned inside an `@abi` attribute.
@@ -1278,8 +1252,7 @@ final class AttributeTests: ParserTestCase {
12781252
func _fn<E: Error>() throws(E)
12791253
)
12801254
func fn<E: Error>() throws(E) {}
1281-
""",
1282-
experimentalFeatures: [.abiAttribute]
1255+
"""
12831256
)
12841257
}
12851258

0 commit comments

Comments
 (0)