Skip to content

Commit 2bc3ee5

Browse files
committed
Apply this policy more broadly to all backtick-enclosed identifiers
1 parent 531f993 commit 2bc3ee5

File tree

5 files changed

+51
-23
lines changed

5 files changed

+51
-23
lines changed

Sources/TestingMacros/Support/Additions/FunctionDeclSyntaxAdditions.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import SwiftSyntax
1212
import SwiftSyntaxBuilder
1313
import SwiftSyntaxMacros
14-
import SwiftParser
1514

1615
extension FunctionDeclSyntax {
1716
/// Whether or not this function a `static` or `class` function.
@@ -39,7 +38,7 @@ extension FunctionDeclSyntax {
3938
/// colons.
4039
var completeName: DeclReferenceExprSyntax {
4140
func possiblyRaw(_ token: TokenSyntax) -> TokenSyntax {
42-
if let rawIdentifier = token.rawIdentifier, !rawIdentifier.isValidSwiftIdentifier(for: .memberAccess) {
41+
if let rawIdentifier = token.rawIdentifier {
4342
return .identifier("`\(rawIdentifier)`")
4443
}
4544
return .identifier(token.textWithoutBackticks)

Sources/TestingMacros/Support/Additions/TokenSyntaxAdditions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ extension TokenSyntax {
3535
/// token, or `nil` if it does not represent one.
3636
var rawIdentifier: String? {
3737
let (textWithoutBackticks, backticksRemoved) = _textWithoutBackticks
38-
if backticksRemoved {
38+
if backticksRemoved, !textWithoutBackticks.isValidSwiftIdentifier(for: .memberAccess) {
3939
return textWithoutBackticks
4040
}
4141

Sources/TestingMacros/Support/AttributeDiscovery.swift

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import SwiftSyntax
1212
import SwiftSyntaxBuilder
1313
import SwiftSyntaxMacros
14-
import SwiftParser
1514

1615
/// A syntax rewriter that removes leading `Self.` tokens from member access
1716
/// expressions in a syntax tree.
@@ -139,20 +138,17 @@ struct AttributeInfo {
139138
}
140139
}
141140

142-
// If this declaration has a raw identifier name, implicitly use the content
143-
// of that raw identifier as its display name.
141+
// If this declaration's name is surrounded by backticks, it may be an
142+
// escaped or raw identifier. If it has an explicitly-specified display name
143+
// string, honor that, otherwise use the content of the backtick-enclosed
144+
// name as the display name.
144145
if let namedDecl = declaration.asProtocol((any NamedDeclSyntax).self),
145-
let rawIdentifier = namedDecl.name.rawIdentifier {
146-
// Disallow having an explicit display name for tests and suites with raw
147-
// identifier names as it's redundant and potentially confusing. An
148-
// exception to this rule is if the content of the raw identifier is not a
149-
// valid identifier on its own. For example:
150-
//
151-
// @Test("...") func `subscript`() { ... }
152-
if let displayName, let displayNameArgument, !rawIdentifier.isValidSwiftIdentifier(for: .memberAccess) {
146+
case let nameWithoutBackticks = namedDecl.name.textWithoutBackticks,
147+
nameWithoutBackticks != namedDecl.name.text {
148+
if let displayName, let displayNameArgument {
153149
context.diagnose(.declaration(namedDecl, hasExtraneousDisplayName: displayName, fromArgument: displayNameArgument, using: attribute))
154150
} else {
155-
displayName = StringLiteralExprSyntax(content: rawIdentifier)
151+
displayName = StringLiteralExprSyntax(content: nameWithoutBackticks)
156152
}
157153
}
158154

Tests/TestingMacrosTests/TestDeclarationMacroTests.swift

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,14 +263,48 @@ struct TestDeclarationMacroTests {
263263
}
264264
}
265265

266-
@Test("No diagnostics are emitted for tests with both a raw identifier name and explicit display name when deemed non-redundant", arguments: [
267-
#"@Test("Class") func `class`()"#,
268-
#"@Test("Struct") func `struct`()"#,
269-
#"@Test("Subscript") func `subscript`()"#,
266+
@Test("Warning diagnostics which include fix-its emitted on API misuse", arguments: [
267+
#"@Test("Subscript") func `subscript`()"#:
268+
(
269+
message: "Attribute 'Test' specifies display name 'Subscript' for function with implicit display name 'subscript'",
270+
fixIts: [
271+
ExpectedFixIt(
272+
message: "Remove 'Subscript'",
273+
changes: [.replace(oldSourceCode: #""Subscript""#, newSourceCode: "")]
274+
),
275+
ExpectedFixIt(
276+
message: "Rename 'subscript'",
277+
changes: [.replace(oldSourceCode: "`subscript`", newSourceCode: "\(EditorPlaceholderExprSyntax("name"))")]
278+
),
279+
]
280+
),
270281
])
271-
func nonRedundantRawIdentifierDisplayName(input: String) throws {
282+
func apiMisuseWarningsIncludingFixIts(input: String, expectedDiagnostic: (message: String, fixIts: [ExpectedFixIt])) throws {
272283
let (_, diagnostics) = try parse(input)
273-
#expect(diagnostics.isEmpty)
284+
285+
#expect(diagnostics.count == 1)
286+
let diagnostic = try #require(diagnostics.first)
287+
#expect(diagnostic.diagMessage.severity == .warning)
288+
#expect(diagnostic.message == expectedDiagnostic.message)
289+
290+
try #require(diagnostic.fixIts.count == expectedDiagnostic.fixIts.count)
291+
for (fixIt, expectedFixIt) in zip(diagnostic.fixIts, expectedDiagnostic.fixIts) {
292+
#expect(fixIt.message.message == expectedFixIt.message)
293+
294+
try #require(fixIt.changes.count == expectedFixIt.changes.count)
295+
for (change, expectedChange) in zip(fixIt.changes, expectedFixIt.changes) {
296+
switch (change, expectedChange) {
297+
case let (.replace(oldNode, newNode), .replace(expectedOldSourceCode, expectedNewSourceCode)):
298+
let oldSourceCode = String(describing: oldNode.formatted())
299+
#expect(oldSourceCode == expectedOldSourceCode)
300+
301+
let newSourceCode = String(describing: newNode.formatted())
302+
#expect(newSourceCode == expectedNewSourceCode)
303+
default:
304+
Issue.record("Change \(change) differs from expected change \(expectedChange)")
305+
}
306+
}
307+
}
274308
}
275309

276310
@Test("Raw identifier is detected")

Tests/TestingTests/Support/GraphTests.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ struct GraphTests {
5353
#expect(graph.subgraph(at: "C2", "C3")?.value == 2468)
5454
}
5555

56-
@Test("subscript([K]) operator")
57-
func `subscript`() {
56+
@Test func `subscript([K]) operator`() {
5857
let graph = Graph<String, Int>(value: 123, children: [
5958
"C1": Graph(value: 456),
6059
"C2": Graph(value: 789, children: [

0 commit comments

Comments
 (0)