Skip to content

Commit 856115e

Browse files
committed
Move SyntaxClassifier to a separate module
rdar://98318240
1 parent dcc67f7 commit 856115e

12 files changed

+98
-62
lines changed

Package.swift

Lines changed: 12 additions & 3 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"]),
@@ -77,7 +78,6 @@ let package = Package(
7778
"Raw/RawSyntaxValidation.swift.gyb",
7879
"SyntaxAnyVisitor.swift.gyb",
7980
"SyntaxBaseNodes.swift.gyb",
80-
"SyntaxClassification.swift.gyb",
8181
"SyntaxCollections.swift.gyb",
8282
"SyntaxEnum.swift.gyb",
8383
"SyntaxFactory.swift.gyb",
@@ -97,6 +97,7 @@ let package = Package(
9797
name: "SwiftSyntaxBuilder",
9898
dependencies: ["SwiftBasicFormat", "SwiftSyntax", "SwiftParser"],
9999
exclude: [
100+
"CMakeLists.txt",
100101
"gyb_helpers",
101102
"SyntaxExpressibleByStringInterpolationConformances.swift.gyb",
102103
]
@@ -114,6 +115,13 @@ let package = Package(
114115
name: "_SwiftSyntaxTestSupport",
115116
dependencies: ["SwiftBasicFormat", "SwiftSyntax", "SwiftSyntaxBuilder"]
116117
),
118+
.target(
119+
name: "IDEUtils",
120+
dependencies: ["SwiftSyntax"],
121+
exclude: [
122+
"SyntaxClassification.swift.gyb",
123+
]
124+
),
117125
.target(
118126
name: "SwiftParser",
119127
dependencies: ["SwiftBasicFormat", "SwiftDiagnostics", "SwiftSyntax"],
@@ -151,13 +159,14 @@ let package = Package(
151159
]),
152160
.executableTarget(
153161
name: "lit-test-helper",
154-
dependencies: ["SwiftSyntax", "SwiftSyntaxParser"]
162+
dependencies: ["IDEUtils", "SwiftSyntax", "SwiftSyntaxParser"]
155163
),
156164
.executableTarget(
157165
name: "swift-parser-cli",
158166
dependencies: ["SwiftDiagnostics", "SwiftSyntax", "SwiftParser", "SwiftOperators", "_SwiftSyntaxMacros",
159167
.product(name: "ArgumentParser", package: "swift-argument-parser")]
160168
),
169+
.testTarget(name: "IDEUtilsTest", dependencies: ["_SwiftSyntaxTestSupport", "SwiftParser", "SwiftSyntax", "IDEUtils"]),
161170
.testTarget(
162171
name: "SwiftDiagnosticsTest",
163172
dependencies: ["_SwiftSyntaxTestSupport", "SwiftDiagnostics", "SwiftParser"]
@@ -183,7 +192,7 @@ let package = Package(
183192
),
184193
.testTarget(
185194
name: "PerformanceTest",
186-
dependencies: ["SwiftSyntax", "SwiftSyntaxParser", "SwiftParser"],
195+
dependencies: ["IDEUtils", "SwiftSyntax", "SwiftSyntaxParser", "SwiftParser"],
187196
exclude: ["Inputs"]
188197
),
189198
.testTarget(
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/SyntaxClassification.swift.gyb renamed to Sources/IDEUtils/SyntaxClassification.swift.gyb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
//
3636
//===----------------------------------------------------------------------===//
3737

38+
@_spi(RawSyntax) import SwiftSyntax
39+
3840
public enum SyntaxClassification {
3941
% for classification in SYNTAX_CLASSIFICATIONS:
4042
% for line in dedented_lines(classification.description):

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

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

13-
extension SyntaxData {
13+
@_spi(RawSyntax) import SwiftSyntax
14+
15+
fileprivate extension SyntaxProtocol {
1416
var contextualClassification: (SyntaxClassification, Bool)? {
1517
var contextualClassif: (SyntaxClassification, Bool)? = nil
16-
var curData = self
18+
var curData = Syntax(self)
1719
repeat {
1820
guard let parent = curData.parent else { break }
1921
contextualClassif = SyntaxClassification.classify(parentKind: parent.raw.kind,
@@ -27,10 +29,10 @@ extension SyntaxData {
2729
extension TokenSyntax {
2830
/// The `SyntaxClassifiedRange` for the token text, excluding trivia.
2931
public var tokenClassification: SyntaxClassifiedRange {
30-
let contextualClassification = self.data.contextualClassification
31-
let relativeOffset = tokenView.leadingTriviaLength.utf8Length
32+
let contextualClassification = self.contextualClassification
33+
let relativeOffset = leadingTriviaLength.utf8Length
3234
let absoluteOffset = position.utf8Offset + relativeOffset
33-
return TokenKindAndText(kind: tokenView.rawKind, text: tokenView.rawText).classify(
35+
return TokenKindAndText(kind: rawTokenKind, text: tokenView.rawText).classify(
3436
offset: absoluteOffset, contextualClassification: contextualClassification)
3537
}
3638
}
@@ -122,7 +124,7 @@ private struct ClassificationVisitor {
122124
_ = self.visit(Descriptor(
123125
node: node.raw,
124126
byteOffset: node.position.utf8Offset,
125-
contextualClassification: node.data.contextualClassification))
127+
contextualClassification: node.contextualClassification))
126128
}
127129
}
128130

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/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ add_library(SwiftSyntax STATIC
1818
Syntax.swift
1919
SyntaxArena.swift
2020
SyntaxChildren.swift
21-
SyntaxClassifier.swift
2221
SyntaxData.swift
2322
SyntaxOtherNodes.swift
2423
SyntaxText.swift
@@ -37,7 +36,6 @@ add_library(SwiftSyntax STATIC
3736
gyb_generated/Misc.swift
3837
gyb_generated/SyntaxAnyVisitor.swift
3938
gyb_generated/SyntaxBaseNodes.swift
40-
gyb_generated/SyntaxClassification.swift
4139
gyb_generated/SyntaxCollections.swift
4240
gyb_generated/SyntaxEnum.swift
4341
gyb_generated/SyntaxFactory.swift

Sources/SwiftSyntax/Syntax.swift

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -456,56 +456,6 @@ public extension SyntaxProtocol {
456456
return TokenSequence(_syntaxNode, viewMode: viewMode)
457457
}
458458

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

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 {

Sources/lit-test-helper/ClassifiedSyntaxTreePrinter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import IDEUtils
1314
import SwiftSyntax
1415
import Foundation
1516

Tests/SwiftParserTest/ClassificationTests.swift renamed to Tests/IDEUtilsTest/ClassificationTests.swift

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

1313
import XCTest
14+
import IDEUtils
1415
import SwiftSyntax
1516
import SwiftParser
17+
import _SwiftSyntaxTestSupport
1618

1719
public class ClassificationTests: XCTestCase {
1820

Tests/PerformanceTest/SyntaxClassifierPerformanceTests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import XCTest
14+
import IDEUtils
1415
import SwiftSyntax
1516
import SwiftSyntaxParser
1617

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)