Skip to content

Commit 79a4162

Browse files
committed
SwiftCompilerSources: reintroduce DiagnosticEngine
1 parent 2a8f846 commit 79a4162

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/PassManager/Context.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ protocol Context {
2121
extension Context {
2222
var options: Options { Options(_bridged: _bridged) }
2323

24+
var diagnosticEngine: DiagnosticEngine {
25+
return DiagnosticEngine(bridged: _bridged.getDiagnosticEngine())
26+
}
27+
2428
// The calleeAnalysis is not specific to a function and therefore can be provided in
2529
// all contexts.
2630
var calleeAnalysis: CalleeAnalysis {

SwiftCompilerSources/Sources/Optimizer/Utilities/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

99
swift_compiler_sources(Optimizer
10+
DiagnosticEngine.swift
1011
EscapeUtils.swift
1112
OptUtils.swift
1213
ForwardingUtils.swift
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
//===--- DiagnosticEngine.swift -------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2022 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 ASTBridging
14+
15+
import Basic
16+
17+
public typealias DiagID = BridgedDiagID
18+
19+
public protocol DiagnosticArgument {
20+
func _withBridgedDiagnosticArgument(_ fn: (BridgedDiagnosticArgument) -> Void)
21+
}
22+
extension String: DiagnosticArgument {
23+
public func _withBridgedDiagnosticArgument(_ fn: (BridgedDiagnosticArgument) -> Void) {
24+
_withBridgedStringRef { fn(BridgedDiagnosticArgument($0)) }
25+
}
26+
}
27+
extension Int: DiagnosticArgument {
28+
public func _withBridgedDiagnosticArgument(_ fn: (BridgedDiagnosticArgument) -> Void) {
29+
fn(BridgedDiagnosticArgument(self))
30+
}
31+
}
32+
33+
public struct DiagnosticFixIt {
34+
public let start: SourceLoc
35+
public let byteLength: Int
36+
public let text: String
37+
38+
public init(start: SourceLoc, byteLength: Int, replacement text: String) {
39+
self.start = start
40+
self.byteLength = byteLength
41+
self.text = text
42+
}
43+
44+
func withBridgedDiagnosticFixIt(_ fn: (BridgedDiagnosticFixIt) -> Void) {
45+
text._withBridgedStringRef { bridgedTextRef in
46+
let bridgedDiagnosticFixIt = BridgedDiagnosticFixIt(
47+
start.bridged, UInt32(byteLength),
48+
bridgedTextRef)
49+
fn(bridgedDiagnosticFixIt)
50+
}
51+
}
52+
}
53+
54+
public struct DiagnosticEngine {
55+
private let bridged: BridgedDiagnosticEngine
56+
57+
public init(bridged: BridgedDiagnosticEngine) {
58+
self.bridged = bridged
59+
}
60+
public init?(bridged: BridgedNullableDiagnosticEngine) {
61+
guard let raw = bridged.raw else {
62+
return nil
63+
}
64+
self.bridged = BridgedDiagnosticEngine(raw: raw)
65+
}
66+
67+
public func diagnose(_ position: SourceLoc?,
68+
_ id: DiagID,
69+
_ args: [DiagnosticArgument],
70+
highlight: CharSourceRange? = nil,
71+
fixIts: [DiagnosticFixIt] = []) {
72+
73+
let bridgedSourceLoc: BridgedSourceLoc = position.bridged
74+
let highlightStart: BridgedSourceLoc
75+
let highlightLength: UInt32
76+
if let highlight = highlight {
77+
highlightStart = highlight.start.bridged
78+
highlightLength = highlight.byteLength
79+
} else {
80+
highlightStart = BridgedSourceLoc()
81+
highlightLength = 0
82+
}
83+
var bridgedArgs: [BridgedDiagnosticArgument] = []
84+
var bridgedFixIts: [BridgedDiagnosticFixIt] = []
85+
86+
// Build a higher-order function to wrap every 'withBridgedXXX { ... }'
87+
// calls, so we don't escape anything from the closure. 'bridgedArgs' and
88+
// 'bridgedFixIts' are temporary storage to store bridged values. So they
89+
// should not be used after the closure is executed.
90+
91+
var closure: () -> Void = {
92+
bridgedArgs.withBridgedArrayRef { bridgedArgsRef in
93+
bridgedFixIts.withBridgedArrayRef { bridgedFixItsRef in
94+
bridged.diagnose(at: bridgedSourceLoc, id, bridgedArgsRef,
95+
highlightAt: highlightStart,
96+
highlightLength: highlightLength,
97+
fixIts: bridgedFixItsRef)
98+
}
99+
}
100+
}
101+
// 'reversed()' because the closure should be wrapped in that order.
102+
for arg in args.reversed() {
103+
closure = { [closure, arg] in
104+
arg._withBridgedDiagnosticArgument { bridgedArg in
105+
bridgedArgs.append(bridgedArg)
106+
closure()
107+
}
108+
}
109+
}
110+
// 'reversed()' because the closure should be wrapped in that order.
111+
for fixIt in fixIts.reversed() {
112+
closure = { [closure, fixIt] in
113+
fixIt.withBridgedDiagnosticFixIt { bridgedFixIt in
114+
bridgedFixIts.append(bridgedFixIt)
115+
closure()
116+
}
117+
}
118+
}
119+
120+
closure()
121+
}
122+
123+
public func diagnose(_ position: SourceLoc?,
124+
_ id: DiagID,
125+
_ args: DiagnosticArgument...,
126+
highlight: CharSourceRange? = nil,
127+
fixIts: DiagnosticFixIt...) {
128+
diagnose(position, id, args, highlight: highlight, fixIts: fixIts)
129+
}
130+
}

0 commit comments

Comments
 (0)