Skip to content

Commit a80f17d

Browse files
authored
[Traits] Only allow valid Swift identifiers (#8178)
# Motivation During the proposal review it was brought up that the rules around trait names wasn't inline with Swift identifiers. Neither was the implementation which was inline with the proposal. # Modification This PR changes our validation logic to only allow valid Swift identifiers. # Result Only allows trait names that can be used as Swift identifiers.
1 parent e8e0850 commit a80f17d

File tree

2 files changed

+6
-21
lines changed

2 files changed

+6
-21
lines changed

Sources/PackageLoading/ManifestLoader+Validation.swift

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,9 @@ public struct ManifestValidator {
107107
continue
108108
}
109109

110-
for (index, unicodeScalar) in traitName.unicodeScalars.enumerated() {
111-
let properties = unicodeScalar.properties
112-
113-
if index == 0 {
114-
if !(properties.isIDStart || properties.isASCIIHexDigit || unicodeScalar == "_") {
115-
diagnostics.append(.invalidFirstCharacterInTrait(firstCharater: unicodeScalar, trait: trait.name))
116-
}
117-
} else {
118-
if !(properties.isXIDContinue || unicodeScalar == "_" || unicodeScalar == "+") {
119-
diagnostics.append(.invalidCharacterInTrait(character: unicodeScalar, trait: trait.name))
120-
}
121-
}
110+
guard traitName.isValidIdentifier else {
111+
diagnostics.append(.invalidTraitName(trait: traitName))
112+
continue
122113
}
123114
}
124115

@@ -365,12 +356,8 @@ extension Basics.Diagnostic {
365356
.error("Empty strings are not allowed as trait names")
366357
}
367358

368-
static func invalidFirstCharacterInTrait(firstCharater: UnicodeScalar, trait: String) -> Self {
369-
.error("Invalid first character (\(firstCharater)) in trait \(trait). The first character must be a Unicode XID start character (most letters), a digit, or _.")
370-
}
371-
372-
static func invalidCharacterInTrait(character: UnicodeScalar, trait: String) -> Self {
373-
.error("Invalid character \(character) in trait \(trait). Characters must be a Unicode XID continue character (a digit, _, or most letters), -, or +")
359+
static func invalidTraitName(trait: String) -> Self {
360+
.error("Invalid trait name \(trait). Trait names must be valid Swift identifiers")
374361
}
375362

376363
static func invalidEnabledTrait(trait: String, enabledBy enablerTrait: String) -> Self {

Tests/PackageLoadingTests/TraitLoadingTests.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ final class TraitLoadingTests: PackageDescriptionLoadingTests {
9595
".",
9696
"?",
9797
",",
98-
"ⒶⒷⒸ",
9998
]
10099

101100
for traitName in invalidTraitNames {
@@ -114,7 +113,7 @@ final class TraitLoadingTests: PackageDescriptionLoadingTests {
114113
XCTAssertNoDiagnostics(observability.diagnostics)
115114
let firstDiagnostic = try XCTUnwrap(validationDiagnostics.first)
116115
XCTAssertEqual(firstDiagnostic.severity, .error)
117-
XCTAssertEqual(firstDiagnostic.message, "Invalid first character (\(traitName.first!)) in trait \(traitName). The first character must be a Unicode XID start character (most letters), a digit, or _.")
116+
XCTAssertEqual(firstDiagnostic.message, "Invalid trait name \(traitName). Trait names must be valid Swift identifiers")
118117
}
119118
}
120119

@@ -129,7 +128,6 @@ final class TraitLoadingTests: PackageDescriptionLoadingTests {
129128
"foo,",
130129
"foo:bar",
131130
"foo?",
132-
"",
133131
]
134132

135133
for traitName in invalidTraitNames {

0 commit comments

Comments
 (0)