Skip to content

Commit 748e457

Browse files
committed
Classify Operator Identifiers
1 parent a1079dd commit 748e457

File tree

8 files changed

+74
-9
lines changed

8 files changed

+74
-9
lines changed

CodeGeneration/Sources/SyntaxSupport/gyb_generated/Classification.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public let SYNTAX_CLASSIFICATIONS: [SyntaxClassification] = [
3232
SyntaxClassification(name: "Keyword", description: "A Swift keyword, including contextual keywords."),
3333
SyntaxClassification(name: "Identifier", description: "A generic identifier."),
3434
SyntaxClassification(name: "TypeIdentifier", description: "An identifier referring to a type."),
35+
SyntaxClassification(name: "OperatorIdentifier", description: "An identifier referring to an operator."),
3536
SyntaxClassification(name: "DollarIdentifier", description: "An identifier starting with `$` like `$0`."),
3637
SyntaxClassification(name: "IntegerLiteral", description: "An integer literal."),
3738
SyntaxClassification(name: "FloatingLiteral", description: "A floating point literal."),

CodeGeneration/Sources/SyntaxSupport/gyb_generated/DeclNodes.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,8 @@ public let DECL_NODES: [Node] = [
12881288
"SpacedBinaryOperator",
12891289
"PrefixOperator",
12901290
"PostfixOperator"
1291-
]),
1291+
],
1292+
classification: "OperatorIdentifier"),
12921293
Child(name: "OperatorPrecedenceAndTypes",
12931294
kind: "OperatorPrecedenceAndTypes",
12941295
description: "Optionally specify a precedence group and designated types.",

Sources/SwiftSyntax/gyb_generated/SyntaxClassification.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public enum SyntaxClassification {
2121
case identifier
2222
/// An identifier referring to a type.
2323
case typeIdentifier
24+
/// An identifier referring to an operator.
25+
case operatorIdentifier
2426
/// An identifier starting with `$` like `$0`.
2527
case dollarIdentifier
2628
/// An integer literal.
@@ -75,6 +77,8 @@ extension SyntaxClassification {
7577
return (.buildConfigId, false)
7678
case (.declModifier, 1):
7779
return (.attribute, false)
80+
case (.operatorDecl, 7):
81+
return (.operatorIdentifier, false)
7882
case (.precedenceGroupRelation, 1):
7983
return (.keyword, false)
8084
case (.precedenceGroupAssociativity, 1):
@@ -343,13 +347,13 @@ extension RawTokenKind {
343347
case .identifier:
344348
return .identifier
345349
case .unspacedBinaryOperator:
346-
return .none
350+
return .operatorIdentifier
347351
case .spacedBinaryOperator:
348-
return .none
352+
return .operatorIdentifier
349353
case .postfixOperator:
350-
return .none
354+
return .operatorIdentifier
351355
case .prefixOperator:
352-
return .none
356+
return .operatorIdentifier
353357
case .dollarIdentifier:
354358
return .dollarIdentifier
355359
case .contextualKeyword:

Sources/lit-test-helper/ClassifiedSyntaxTreePrinter.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extension SyntaxClassification {
2121
case .identifier: return "id"
2222
case .typeIdentifier: return "type"
2323
case .dollarIdentifier: return "dollar"
24+
case .operatorIdentifier: return "op"
2425
case .integerLiteral: return "int"
2526
case .floatingLiteral: return "float"
2627
case .stringLiteral: return "str"

Tests/SwiftParserTest/ClassificationTests.swift

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,56 @@ public class ClassificationTests: XCTestCase {
121121
XCTAssertEqual(classif.kind, .typeIdentifier)
122122
}
123123
}
124+
125+
public func testOperatorTokenClassification() {
126+
do {
127+
let source = "let x: Int = 4 + 5 / 6"
128+
let tree = Parser.parse(source: source)
129+
130+
let tokens = Array(tree.tokens(viewMode: .sourceAccurate))
131+
XCTAssertEqual(tokens.count, 10)
132+
guard tokens.count == 10 else {
133+
return
134+
}
135+
let classif = tokens.map { $0.tokenClassification }
136+
XCTAssertEqual(classif[0].kind, .keyword)
137+
XCTAssertEqual(classif[0].range, ByteSourceRange(offset: 0, length: 3))
138+
XCTAssertEqual(classif[1].kind, .identifier)
139+
XCTAssertEqual(classif[1].range, ByteSourceRange(offset: 4, length: 1))
140+
XCTAssertEqual(classif[2].kind, .none)
141+
XCTAssertEqual(classif[2].range, ByteSourceRange(offset: 5, length: 1))
142+
XCTAssertEqual(classif[3].kind, .typeIdentifier)
143+
XCTAssertEqual(classif[3].range, ByteSourceRange(offset: 7, length: 3))
144+
XCTAssertEqual(classif[4].kind, .none)
145+
XCTAssertEqual(classif[4].range, ByteSourceRange(offset: 11, length: 1))
146+
XCTAssertEqual(classif[5].kind, .integerLiteral)
147+
XCTAssertEqual(classif[5].range, ByteSourceRange(offset: 13, length: 1))
148+
XCTAssertEqual(classif[6].kind, .operatorIdentifier)
149+
XCTAssertEqual(classif[6].range, ByteSourceRange(offset: 15, length: 1))
150+
XCTAssertEqual(classif[7].kind, .integerLiteral)
151+
XCTAssertEqual(classif[7].range, ByteSourceRange(offset: 17, length: 1))
152+
XCTAssertEqual(classif[8].kind, .operatorIdentifier)
153+
XCTAssertEqual(classif[8].range, ByteSourceRange(offset: 19, length: 1))
154+
XCTAssertEqual(classif[9].kind, .integerLiteral)
155+
XCTAssertEqual(classif[9].range, ByteSourceRange(offset: 21, length: 1))
156+
}
157+
158+
do {
159+
let source = "infix operator *--*"
160+
let tree = Parser.parse(source: source)
161+
162+
let tokens = Array(tree.tokens(viewMode: .sourceAccurate))
163+
XCTAssertEqual(tokens.count, 3)
164+
guard tokens.count == 3 else {
165+
return
166+
}
167+
let classif = tokens.map { $0.tokenClassification }
168+
XCTAssertEqual(classif[0].kind, .keyword)
169+
XCTAssertEqual(classif[0].range, ByteSourceRange(offset: 0, length: 5))
170+
XCTAssertEqual(classif[1].kind, .keyword)
171+
XCTAssertEqual(classif[1].range, ByteSourceRange(offset: 6, length: 8))
172+
XCTAssertEqual(classif[2].kind, .operatorIdentifier)
173+
XCTAssertEqual(classif[2].range, ByteSourceRange(offset: 15, length: 4))
174+
}
175+
}
124176
}

gyb_syntax_support/Classification.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ def __init__(self, name, description):
2626
SyntaxClassification('TypeIdentifier', description='''
2727
An identifier referring to a type.
2828
'''),
29+
SyntaxClassification('OperatorIdentifier', description='''
30+
An identifier referring to an operator.
31+
'''),
2932
SyntaxClassification('DollarIdentifier', description='''
3033
An identifier starting with `$` like `$0`.
3134
'''),

gyb_syntax_support/DeclNodes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@
744744
'''),
745745
Child('OperatorKeyword', kind='OperatorToken'),
746746
Child('Identifier', kind='Token', name_for_diagnostics='name',
747+
classification='OperatorIdentifier',
747748
token_choices=[
748749
'UnspacedBinaryOperatorToken',
749750
'SpacedBinaryOperatorToken',

gyb_syntax_support/Token.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,14 +399,16 @@ def macro_name(self):
399399
Misc('Identifier', 'identifier', name_for_diagnostics='identifier',
400400
classification='Identifier', serialization_code=105),
401401
Misc('UnspacedBinaryOperator', 'oper_binary_unspaced',
402-
name_for_diagnostics='binary operator', serialization_code=107),
402+
name_for_diagnostics='binary operator',
403+
classification='OperatorIdentifier', serialization_code=107),
403404
Misc('SpacedBinaryOperator', 'oper_binary_spaced',
404-
name_for_diagnostics='binary operator', serialization_code=108,
405+
name_for_diagnostics='binary operator',
406+
classification='OperatorIdentifier', serialization_code=108,
405407
requires_leading_space=True, requires_trailing_space=True),
406408
Misc('PostfixOperator', 'oper_postfix', name_for_diagnostics='postfix operator',
407-
serialization_code=110),
409+
classification='OperatorIdentifier', serialization_code=110),
408410
Misc('PrefixOperator', 'oper_prefix', name_for_diagnostics='prefix operator',
409-
serialization_code=109),
411+
classification='OperatorIdentifier', serialization_code=109),
410412
Misc('DollarIdentifier', 'dollarident', name_for_diagnostics='dollar identifier',
411413
classification='DollarIdentifier', serialization_code=106),
412414

0 commit comments

Comments
 (0)