From e1f00898731d519e3d74640b4d97a02f95ed7394 Mon Sep 17 00:00:00 2001 From: Rintaro Ishizaki Date: Sun, 3 Dec 2023 23:37:45 -0800 Subject: [PATCH] [ASTGen] Start using 'TokenSyntax.rawText' `TokenSyntax.text` causes intiation of heap allocated `Swift.String` for each access. `TokenSyntax.rawText` is faster than that because it's just a reference to the pre-allocated buffer. Also, converting to `BridgedString` is simplar, and guaranteed to be free, unlike bridging via `String.withUTF8(_:)` --- lib/ASTGen/Sources/ASTGen/Bridge.swift | 8 +++++++- lib/ASTGen/Sources/ASTGen/Literals.swift | 3 +++ lib/ASTGen/Sources/ASTGen/Types.swift | 13 +++++-------- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/ASTGen/Sources/ASTGen/Bridge.swift b/lib/ASTGen/Sources/ASTGen/Bridge.swift index 9a198294315b1..d9601d6f8ede0 100644 --- a/lib/ASTGen/Sources/ASTGen/Bridge.swift +++ b/lib/ASTGen/Sources/ASTGen/Bridge.swift @@ -12,7 +12,7 @@ import ASTBridging import BasicBridging -import SwiftSyntax +@_spi(RawSyntax) import SwiftSyntax protocol BridgedNullable: ExpressibleByNilLiteral { associatedtype RawPtr @@ -100,6 +100,12 @@ extension String { } } +extension SyntaxText { + var bridged: BridgedStringRef { + BridgedStringRef(data: self.baseAddress, count: self.count) + } +} + /// Allocate a copy of the given string as a null-terminated UTF-8 string. func allocateBridgedString( _ string: String diff --git a/lib/ASTGen/Sources/ASTGen/Literals.swift b/lib/ASTGen/Sources/ASTGen/Literals.swift index 8a36b7ce8596b..73d3482500d4b 100644 --- a/lib/ASTGen/Sources/ASTGen/Literals.swift +++ b/lib/ASTGen/Sources/ASTGen/Literals.swift @@ -18,6 +18,7 @@ extension ASTGenVisitor { let openDelimiterOrQuoteLoc = (node.openingPounds ?? node.openingQuote).bridgedSourceLoc(in: self) // FIXME: Handle interpolated strings. + // FIXME: Avoid 'String' instantiation var segment = node.segments.first!.as(StringSegmentSyntax.self)!.content.text return segment.withBridgedString { bridgedSegment in return .createParsed(self.ctx, value: bridgedSegment, loc: openDelimiterOrQuoteLoc) @@ -25,6 +26,8 @@ extension ASTGenVisitor { } public func generate(integerLiteralExpr node: IntegerLiteralExprSyntax) -> BridgedIntegerLiteralExpr { + // FIXME: Avoid 'String' instantiation + // FIXME: Strip '_'. var segment = node.literal.text return segment.withBridgedString { bridgedSegment in return .createParsed(ctx, value: bridgedSegment, loc: node.literal.bridgedSourceLoc(in: self)) diff --git a/lib/ASTGen/Sources/ASTGen/Types.swift b/lib/ASTGen/Sources/ASTGen/Types.swift index 4e3e8bee4e2c6..d6e61e1169dc4 100644 --- a/lib/ASTGen/Sources/ASTGen/Types.swift +++ b/lib/ASTGen/Sources/ASTGen/Types.swift @@ -13,7 +13,7 @@ import ASTBridging import BasicBridging import SwiftDiagnostics -@_spi(ExperimentalLanguageFeatures) import SwiftSyntax +@_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax extension EffectSpecifiersSyntax { var thrownError: TypeSyntax? { @@ -203,14 +203,14 @@ extension ASTGenVisitor { public func generate(metatypeType node: MetatypeTypeSyntax) -> BridgedTypeRepr { let baseType = generate(type: node.baseType) let tyLoc = node.metatypeSpecifier.bridgedSourceLoc(in: self) - if node.metatypeSpecifier.text == "Type" { + if node.metatypeSpecifier.rawText == "Type" { return BridgedMetatypeTypeRepr.createParsed( self.ctx, base: baseType, typeKeywordLoc: tyLoc ) } else { - assert(node.metatypeSpecifier.text == "Protocol") + assert(node.metatypeSpecifier.rawText == "Protocol") return BridgedProtocolTypeRepr.createParsed( self.ctx, base: baseType, @@ -298,7 +298,7 @@ extension ASTGenVisitor { public func generate(someOrAnyType node: SomeOrAnyTypeSyntax) -> BridgedTypeRepr { let someOrAnyLoc = node.someOrAnySpecifier.bridgedSourceLoc(in: self) let baseTy = generate(type: node.constraint) - if node.someOrAnySpecifier.text == "some" { + if node.someOrAnySpecifier.rawText == "some" { return BridgedOpaqueReturnTypeRepr.createParsed( self.ctx, someKeywordLoc: someOrAnyLoc, @@ -368,10 +368,7 @@ extension ASTGenVisitor { } let nameSyntax = identType.name - var name = nameSyntax.text - let typeAttrKind = name.withBridgedString { bridgedName in - BridgedTypeAttrKind(from: bridgedName) - } + let typeAttrKind = BridgedTypeAttrKind(from: nameSyntax.rawText.bridged) let atLoc = attribute.atSign.bridgedSourceLoc(in: self) let attrLoc = nameSyntax.bridgedSourceLoc(in: self) switch typeAttrKind {