Skip to content

Commit d0a8c51

Browse files
Fixed up two issues that were discovered (#12)
* Fixed up two issues that were discovered 1. When a diagnostic has multiple fix its the annotated string didn't insert newlines between fix-its 2. When a syntax has the same node offset as one of its children, replacing the child with a fix-it would *always* replace the outermost node * Fixed up formatting * Updates per code review suggestions * Additional updates per code review suggestions
1 parent 35acd94 commit d0a8c51

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

Sources/MacroTesting/SwiftDiagnostics/DiagnosticsFormatter.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,12 @@ struct DiagnosticsFormatter {
324324
for diag in diags.dropLast(1) {
325325
annotatedSource.append("\(preMessage)├─ \(colorizeIfRequested(diag.diagMessage))\n")
326326
for fixIt in diag.fixIts {
327-
annotatedSource.append("\(preMessage)│ ✏️ \(fixIt.message.message)")
327+
annotatedSource.append("\(preMessage)│ ✏️ \(fixIt.message.message)\n")
328328
}
329329
}
330330
annotatedSource.append("\(preMessage)╰─ \(colorizeIfRequested(diags.last!.diagMessage))\n")
331331
for fixIt in diags.last!.fixIts {
332-
annotatedSource.append("\(preMessage) ✏️ \(fixIt.message.message)")
332+
annotatedSource.append("\(preMessage) ✏️ \(fixIt.message.message)\n")
333333
}
334334
}
335335

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import MacroTesting
2+
import XCTest
3+
4+
final class DiagnosticsAndFixitsEmitterMacroTests: BaseTestCase {
5+
override func invokeTest() {
6+
withMacroTesting(macros: [DiagnosticsAndFixitsEmitterMacro.self]) {
7+
super.invokeTest()
8+
}
9+
}
10+
11+
func testExpansionEmitsDiagnosticsAndFixits() {
12+
assertMacro {
13+
"""
14+
@DiagnosticsAndFixitsEmitter
15+
struct FooBar {
16+
let foo: Foo
17+
let bar: Bar
18+
}
19+
"""
20+
} diagnostics: {
21+
"""
22+
@DiagnosticsAndFixitsEmitter
23+
┬──────────────────────────
24+
├─ ⚠️ This is the first diagnostic.
25+
│ ✏️ This is the first fix-it.
26+
│ ✏️ This is the second fix-it.
27+
╰─ ℹ️ This is the second diagnostic, it's a note.
28+
struct FooBar {
29+
let foo: Foo
30+
let bar: Bar
31+
}
32+
"""
33+
} expansion: {
34+
"""
35+
struct FooBar {
36+
let foo: Foo
37+
let bar: Bar
38+
}
39+
"""
40+
}
41+
}
42+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
import SwiftSyntaxBuilder
15+
import SwiftSyntaxMacros
16+
import SwiftDiagnostics
17+
18+
/// Emits two diagnostics, the first of which is a warning and has two fix-its, and
19+
/// the second is a note and has no fix-its.
20+
public enum DiagnosticsAndFixitsEmitterMacro: MemberMacro {
21+
public static func expansion(
22+
of node: AttributeSyntax,
23+
providingMembersOf declaration: some DeclGroupSyntax,
24+
in context: some MacroExpansionContext
25+
) throws -> [DeclSyntax] {
26+
let firstFixIt = FixIt(message: SimpleDiagnosticMessage(message: "This is the first fix-it.",
27+
diagnosticID: MessageID(domain: "domain", id: "fixit1"),
28+
severity: .error),
29+
changes: [
30+
.replace(oldNode: Syntax(node), newNode: Syntax(node)) // no-op
31+
])
32+
let secondFixIt = FixIt(message: SimpleDiagnosticMessage(message: "This is the second fix-it.",
33+
diagnosticID: MessageID(domain: "domain", id: "fixit2"),
34+
severity: .error),
35+
changes: [
36+
.replace(oldNode: Syntax(node), newNode: Syntax(node)) // no-op
37+
])
38+
39+
context.diagnose(Diagnostic(node: node.attributeName,
40+
message: SimpleDiagnosticMessage(message: "This is the first diagnostic.",
41+
diagnosticID: MessageID(domain: "domain", id: "diagnostic2"),
42+
severity: .warning),
43+
fixIts: [firstFixIt, secondFixIt]))
44+
context.diagnose(Diagnostic(node: node.attributeName,
45+
message: SimpleDiagnosticMessage(message: "This is the second diagnostic, it's a note.",
46+
diagnosticID: MessageID(domain: "domain", id: "diagnostic2"),
47+
severity: .note)))
48+
49+
return []
50+
}
51+
}

0 commit comments

Comments
 (0)