@@ -14,7 +14,7 @@ import ASTBridging
1414import BasicBridging
1515import SwiftIfConfig
1616// Needed to use BumpPtrAllocator
17- @_spi ( BumpPtrAllocator) @_spi ( RawSyntax) @_spi ( Compiler) import SwiftSyntax
17+ @_spi ( BumpPtrAllocator) @_spi ( ExperimentalLanguageFeatures ) @ _spi ( RawSyntax) @_spi ( Compiler) import SwiftSyntax
1818
1919import struct SwiftDiagnostics. Diagnostic
2020
@@ -205,7 +205,8 @@ extension ASTGenVisitor {
205205 /// source buffer.
206206 @inline ( __always)
207207 func generateSourceLoc( _ node: some SyntaxProtocol ) -> SourceLoc {
208- SourceLoc ( at: node. positionAfterSkippingLeadingTrivia, in: self . base)
208+ precondition ( node. positionAfterSkippingLeadingTrivia. utf8Offset < 0x0000000100000000 )
209+ return SourceLoc ( at: node. positionAfterSkippingLeadingTrivia, in: self . base)
209210 }
210211
211212 /// Obtains the C++ start location of the node excluding leading trivia in the
@@ -247,6 +248,91 @@ extension ASTGenVisitor {
247248 )
248249 }
249250
251+ /// Obtains the bridged declaration based name and bridged source location from a token.
252+ func generateDeclBaseName( _ token: TokenSyntax ) -> ( baseName: DeclBaseName , sourceLoc: SourceLoc ) {
253+ let baseName : DeclBaseName
254+ switch token. keywordKind {
255+ case . `init`:
256+ baseName = . createConstructor( )
257+ case . deinit:
258+ baseName = . createDestructor( )
259+ case . subscript:
260+ baseName = . createSubscript( )
261+ default :
262+ baseName = . init( self . generateIdentifier ( token) )
263+ }
264+ let baseNameLoc = self . generateSourceLoc ( token)
265+ return ( baseName, baseNameLoc)
266+ }
267+
268+ /// Obtains the bridged module name and bridged source location from a module selector.
269+ func generateModuleSelector( _ node: ModuleSelectorSyntax ? ) -> ( moduleName: Identifier , sourceLoc: SourceLoc ) {
270+ let moduleName = self . self. generateIdentifierAndSourceLoc ( node? . moduleName)
271+ return ( moduleName: moduleName. identifier, sourceLoc: moduleName. sourceLoc)
272+ }
273+
274+ func generateDeclNameRef(
275+ moduleSelector: ModuleSelectorSyntax ? ,
276+ baseName: TokenSyntax ,
277+ arguments: (
278+ leftParen: TokenSyntax ,
279+ labels: some Collection < TokenSyntax > ,
280+ rightParen: TokenSyntax
281+ ) ? = Optional< ( leftParen: TokenSyntax, labels: [ TokenSyntax] , rightParen: TokenSyntax) > . none
282+ ) -> ( name: BridgedDeclNameRef , loc: BridgedDeclNameLoc ) {
283+ let moduleSelectorLoc = self . generateModuleSelector ( moduleSelector)
284+ let baseNameLoc = self . generateDeclBaseName ( baseName)
285+
286+ // Create the name itself.
287+ let nameRef : BridgedDeclNameRef
288+ if let arguments {
289+ let bridgedLabels : BridgedArrayRef
290+ if arguments. labels. isEmpty {
291+ bridgedLabels = BridgedArrayRef ( )
292+ } else {
293+ let labels = arguments. labels. lazy. map {
294+ self . generateIdentifier ( $0)
295+ }
296+ bridgedLabels = labels. bridgedArray ( in: self )
297+ }
298+ nameRef = . createParsed(
299+ self . ctx,
300+ moduleSelector: moduleSelectorLoc. moduleName,
301+ baseName: baseNameLoc. baseName,
302+ argumentLabels: bridgedLabels
303+ )
304+ } else {
305+ nameRef = . createParsed( self . ctx, moduleSelector: moduleSelectorLoc. moduleName, baseName: baseNameLoc. baseName)
306+ }
307+
308+ // Create the location. Complication: if the argument list has no labels, the paren locs aren't provided either.
309+ // FIXME: This is silly but I'm pretty sure it's load-bearing.
310+ let nameLoc : BridgedDeclNameLoc
311+ if let arguments, !arguments. labels. isEmpty {
312+ let labelLocs = arguments. labels. lazy. map {
313+ self . generateSourceLoc ( $0)
314+ }
315+ let bridgedLabelLocs = labelLocs. bridgedArray ( in: self )
316+
317+ nameLoc = . createParsed(
318+ self . ctx,
319+ moduleSelectorLoc: moduleSelectorLoc. sourceLoc,
320+ baseNameLoc: baseNameLoc. sourceLoc,
321+ lParenLoc: self . generateSourceLoc ( arguments. leftParen) ,
322+ argumentLabelLocs: bridgedLabelLocs,
323+ rParenLoc: self . generateSourceLoc ( arguments. rightParen)
324+ )
325+ } else {
326+ nameLoc = . createParsed(
327+ self . ctx,
328+ moduleSelectorLoc: moduleSelectorLoc. sourceLoc,
329+ baseNameLoc: baseNameLoc. sourceLoc
330+ )
331+ }
332+
333+ return ( name: nameRef, loc: nameLoc)
334+ }
335+
250336 /// Obtains a C++ source range from a pair of token nodes.
251337 @inline ( __always)
252338 func generateSourceRange( start: TokenSyntax , end: TokenSyntax ) -> SourceRange {
0 commit comments