Skip to content

Commit 05d5e0c

Browse files
committed
[SwiftCompiler] Add DiagnosticEngine bridging
* 'SourceLoc' and 'CharSourceRange' bridging in Basic * New 'AST' bridging. 'DiagID', 'DiagnosticArgument', 'DiagnosticFixIt', and 'DiagnosticEngine'
1 parent 9297ba1 commit 05d5e0c

File tree

12 files changed

+435
-0
lines changed

12 files changed

+435
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# This source file is part of the Swift.org open source project
2+
#
3+
# Copyright (c) 2022 Apple Inc. and the Swift project authors
4+
# Licensed under Apache License v2.0 with Runtime Library Exception
5+
#
6+
# See http://swift.org/LICENSE.txt for license information
7+
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
8+
9+
add_swift_compiler_module(AST
10+
DEPENDS
11+
Basic
12+
SOURCES
13+
DiagnosticEngine.swift)
14+
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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+
@_exported import ASTBridging
14+
import Basic
15+
16+
public typealias DiagID = BridgedDiagID
17+
18+
extension BridgedDiagnosticArgument {
19+
init(stringRef val: BridgedStringRef) {
20+
self.init(kind: .stringRef, value: .init(stringRefValue: val))
21+
}
22+
init(int val: Int) {
23+
self.init(kind: .int, value: .init(intValue: val))
24+
}
25+
init(uInt val: UInt) {
26+
self.init(kind: .uInt, value: .init(uintValue: val))
27+
}
28+
}
29+
30+
public protocol DiagnosticArgument {
31+
func withBridgedDiagnosticArgument(_ fn: (BridgedDiagnosticArgument) -> Void)
32+
}
33+
extension String: DiagnosticArgument {
34+
public func withBridgedDiagnosticArgument(_ fn: (BridgedDiagnosticArgument) -> Void) {
35+
withBridgedStringRef { fn(BridgedDiagnosticArgument(stringRef: $0)) }
36+
}
37+
}
38+
extension Int: DiagnosticArgument {
39+
public func withBridgedDiagnosticArgument(_ fn: (BridgedDiagnosticArgument) -> Void) {
40+
fn(BridgedDiagnosticArgument(int: self))
41+
}
42+
}
43+
extension UInt: DiagnosticArgument {
44+
public func withBridgedDiagnosticArgument(_ fn: (BridgedDiagnosticArgument) -> Void) {
45+
fn(BridgedDiagnosticArgument(uInt: self))
46+
}
47+
}
48+
49+
public struct DiagnosticFixIt {
50+
public var start: SourceLoc
51+
public var byteLength: Int
52+
public var text: String
53+
54+
public init(start: SourceLoc, byteLength: Int, replacement text: String) {
55+
self.start = start
56+
self.byteLength = byteLength
57+
self.text = text
58+
}
59+
60+
func withBridgedDiagnosticFixIt(_ fn: (BridgedDiagnosticFixIt) -> Void) {
61+
text.withBridgedStringRef { bridgedTextRef in
62+
let bridgedDiagnosticFixIt = BridgedDiagnosticFixIt(
63+
start: start.bridged,
64+
byteLength: byteLength,
65+
text: bridgedTextRef)
66+
fn(bridgedDiagnosticFixIt)
67+
}
68+
}
69+
}
70+
71+
public struct DiagnosticEngine {
72+
private var bridged: BridgedDiagnosticEngine
73+
74+
public init(bridged: BridgedDiagnosticEngine) {
75+
self.bridged = bridged
76+
}
77+
78+
public func diagnose(_ position: SourceLoc?,
79+
_ id: DiagID,
80+
_ args: [DiagnosticArgument],
81+
highlight: CharSourceRange? = nil,
82+
fixIts: [DiagnosticFixIt] = []) {
83+
84+
let bridgedSourceLoc: BridgedSourceLoc = position.bridged
85+
let bridgedHighlightRange: BridgedCharSourceRange = highlight.bridged
86+
var bridgedArgs: [BridgedDiagnosticArgument] = []
87+
var bridgedFixIts: [BridgedDiagnosticFixIt] = []
88+
89+
var closure: () -> Void = {
90+
bridgedArgs.withBridgedArrayRef { bridgedArgsRef in
91+
bridgedFixIts.withBridgedArrayRef { bridgedFixItsRef in
92+
DiagnosticEngine_diagnose(bridged, bridgedSourceLoc,
93+
id, bridgedArgsRef,
94+
bridgedHighlightRange, bridgedFixItsRef)
95+
}
96+
}
97+
}
98+
for arg in args {
99+
closure = { [closure, arg] in
100+
arg.withBridgedDiagnosticArgument { bridgedArg in
101+
bridgedArgs.append(bridgedArg)
102+
closure()
103+
}
104+
}
105+
}
106+
for fixIt in fixIts {
107+
closure = { [closure, fixIt] in
108+
fixIt.withBridgedDiagnosticFixIt { bridgedFixIt in
109+
bridgedFixIts.append(bridgedFixIt)
110+
closure()
111+
}
112+
}
113+
}
114+
115+
closure()
116+
}
117+
}

SwiftCompilerSources/Sources/Basic/CMakeLists.txt

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

99
add_swift_compiler_module(Basic
10+
SourceLoc.swift
1011
Utils.swift)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//===--- SourceLoc.swift - SourceLoc bridiging utilities ------------------===//
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+
public struct SourceLoc {
14+
public var pointer: UnsafePointer<UInt8>
15+
16+
public init?(pointer: UnsafePointer<UInt8>?) {
17+
guard let pointer = pointer else {
18+
return nil
19+
}
20+
self.pointer = pointer
21+
}
22+
23+
public init?(pointer: UnsafePointer<CChar>?) {
24+
guard let pointer = pointer else {
25+
return nil
26+
}
27+
self.pointer = UnsafeRawPointer(pointer).assumingMemoryBound(to: UInt8.self)
28+
}
29+
30+
public init?(bridged: BridgedSourceLoc) {
31+
guard let pointer = bridged.pointer else {
32+
return nil
33+
}
34+
self.init(pointer: pointer)
35+
}
36+
37+
public var bridged: BridgedSourceLoc {
38+
.init(pointer: pointer)
39+
}
40+
}
41+
42+
extension Optional where Wrapped == SourceLoc {
43+
public var bridged: BridgedSourceLoc {
44+
self?.bridged ?? .init(pointer: nil)
45+
}
46+
}
47+
48+
public struct CharSourceRange {
49+
public var start: SourceLoc
50+
public var byteLength: Int
51+
52+
public init(start: SourceLoc, byteLength: Int) {
53+
self.start = start
54+
self.byteLength = byteLength
55+
}
56+
57+
public init?(bridged: BridgedCharSourceRange) {
58+
guard let start = SourceLoc(bridged: bridged.start) else {
59+
return nil
60+
}
61+
self.init(start: start, byteLength: bridged.byteLength)
62+
}
63+
64+
public var bridged: BridgedCharSourceRange {
65+
.init(start: start.bridged, byteLength: byteLength)
66+
}
67+
}
68+
69+
extension Optional where Wrapped == CharSourceRange {
70+
public var bridged: BridgedCharSourceRange {
71+
self?.bridged ?? .init(start: .init(pointer: nil), byteLength: 0)
72+
}
73+
}

SwiftCompilerSources/Sources/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
# NOTE: Subdirectories must be added in dependency order.
1010

1111
add_subdirectory(Basic)
12+
add_subdirectory(AST)
1213
if(SWIFT_ENABLE_EXPERIMENTAL_STRING_PROCESSING)
1314
add_subdirectory(ExperimentalRegex)
1415
endif()

include/swift/AST/ASTBridging.h

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//===--- ASTBridging.h - header for the swift SILBridging module ----------===//
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+
#ifndef SWIFT_AST_ASTBRIDGING_H
14+
#define SWIFT_AST_ASTBRIDGING_H
15+
16+
#include "swift/Basic/BasicBridging.h"
17+
#include "swift/Basic/Compiler.h"
18+
#include <stdbool.h>
19+
#include <stddef.h>
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
26+
27+
//===----------------------------------------------------------------------===//
28+
// Diagnostic Engine
29+
//===----------------------------------------------------------------------===//
30+
31+
// TODO: Move this to somewhere common header.
32+
#if __has_attribute(enum_extensibility)
33+
#define ENUM_EXTENSIBILITY_ATTR(arg) __attribute__((enum_extensibility(arg)))
34+
#else
35+
#define ENUM_EXTENSIBILITY_ATTR(arg)
36+
#endif
37+
38+
// NOTE: This must be the same underlying value as C++ 'swift::DiagID' defined
39+
// in 'DiagnosticList.cpp'.
40+
typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedDiagID : uint32_t {
41+
#define DIAG(KIND, ID, Options, Text, Signature) BridgedDiagID_##ID,
42+
#include "swift/AST/DiagnosticsAll.def"
43+
} BridgedDiagID;
44+
45+
typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedDiagnosticArgumentKind {
46+
BridgedDiagnosticArgumentKind_StringRef,
47+
BridgedDiagnosticArgumentKind_Int,
48+
BridgedDiagnosticArgumentKind_UInt,
49+
} BridgedDiagnosticArgumentKind;
50+
51+
typedef struct {
52+
BridgedDiagnosticArgumentKind kind;
53+
union {
54+
BridgedStringRef stringRefValue;
55+
SwiftInt intValue;
56+
SwiftUInt uintValue;
57+
} value;
58+
} BridgedDiagnosticArgument;
59+
60+
typedef struct {
61+
BridgedSourceLoc start;
62+
SwiftInt byteLength;
63+
BridgedStringRef text;
64+
} BridgedDiagnosticFixIt;
65+
66+
typedef struct {
67+
void * _Nonnull object;
68+
} BridgedDiagnosticEngine;
69+
70+
// FIXME: Can we bridge InFlightDiagnostic?
71+
void DiagnosticEngine_diagnose(BridgedDiagnosticEngine, BridgedSourceLoc loc,
72+
BridgedDiagID diagID, BridgedArrayRef arguments,
73+
BridgedCharSourceRange highlight,
74+
BridgedArrayRef fixIts);
75+
76+
bool DiagnosticEngine_hadAnyError(BridgedDiagnosticEngine);
77+
78+
SWIFT_END_NULLABILITY_ANNOTATIONS
79+
80+
#ifdef __cplusplus
81+
} // extern "C"
82+
#endif
83+
84+
#endif // SWIFT_AST_ASTBRIDGING_H

include/swift/AST/BridgingUtils.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//===--- BridgingUtils.h - utilities for swift bridging -------------------===//
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+
#ifndef SWIFT_AST_BRIDGINGUTILS_H
14+
#define SWIFT_AST_BRIDGINGUTILS_H
15+
16+
#include "swift/AST/ASTBridging.h"
17+
#include "swift/AST/DiagnosticEngine.h"
18+
19+
namespace swift {
20+
21+
inline BridgedDiagnosticEngine getBridgedDiagnosticEngine(DiagnosticEngine *D) {
22+
return {(void *)D};
23+
}
24+
25+
} // namespace swift
26+
27+
#endif
28+

include/swift/Basic/BasicBridging.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,19 @@ void OStream_write(BridgedOStream os, BridgedStringRef str);
4343

4444
void freeBridgedStringRef(BridgedStringRef str);
4545

46+
//===----------------------------------------------------------------------===//
47+
// Source location
48+
//===----------------------------------------------------------------------===//
49+
50+
typedef struct {
51+
const unsigned char * _Nullable pointer;
52+
} BridgedSourceLoc;
53+
54+
typedef struct {
55+
BridgedSourceLoc start;
56+
SwiftInt byteLength;
57+
} BridgedCharSourceRange;
58+
4659
SWIFT_END_NULLABILITY_ANNOTATIONS
4760

4861
#ifdef __cplusplus

include/swift/Basic/BridgingUtils.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,27 @@ inline llvm::ArrayRef<T> getArrayRef(BridgedArrayRef bridged) {
3636
return {static_cast<const T *>(bridged.data), bridged.numElements};
3737
}
3838

39+
inline SourceLoc getSourceLoc(const BridgedSourceLoc &bridged) {
40+
return SourceLoc(
41+
llvm::SMLoc::getFromPointer((const char *)bridged.pointer));
42+
}
43+
44+
inline BridgedSourceLoc getBridgedSourceLoc(const SourceLoc &loc) {
45+
return {static_cast<const unsigned char *>(loc.getOpaquePointerValue())};
46+
}
47+
48+
inline CharSourceRange
49+
getCharSourceRange(const BridgedCharSourceRange &bridged) {
50+
auto start = getSourceLoc(bridged.start);
51+
return CharSourceRange(start, bridged.byteLength);
52+
}
53+
54+
inline BridgedCharSourceRange
55+
getBridgedCharSourceRange(const CharSourceRange &range) {
56+
auto start = getBridgedSourceLoc(range.getStart());
57+
return {start, range.getByteLength()};
58+
}
59+
3960
/// Copies the string in an malloc'ed memory and the caller is responsible for
4061
/// freeing it. 'freeBridgedStringRef()' is available in 'BasicBridging.h'
4162
inline BridgedStringRef

include/swift/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ module BasicBridging {
44
export *
55
}
66

7+
module ASTBridging {
8+
header "AST/ASTBridging.h"
9+
export *
10+
}
11+
712
module SILBridging {
813
header "SIL/SILBridging.h"
914
export *

0 commit comments

Comments
 (0)