Skip to content

Commit d1c1564

Browse files
committed
[ASTGen] TokenSyntax.keyworkKind to directly get Keyword kind
This should be faster than e.g. `token.tokenKind == .keyword(.true)`.
1 parent 4673d63 commit d1c1564

File tree

5 files changed

+64
-47
lines changed

5 files changed

+64
-47
lines changed

lib/ASTGen/Sources/ASTGen/ASTGen.swift

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,10 @@ extension ASTGenVisitor {
137137
/// escaped identifier, backticks are stripped.
138138
@inline(__always)
139139
func generateIdentifier(_ token: TokenSyntax) -> BridgedIdentifier {
140-
var text = token.rawText
141-
// FIXME: Maybe `TokenSyntax.tokenView.rawKind == .wildcard`, or expose it as `.rawTokenKind`.
142-
if text == "_" {
140+
if token.rawTokenKind == .wildcard {
143141
return nil
144142
}
143+
var text = token.rawText
145144
if text.count > 2 && text.hasPrefix("`") && text.hasSuffix("`") {
146145
text = .init(rebasing: text.dropFirst().dropLast())
147146
}
@@ -382,6 +381,24 @@ extension Optional where Wrapped: LazyCollectionProtocol {
382381
}
383382
}
384383

384+
extension TokenSyntax {
385+
/// Get `Keyword` kind if the token is a keyword.
386+
var keywordKind: Keyword? {
387+
// Performance note:
388+
// This is faster than `token.tokenKind == .keyword(.true)` because
389+
// `TokenKind.tokenKind` may instantiate `Swift.String`.
390+
// That being said, `SwiftSyntax.Keyword` is a non-SPI public type, so it
391+
// cannot be `@frozen`. Also `Keyword(_:SyntaxText)` itself is heavier than
392+
// simple `token.rawText == "true"`.
393+
// We should ensure `token.keywordKind == .true` is optimized out to
394+
// a simple `cmp` instruction.
395+
guard rawTokenKind == .keyword else {
396+
return nil
397+
}
398+
return Keyword(self.rawText)
399+
}
400+
}
401+
385402
/// Generate AST nodes for all top-level entities in the given source file.
386403
@_cdecl("swift_ASTGen_buildTopLevelASTNodes")
387404
public func buildTopLevelASTNodes(

lib/ASTGen/Sources/ASTGen/Decls.swift

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import ASTBridging
1414
import BasicBridging
1515
import SwiftDiagnostics
16-
@_spi(ExperimentalLanguageFeatures) import SwiftSyntax
16+
@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax
1717

1818
// MARK: - TypeDecl
1919

@@ -293,7 +293,7 @@ extension ASTGenVisitor {
293293
let initializer = generate(initializerClause: node.bindings.first!.initializer!)
294294

295295
let isStatic = false // TODO: compute this
296-
let isLet = node.bindingSpecifier.tokenKind == .keyword(.let)
296+
let isLet = node.bindingSpecifier.keywordKind == .let
297297

298298
return .createParsed(
299299
self.ctx,
@@ -347,7 +347,7 @@ extension ASTGenVisitor {
347347
declContext: self.declContext,
348348
initKeywordLoc: self.generateSourceLoc(node.initKeyword),
349349
failabilityMarkLoc: self.generateSourceLoc(node.optionalMark),
350-
isIUO: node.optionalMark?.tokenKind == .exclamationMark,
350+
isIUO: node.optionalMark?.rawTokenKind == .exclamationMark,
351351
genericParamList: self.generate(genericParameterClause: node.genericParameterClause),
352352
parameterList: self.generate(functionParameterClause: node.signature.parameterClause),
353353
asyncSpecifierLoc: self.generateSourceLoc(node.signature.effectSpecifiers?.asyncSpecifier),
@@ -385,11 +385,11 @@ extension ASTGenVisitor {
385385
// MARK: - OperatorDecl
386386

387387
extension BridgedOperatorFixity {
388-
fileprivate init?(from tokenKind: TokenKind) {
389-
switch tokenKind {
390-
case .keyword(.infix): self = .infix
391-
case .keyword(.prefix): self = .prefix
392-
case .keyword(.postfix): self = .postfix
388+
fileprivate init?(from keyword: Keyword?) {
389+
switch keyword {
390+
case .infix: self = .infix
391+
case .prefix: self = .prefix
392+
case .postfix: self = .postfix
393393
default: return nil
394394
}
395395
}
@@ -402,7 +402,7 @@ extension ASTGenVisitor {
402402
self.generateIdentifierAndSourceLoc(node.operatorPrecedenceAndTypes?.precedenceGroup)
403403

404404
let fixity: BridgedOperatorFixity
405-
if let value = BridgedOperatorFixity(from: node.fixitySpecifier.tokenKind) {
405+
if let value = BridgedOperatorFixity(from: node.fixitySpecifier.keywordKind) {
406406
fixity = value
407407
} else {
408408
fixity = .infix
@@ -428,11 +428,11 @@ extension ASTGenVisitor {
428428
// MARK: - PrecedenceGroupDecl
429429

430430
extension BridgedAssociativity {
431-
fileprivate init?(from tokenKind: TokenKind) {
432-
switch tokenKind {
433-
case .keyword(.none): self = .none
434-
case .keyword(.left): self = .left
435-
case .keyword(.right): self = .right
431+
fileprivate init?(from keyword: Keyword?) {
432+
switch keyword {
433+
case .none?: self = .none
434+
case .left?: self = .left
435+
case .right?: self = .right
436436
default: return nil
437437
}
438438
}
@@ -459,14 +459,14 @@ extension ASTGenVisitor {
459459
switch element {
460460
case .precedenceGroupRelation(let relation):
461461
let keyword = relation.higherThanOrLowerThanLabel
462-
switch keyword.tokenKind {
463-
case .keyword(.higherThan):
462+
switch keyword.keywordKind {
463+
case .higherThan:
464464
if let current = body.higherThanRelation {
465465
diagnoseDuplicateSyntax(relation, original: current)
466466
} else {
467467
body.higherThanRelation = relation
468468
}
469-
case .keyword(.lowerThan):
469+
case .lowerThan:
470470
if let current = body.lowerThanRelation {
471471
diagnoseDuplicateSyntax(relation, original: current)
472472
} else {
@@ -492,7 +492,7 @@ extension ASTGenVisitor {
492492

493493
let associativityValue: BridgedAssociativity
494494
if let token = body.associativity?.value {
495-
if let value = BridgedAssociativity(from: token.tokenKind) {
495+
if let value = BridgedAssociativity(from: token.keywordKind) {
496496
associativityValue = value
497497
} else {
498498
self.diagnose(Diagnostic(node: token, message: UnexpectedTokenKindError(token: token)))
@@ -504,7 +504,7 @@ extension ASTGenVisitor {
504504

505505
let assignmentValue: Bool
506506
if let token = body.assignment?.value {
507-
if token.tokenKind == .keyword(.true) {
507+
if token.keywordKind == .true {
508508
assignmentValue = true
509509
} else {
510510
self.diagnose(Diagnostic(node: token, message: UnexpectedTokenKindError(token: token)))
@@ -538,15 +538,15 @@ extension ASTGenVisitor {
538538
// MARK: - ImportDecl
539539

540540
extension BridgedImportKind {
541-
fileprivate init?(from tokenKind: TokenKind) {
542-
switch tokenKind {
543-
case .keyword(.typealias): self = .type
544-
case .keyword(.struct): self = .struct
545-
case .keyword(.class): self = .class
546-
case .keyword(.enum): self = .enum
547-
case .keyword(.protocol): self = .protocol
548-
case .keyword(.var), .keyword(.let): self = .var
549-
case .keyword(.func): self = .func
541+
fileprivate init?(from keyword: Keyword?) {
542+
switch keyword {
543+
case .typealias: self = .type
544+
case .struct: self = .struct
545+
case .class: self = .class
546+
case .enum: self = .enum
547+
case .protocol: self = .protocol
548+
case .var, .let: self = .var
549+
case .func: self = .func
550550
default: return nil
551551
}
552552
}
@@ -556,7 +556,7 @@ extension ASTGenVisitor {
556556
func generate(importDecl node: ImportDeclSyntax) -> BridgedImportDecl {
557557
let importKind: BridgedImportKind
558558
if let specifier = node.importKindSpecifier {
559-
if let value = BridgedImportKind(from: specifier.tokenKind) {
559+
if let value = BridgedImportKind(from: specifier.keywordKind) {
560560
importKind = value
561561
} else {
562562
self.diagnose(Diagnostic(node: specifier, message: UnexpectedTokenKindError(token: specifier)))

lib/ASTGen/Sources/ASTGen/Exprs.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,12 +292,12 @@ extension ASTGenVisitor {
292292

293293
private func createDeclNameRef(declReferenceExpr node: DeclReferenceExprSyntax) -> (name: BridgedDeclNameRef, loc: BridgedDeclNameLoc) {
294294
let baseName: BridgedDeclBaseName
295-
switch node.baseName.tokenKind {
296-
case .keyword(.`init`):
295+
switch node.baseName.keywordKind {
296+
case .`init`:
297297
baseName = .createConstructor()
298-
case .keyword(.deinit):
298+
case .deinit:
299299
baseName = .createDestructor()
300-
case .keyword(.subscript):
300+
case .subscript:
301301
baseName = .createSubscript()
302302
default:
303303
baseName = .createIdentifier(self.generateIdentifier(node.baseName))

lib/ASTGen/Sources/ASTGen/Literals.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ extension ASTGenVisitor {
3939
}
4040

4141
func generate(booleanLiteralExpr node: BooleanLiteralExprSyntax) -> BridgedBooleanLiteralExpr {
42-
let value = node.literal.tokenKind == .keyword(.true)
42+
let value = node.literal.keywordKind == .true
4343
return .createParsed(
4444
ctx,
4545
value: value,

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,15 @@ extension ASTGenVisitor {
320320
// MARK: - SpecifierTypeRepr/AttributedTypeRepr
321321

322322
extension BridgedAttributedTypeSpecifier {
323-
fileprivate init?(from tokenKind: TokenKind) {
324-
switch tokenKind {
325-
case .keyword(.inout): self = .inOut
326-
case .keyword(.borrowing): self = .borrowing
327-
case .keyword(.consuming): self = .consuming
328-
case .keyword(.__shared): self = .legacyShared
329-
case .keyword(.__owned): self = .legacyOwned
330-
case .keyword(._const): self = .const
331-
case .keyword(.isolated): self = .isolated
323+
fileprivate init?(from keyword: Keyword?) {
324+
switch keyword {
325+
case .inout: self = .inOut
326+
case .borrowing: self = .borrowing
327+
case .consuming: self = .consuming
328+
case .__shared: self = .legacyShared
329+
case .__owned: self = .legacyOwned
330+
case ._const: self = .const
331+
case .isolated: self = .isolated
332332
default: return nil
333333
}
334334
}
@@ -340,7 +340,7 @@ extension ASTGenVisitor {
340340

341341
// Handle specifiers.
342342
if let specifier = node.specifier {
343-
if let kind = BridgedAttributedTypeSpecifier(from: specifier.tokenKind) {
343+
if let kind = BridgedAttributedTypeSpecifier(from: specifier.keywordKind) {
344344
type = BridgedSpecifierTypeRepr.createParsed(
345345
self.ctx,
346346
base: type,

0 commit comments

Comments
 (0)