Skip to content

Commit f4f4dbf

Browse files
committed
Move SyntaxClassifier to a separate module
rdar://98318240
1 parent 587d3ad commit f4f4dbf

13 files changed

+114
-69
lines changed

Package.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ let package = Package(
4545
.macCatalyst(.v13),
4646
],
4747
products: [
48+
.library(name: "IDEUtils", type: .static, targets: ["IDEUtils"]),
4849
.library(name: "SwiftOperators", type: .static, targets: ["SwiftOperators"]),
4950
.library(name: "SwiftParser", type: .static, targets: ["SwiftParser"]),
5051
.library(name: "SwiftSyntax", type: .static, targets: ["SwiftSyntax"]),
@@ -114,6 +115,10 @@ let package = Package(
114115
name: "_SwiftSyntaxTestSupport",
115116
dependencies: ["SwiftBasicFormat", "SwiftSyntax", "SwiftSyntaxBuilder"]
116117
),
118+
.target(
119+
name: "IDEUtils",
120+
dependencies: ["SwiftSyntax"]
121+
),
117122
.target(
118123
name: "SwiftParser",
119124
dependencies: ["SwiftBasicFormat", "SwiftDiagnostics", "SwiftSyntax"],

Sources/SwiftSyntax/SyntaxClassifier.swift renamed to Sources/IDEUtils/SyntaxClassifier.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
@_spi(RawSyntax) @_spi(SyntaxData) import SwiftSyntax
14+
1315
extension SyntaxData {
1416
var contextualClassification: (SyntaxClassification, Bool)? {
1517
var contextualClassif: (SyntaxClassification, Bool)? = nil
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 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 SwiftSyntax
14+
15+
public extension SyntaxProtocol {
16+
17+
/// Sequence of `SyntaxClassifiedRange`s for this syntax node.
18+
///
19+
/// The provided classified ranges are consecutive and cover the full source
20+
/// text of the node. The ranges may also span multiple tokens, if multiple
21+
/// consecutive tokens would have the same classification then a single classified
22+
/// range is provided for all of them.
23+
var classifications: SyntaxClassifications {
24+
let fullRange = ByteSourceRange(offset: 0, length: byteSize)
25+
return SyntaxClassifications(_syntaxNode, in: fullRange)
26+
}
27+
28+
/// Sequence of `SyntaxClassifiedRange`s contained in this syntax node within
29+
/// a relative range.
30+
///
31+
/// The provided classified ranges may extend beyond the provided `range`.
32+
/// Active classifications (non-`none`) will extend the range to include the
33+
/// full classified range (e.g. from the beginning of the comment block), while
34+
/// `none` classified ranges will extend to the beginning or end of the token
35+
/// that the `range` touches.
36+
/// It is guaranteed that no classified range will be provided that doesn't
37+
/// intersect the provided `range`.
38+
///
39+
/// - Parameters:
40+
/// - in: The relative byte range to pull `SyntaxClassifiedRange`s from.
41+
/// - Returns: Sequence of `SyntaxClassifiedRange`s.
42+
func classifications(in range: ByteSourceRange) -> SyntaxClassifications {
43+
return SyntaxClassifications(_syntaxNode, in: range)
44+
}
45+
46+
/// The `SyntaxClassifiedRange` for a relative byte offset.
47+
/// - Parameters:
48+
/// - at: The relative to the node byte offset.
49+
/// - Returns: The `SyntaxClassifiedRange` for the offset or nil if the source text
50+
/// at the given offset is unclassified.
51+
func classification(at offset: Int) -> SyntaxClassifiedRange? {
52+
let classifications = SyntaxClassifications(_syntaxNode, in: ByteSourceRange(offset: offset, length: 1))
53+
var iterator = classifications.makeIterator()
54+
return iterator.next()
55+
}
56+
57+
/// The `SyntaxClassifiedRange` for an absolute position.
58+
/// - Parameters:
59+
/// - at: The absolute position.
60+
/// - Returns: The `SyntaxClassifiedRange` for the position or nil if the source text
61+
/// at the given position is unclassified.
62+
func classification(at position: AbsolutePosition) -> SyntaxClassifiedRange? {
63+
let relativeOffset = position.utf8Offset - self.position.utf8Offset
64+
return self.classification(at: relativeOffset)
65+
}
66+
}

Sources/SwiftSyntax/gyb_generated/SyntaxClassification.swift renamed to Sources/IDEUtils/gyb_generated/SyntaxClassification.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
//
1313
//===----------------------------------------------------------------------===//
1414

15+
@_spi(RawSyntax) import SwiftSyntax
16+
1517
public enum SyntaxClassification {
1618
/// The token should not receive syntax coloring.
1719
case none

Sources/SwiftSyntax/Raw/RawSyntax.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
typealias RawSyntaxBuffer = UnsafeBufferPointer<RawSyntax?>
13+
@_spi(RawSyntax) public typealias RawSyntaxBuffer = UnsafeBufferPointer<RawSyntax?>
1414
typealias RawTriviaPieceBuffer = UnsafeBufferPointer<RawTriviaPiece>
1515

1616
fileprivate extension SyntaxKind {
@@ -148,7 +148,8 @@ extension RawSyntax {
148148
}
149149

150150
/// Whether or not this node is a token one.
151-
var isToken: Bool {
151+
@_spi(RawSyntax)
152+
public var isToken: Bool {
152153
kind == .token
153154
}
154155

Sources/SwiftSyntax/Raw/RawSyntaxLayoutView.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
extension RawSyntax {
1414
/// A view into the `RawSyntax` that exposes functionality that's specific to layout nodes.
1515
/// The token's payload must be a layout, otherwise this traps.
16-
var layoutView: RawSyntaxLayoutView? {
16+
@_spi(RawSyntax)
17+
public var layoutView: RawSyntaxLayoutView? {
1718
switch raw.payload {
1819
case .parsedToken, .materializedToken:
1920
return nil
@@ -24,7 +25,8 @@ extension RawSyntax {
2425
}
2526

2627
/// A view into `RawSyntax` that exposes functionality that only applies to layout nodes.
27-
struct RawSyntaxLayoutView {
28+
@_spi(RawSyntax)
29+
public struct RawSyntaxLayoutView {
2830
private let raw: RawSyntax
2931

3032
fileprivate init(raw: RawSyntax) {
@@ -149,7 +151,8 @@ struct RawSyntaxLayoutView {
149151
}
150152

151153
/// Child nodes.
152-
var children: RawSyntaxBuffer {
154+
@_spi(RawSyntax)
155+
public var children: RawSyntaxBuffer {
153156
layoutData.layout
154157
}
155158

Sources/SwiftSyntax/Raw/RawSyntaxTokenView.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
extension RawSyntax {
1414
/// A view into the `RawSyntax` that exposes functionality that's specific to tokens.
1515
/// The token's payload must be a token, otherwise this traps.
16-
var tokenView: RawSyntaxTokenView? {
16+
@_spi(RawSyntax)
17+
public var tokenView: RawSyntaxTokenView? {
1718
switch raw.payload {
1819
case .parsedToken, .materializedToken:
1920
return RawSyntaxTokenView(raw: self)
@@ -24,7 +25,8 @@ extension RawSyntax {
2425
}
2526

2627
/// A view into `RawSyntax` that exposes functionality that only applies to tokens.
27-
struct RawSyntaxTokenView {
28+
@_spi(RawSyntax)
29+
public struct RawSyntaxTokenView {
2830
let raw: RawSyntax
2931

3032
fileprivate init(raw: RawSyntax) {
@@ -38,7 +40,8 @@ struct RawSyntaxTokenView {
3840
}
3941

4042
/// Token kind of this node.
41-
var rawKind: RawTokenKind {
43+
@_spi(RawSyntax)
44+
public var rawKind: RawTokenKind {
4245
switch raw.rawData.payload {
4346
case .materializedToken(let dat):
4447
return dat.tokenKind
@@ -50,7 +53,8 @@ struct RawSyntaxTokenView {
5053
}
5154

5255
/// Token text of this node.
53-
var rawText: SyntaxText {
56+
@_spi(RawSyntax)
57+
public var rawText: SyntaxText {
5458
switch raw.rawData.payload {
5559
case .parsedToken(let dat):
5660
return dat.tokenText
@@ -85,7 +89,8 @@ struct RawSyntaxTokenView {
8589
}
8690
}
8791

88-
var leadingRawTriviaPieces: [RawTriviaPiece] {
92+
@_spi(RawSyntax)
93+
public var leadingRawTriviaPieces: [RawTriviaPiece] {
8994
switch raw.rawData.payload {
9095
case .parsedToken(let dat):
9196
return raw.arena.parseTrivia(source: dat.leadingTriviaText, position: .leading)
@@ -96,7 +101,8 @@ struct RawSyntaxTokenView {
96101
}
97102
}
98103

99-
var trailingRawTriviaPieces: [RawTriviaPiece] {
104+
@_spi(RawSyntax)
105+
public var trailingRawTriviaPieces: [RawTriviaPiece] {
100106
switch raw.rawData.payload {
101107
case .parsedToken(let dat):
102108
return raw.arena.parseTrivia(source: dat.trailingTriviaText, position: .trailing)
@@ -108,7 +114,8 @@ struct RawSyntaxTokenView {
108114
}
109115

110116
/// Returns the leading `Trivia` length.
111-
var leadingTriviaLength: SourceLength {
117+
@_spi(RawSyntax)
118+
public var leadingTriviaLength: SourceLength {
112119
return SourceLength(utf8Length: leadingTriviaByteLength)
113120
}
114121

Sources/SwiftSyntax/Syntax.swift

Lines changed: 2 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ public extension SyntaxProtocol {
152152
}
153153

154154
extension SyntaxProtocol {
155-
var data: SyntaxData {
155+
@_spi(SyntaxData)
156+
public var data: SyntaxData {
156157
return _syntaxNode.data
157158
}
158159

@@ -452,56 +453,6 @@ public extension SyntaxProtocol {
452453
return TokenSequence(_syntaxNode, viewMode: viewMode)
453454
}
454455

455-
/// Sequence of `SyntaxClassifiedRange`s for this syntax node.
456-
///
457-
/// The provided classified ranges are consecutive and cover the full source
458-
/// text of the node. The ranges may also span multiple tokens, if multiple
459-
/// consecutive tokens would have the same classification then a single classified
460-
/// range is provided for all of them.
461-
var classifications: SyntaxClassifications {
462-
let fullRange = ByteSourceRange(offset: 0, length: byteSize)
463-
return SyntaxClassifications(_syntaxNode, in: fullRange)
464-
}
465-
466-
/// Sequence of `SyntaxClassifiedRange`s contained in this syntax node within
467-
/// a relative range.
468-
///
469-
/// The provided classified ranges may extend beyond the provided `range`.
470-
/// Active classifications (non-`none`) will extend the range to include the
471-
/// full classified range (e.g. from the beginning of the comment block), while
472-
/// `none` classified ranges will extend to the beginning or end of the token
473-
/// that the `range` touches.
474-
/// It is guaranteed that no classified range will be provided that doesn't
475-
/// intersect the provided `range`.
476-
///
477-
/// - Parameters:
478-
/// - in: The relative byte range to pull `SyntaxClassifiedRange`s from.
479-
/// - Returns: Sequence of `SyntaxClassifiedRange`s.
480-
func classifications(in range: ByteSourceRange) -> SyntaxClassifications {
481-
return SyntaxClassifications(_syntaxNode, in: range)
482-
}
483-
484-
/// The `SyntaxClassifiedRange` for a relative byte offset.
485-
/// - Parameters:
486-
/// - at: The relative to the node byte offset.
487-
/// - Returns: The `SyntaxClassifiedRange` for the offset or nil if the source text
488-
/// at the given offset is unclassified.
489-
func classification(at offset: Int) -> SyntaxClassifiedRange? {
490-
let classifications = SyntaxClassifications(_syntaxNode, in: ByteSourceRange(offset: offset, length: 1))
491-
var iterator = classifications.makeIterator()
492-
return iterator.next()
493-
}
494-
495-
/// The `SyntaxClassifiedRange` for an absolute position.
496-
/// - Parameters:
497-
/// - at: The absolute position.
498-
/// - Returns: The `SyntaxClassifiedRange` for the position or nil if the source text
499-
/// at the given position is unclassified.
500-
func classification(at position: AbsolutePosition) -> SyntaxClassifiedRange? {
501-
let relativeOffset = position.utf8Offset - self.position.utf8Offset
502-
return self.classification(at: relativeOffset)
503-
}
504-
505456
/// Returns a value representing the unique identity of the node.
506457
var id: SyntaxIdentifier {
507458
return data.nodeId

Sources/SwiftSyntax/SyntaxData.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ struct AbsoluteRawSyntax {
194194
///
195195
/// SyntaxData is an implementation detail, and should not be exposed to clients
196196
/// of SwiftSyntax.
197-
struct SyntaxData {
197+
@_spi(SyntaxData)
198+
public struct SyntaxData {
198199
private enum Info {
199200
case root(Root)
200201
indirect case nonRoot(NonRoot)
@@ -212,7 +213,8 @@ struct SyntaxData {
212213
}
213214

214215
private let info: Info
215-
let raw: RawSyntax
216+
@_spi(SyntaxData) @_spi(RawSyntax)
217+
public let raw: RawSyntax
216218

217219
private var rootInfo: Info.Root {
218220
switch info {
@@ -239,7 +241,8 @@ struct SyntaxData {
239241
}
240242
}
241243

242-
var parent: SyntaxData? {
244+
@_spi(SyntaxData)
245+
public var parent: SyntaxData? {
243246
nonRootInfo?.parent
244247
}
245248

@@ -251,7 +254,8 @@ struct SyntaxData {
251254
AbsoluteRawSyntax(raw: raw, info: absoluteInfo)
252255
}
253256

254-
var indexInParent: Int {
257+
@_spi(SyntaxData)
258+
public var indexInParent: Int {
255259
Int(absoluteInfo.indexInParent)
256260
}
257261

Sources/SwiftSyntax/SyntaxOtherNodes.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ extension UnknownSyntax: CustomReflectable {
5757
public struct TokenSyntax: SyntaxProtocol, SyntaxHashable {
5858
public let _syntaxNode: Syntax
5959

60-
var tokenView: RawSyntaxTokenView {
60+
@_spi(RawSyntax)
61+
public var tokenView: RawSyntaxTokenView {
6162
return raw.tokenView!
6263
}
6364

Sources/SwiftSyntax/SyntaxTreeViewMode.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public enum SyntaxTreeViewMode {
2828
case all
2929

3030
/// Returns whether this traversal node should visit `node` or ignore it.
31-
func shouldTraverse(node: RawSyntax) -> Bool {
31+
@_spi(RawSyntax)
32+
public func shouldTraverse(node: RawSyntax) -> Bool {
3233
switch self {
3334
case .sourceAccurate:
3435
if let tokenView = node.tokenView {

build-script.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
PACKAGE_DIR = os.path.dirname(os.path.realpath(__file__))
1717
WORKSPACE_DIR = os.path.dirname(PACKAGE_DIR)
1818
SOURCES_DIR = os.path.join(PACKAGE_DIR, "Sources")
19+
IDEUTILS_DIR = os.path.join(SOURCES_DIR, "IDEUtils")
1920
SWIFTSYNTAX_DIR = os.path.join(SOURCES_DIR, "SwiftSyntax")
2021
SWIFTSYNTAX_DOCUMENTATION_DIR = \
2122
os.path.join(SWIFTSYNTAX_DIR, "Documentation.docc")
@@ -299,6 +300,7 @@ def generate_syntax_node_template_gyb_files(
299300
def gyb_dir_mapping(temp_directories: bool) -> Dict[str, str]:
300301
source_dirs = [
301302
SYNTAXSUPPORT_DIR,
303+
IDEUTILS_DIR,
302304
SWIFTSYNTAX_DIR,
303305
os.path.join(SWIFTSYNTAX_DIR, "Raw"),
304306
SWIFTSYNTAXBUILDER_DIR,

0 commit comments

Comments
 (0)