1515import Foundation
1616import JavaTypes
1717import SwiftSyntax
18+ import OrderedCollections
1819
20+ /// Any imported (Swift) declaration
1921protocol ImportedDecl {
2022
2123}
@@ -32,6 +34,7 @@ public struct ImportedNominalType: ImportedDecl {
3234
3335 public var initializers : [ ImportedFunc ] = [ ]
3436 public var methods : [ ImportedFunc ] = [ ]
37+ public var variables : [ ImportedVariable ] = [ ]
3538
3639 public init ( swiftTypeName: String , javaType: JavaType , swiftMangledName: String ? = nil , kind: NominalTypeKind ) {
3740 self . swiftTypeName = swiftTypeName
@@ -195,7 +198,7 @@ public struct ImportedFunc: ImportedDecl, CustomStringConvertible {
195198
196199 public var swiftMangledName : String = " "
197200
198- public var swiftDeclRaw : String ? = nil
201+ public var syntax : String ? = nil
199202
200203 public var isInit : Bool = false
201204
@@ -221,7 +224,153 @@ public struct ImportedFunc: ImportedDecl, CustomStringConvertible {
221224
222225 Swift mangled name:
223226 Imported from:
224- \( swiftDeclRaw ?? " <no swift source> " )
227+ \( syntax? . description ?? " <no swift source> " )
228+ }
229+ """
230+ }
231+ }
232+
233+ public enum VariableAccessorKind {
234+ case get
235+ case set
236+ }
237+
238+ public struct ImportedVariable : ImportedDecl , CustomStringConvertible {
239+ /// If this function/method is member of a class/struct/protocol,
240+ /// this will contain that declaration's imported name.
241+ ///
242+ /// This is necessary when rendering accessor Java code we need the type that "self" is expecting to have.
243+ public var parentName : TranslatedType ?
244+ public var hasParent : Bool { parentName != nil }
245+
246+ /// This is a full name such as "counter".
247+ public var identifier : String
248+
249+ /// Which accessors are we able to expose.
250+ ///
251+ /// Usually this will be all the accessors the variable declares,
252+ /// however if the getter is async or throwing we may not be able to import it
253+ /// (yet), and therefore would skip it from the supported set.
254+ public var supportedAccessorKinds : OrderedSet < VariableAccessorKind > = [ . get, . set]
255+
256+ /// This is the base identifier for the function, e.g., "init" for an
257+ /// initializer or "f" for "f(a:b:)".
258+ public var baseIdentifier : String {
259+ guard let idx = identifier. firstIndex ( of: " ( " ) else {
260+ return identifier
261+ }
262+ return String ( identifier [ ..< idx] )
263+ }
264+
265+ /// A display name to use to refer to the Swift declaration with its
266+ /// enclosing type, if there is one.
267+ public var displayName : String {
268+ if let parentName {
269+ return " \( parentName. swiftTypeName) . \( identifier) "
270+ }
271+
272+ return identifier
273+ }
274+
275+ public var returnType : TranslatedType
276+
277+ /// Synthetic signature of an accessor function of the given kind of this property
278+ public func accessorFunc( kind: VariableAccessorKind ) -> ImportedFunc ? {
279+ guard self . supportedAccessorKinds. contains ( kind) else {
280+ return nil
281+ }
282+
283+ switch kind {
284+ case . set:
285+ let newValueParam : FunctionParameterSyntax = " _ newValue: \( self . returnType. cCompatibleSwiftType) "
286+ var funcDecl = ImportedFunc (
287+ parentName: self . parentName,
288+ identifier: self . identifier,
289+ returnType: TranslatedType . void,
290+ parameters: [ . init( param: newValueParam, type: self . returnType) ] )
291+ funcDecl. swiftMangledName = self . swiftMangledName + " s " // form mangled name of the getter by adding the suffix
292+ return funcDecl
293+
294+ case . get:
295+ var funcDecl = ImportedFunc (
296+ parentName: self . parentName,
297+ identifier: self . identifier,
298+ returnType: self . returnType,
299+ parameters: [ ] )
300+ funcDecl. swiftMangledName = self . swiftMangledName + " g " // form mangled name of the getter by adding the suffix
301+ return funcDecl
302+ }
303+ }
304+
305+ public func effectiveAccessorParameters( _ kind: VariableAccessorKind , selfVariant: SelfParameterVariant ? ) -> [ ImportedParam ] {
306+ var params : [ ImportedParam ] = [ ]
307+
308+ if kind == . set {
309+ let newValueParam : FunctionParameterSyntax = " _ newValue: \( raw: self . returnType. swiftTypeName) "
310+ params. append (
311+ ImportedParam (
312+ param: newValueParam,
313+ type: self . returnType)
314+ )
315+ }
316+
317+ if let parentName {
318+ // Add `self: Self` for method calls on a member
319+ //
320+ // allocating initializer takes a Self.Type instead, but it's also a pointer
321+ switch selfVariant {
322+ case nil , . wrapper:
323+ break
324+
325+ case . pointer:
326+ let selfParam : FunctionParameterSyntax = " self$: $swift_pointer "
327+ params. append (
328+ ImportedParam (
329+ param: selfParam,
330+ type: parentName
331+ )
332+ )
333+
334+ case . memorySegment:
335+ let selfParam : FunctionParameterSyntax = " self$: $java_lang_foreign_MemorySegment "
336+ var parentForSelf = parentName
337+ parentForSelf. javaType = . javaForeignMemorySegment
338+ params. append (
339+ ImportedParam (
340+ param: selfParam,
341+ type: parentForSelf
342+ )
343+ )
344+ }
345+ }
346+
347+ return params
348+ }
349+
350+ public var swiftMangledName : String = " "
351+
352+ public var syntax : VariableDeclSyntax ? = nil
353+
354+ public init (
355+ parentName: TranslatedType ? ,
356+ identifier: String ,
357+ returnType: TranslatedType
358+ ) {
359+ self . parentName = parentName
360+ self . identifier = identifier
361+ self . returnType = returnType
362+ }
363+
364+ public var description : String {
365+ """
366+ ImportedFunc {
367+ mangledName: \( swiftMangledName)
368+ identifier: \( identifier)
369+ returnType: \( returnType)
370+
371+ Swift mangled name:
372+ Imported from:
373+ \( syntax? . description ?? " <no swift source> " )
225374 }
226375 """
227376 }
0 commit comments