Skip to content

Commit c99e58f

Browse files
committed
Move more type handling over to TranslatedType so we can centralize there
1 parent a6cf883 commit c99e58f

File tree

8 files changed

+87
-42
lines changed

8 files changed

+87
-42
lines changed

Sources/JExtractSwift/ImportedDecls.swift

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,27 @@ public struct ImportedProtocol: ImportedDecl {
2828
/// Describes a Swift nominal type (e.g., a class, struct, enum) that has been
2929
/// imported and is being translated into Java.
3030
public struct ImportedNominalType: ImportedDecl {
31-
public var name: ImportedTypeName
31+
public let swiftTypeName: String
32+
public let javaType: JavaType
33+
public var swiftMangledName: String?
3234
public var kind: NominalTypeKind
3335

3436
public var initializers: [ImportedFunc] = []
3537
public var methods: [ImportedFunc] = []
3638

37-
public init(name: ImportedTypeName, kind: NominalTypeKind) {
38-
self.name = name
39+
public init(swiftTypeName: String, javaType: JavaType, swiftMangledName: String? = nil, kind: NominalTypeKind) {
40+
self.swiftTypeName = swiftTypeName
41+
self.javaType = javaType
42+
self.swiftMangledName = swiftMangledName
3943
self.kind = kind
4044
}
45+
46+
var importedTypeName: ImportedTypeName {
47+
ImportedTypeName(
48+
swiftTypeName: swiftTypeName,
49+
javaType: javaType
50+
)
51+
}
4152
}
4253

4354
public enum NominalTypeKind {
@@ -172,13 +183,31 @@ public struct ImportedFunc: ImportedDecl, CustomStringConvertible {
172183
case .pointer:
173184
let selfParam: FunctionParameterSyntax = "self$: $swift_pointer"
174185
params.append(
175-
ImportedParam(param: selfParam, type: java_lang_foreign_MemorySegment(swiftTypeName: "Self.self"))
186+
ImportedParam(
187+
param: selfParam,
188+
type: TranslatedType(
189+
cCompatibleConvention: .indirect,
190+
originalSwiftType: "\(raw: parentName.swiftTypeName)",
191+
cCompatibleSwiftType: "UnsafeRawPointer",
192+
cCompatibleJavaMemoryLayout: .memorySegment,
193+
javaType: .javaForeignMemorySegment
194+
).importedTypeName
195+
)
176196
)
177197

178198
case .memorySegment:
179199
let selfParam: FunctionParameterSyntax = "self$: $java_lang_foreign_MemorySegment"
180200
params.append(
181-
ImportedParam(param: selfParam, type: java_lang_foreign_MemorySegment(swiftTypeName: ""))
201+
ImportedParam(
202+
param: selfParam,
203+
type: TranslatedType(
204+
cCompatibleConvention: .indirect,
205+
originalSwiftType: "\(raw: parentName.swiftTypeName)",
206+
cCompatibleSwiftType: "UnsafeRawPointer",
207+
cCompatibleJavaMemoryLayout: .memorySegment,
208+
javaType: .javaForeignMemorySegment
209+
).importedTypeName
210+
)
182211
)
183212

184213
case .wrapper:

Sources/JExtractSwift/JavaTypes.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@
1313

1414
import JavaTypes
1515

16-
func java_lang_foreign_MemorySegment(swiftTypeName: String) -> ImportedTypeName {
17-
ImportedTypeName(
18-
swiftTypeName: swiftTypeName,
19-
javaType: .javaForeignMemorySegment
20-
)
21-
}
22-
2316
extension JavaType {
2417
/// The description of the type java.lang.foreign.MemorySegment.
2518
static var javaForeignMemorySegment: JavaType {

Sources/JExtractSwift/Swift2JavaTranslator+Printing.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extension Swift2JavaTranslator {
2828
var printer = CodePrinter()
2929

3030
for (_, ty) in importedTypes.sorted(by: { (lhs, rhs) in lhs.key < rhs.key }) {
31-
let filename = "\(ty.name.javaClassName!).java"
31+
let filename = "\(ty.javaType).java"
3232
log.info("Printing contents: \(filename)")
3333
printImportedClass(&printer, ty)
3434

@@ -116,7 +116,7 @@ extension Swift2JavaTranslator {
116116
printer.print(
117117
"""
118118
// FIXME: this detecting is somewhat off
119-
public static final String TYPE_METADATA_NAME = "\(decl.name.swiftMangledName)";
119+
public static final String TYPE_METADATA_NAME = "\(decl.swiftMangledName!)";
120120
static final MemorySegment TYPE_METADATA = SwiftKit.getTypeByMangledNameInEnvironment(TYPE_METADATA_NAME);
121121
"""
122122
)
@@ -165,7 +165,7 @@ extension Swift2JavaTranslator {
165165
}
166166

167167
public func printClass(_ printer: inout CodePrinter, _ decl: ImportedNominalType, body: (inout CodePrinter) -> Void) {
168-
printer.printTypeDecl("public final class \(decl.name.javaClassName!)") { printer in
168+
printer.printTypeDecl("public final class \(decl.javaType)") { printer in
169169
// ==== Storage of the class
170170
// FIXME: implement the self storage for the memory address and accessors
171171
printClassSelfProperty(&printer, decl)
@@ -274,7 +274,7 @@ extension Swift2JavaTranslator {
274274
printer.print(
275275
"""
276276
/** Instances are created using static {@code init} methods rather than through the constructor directly. */
277-
private \(decl.name.javaClassName!)(MemorySegment selfMemorySegment) {
277+
private \(decl.javaType)(MemorySegment selfMemorySegment) {
278278
this.selfMemorySegment = selfMemorySegment;
279279
}
280280
"""
@@ -307,7 +307,7 @@ extension Swift2JavaTranslator {
307307
// SWIFT_INT.withName("heapObject"),
308308
// ...
309309
// SWIFT_INT.withName("cap")
310-
).withName("\(decl.name.javaClassName!)"); // TODO: is the name right?
310+
).withName("\(decl.javaType)"); // TODO: is the name right?
311311
312312
/**
313313
* When other types refer to this type, they refer to by a pointer,

Sources/JExtractSwift/Swift2JavaTranslator.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
import Foundation
15+
import JavaTypes
1516
import SwiftBasicFormat
1617
import SwiftParser
1718
import SwiftSyntax
@@ -56,6 +57,15 @@ public final class Swift2JavaTranslator {
5657
// MARK: Analysis
5758

5859
extension Swift2JavaTranslator {
60+
/// The primitive Java type to use for Swift's Int type, which follows the
61+
/// size of a pointer.
62+
///
63+
/// FIXME: Consider whether to extract this information from the Swift
64+
/// interface file, so that it would be 'int' for 32-bit targets or 'long' for
65+
/// 64-bit targets but make the Java code different for the two, vs. adding
66+
/// a checked truncation operation at the Java/Swift board.
67+
var javaPrimitiveForSwiftInt: JavaType { .long }
68+
5969
public func analyze(
6070
swiftInterfacePath: String,
6171
text: String? = nil
@@ -126,11 +136,11 @@ extension Swift2JavaTranslator {
126136

127137
importedTypes = Dictionary(uniqueKeysWithValues: try await importedTypes._mapAsync { (tyName, tyDecl) in
128138
var tyDecl = tyDecl
129-
log.info("Mapping type: \(tyDecl.name)")
139+
log.info("Mapping type: \(tyDecl.swiftTypeName)")
130140

131141
tyDecl = try await dylib.fillInTypeMangledName(tyDecl)
132142

133-
log.info("Mapping members of: \(tyDecl.name)")
143+
log.info("Mapping members of: \(tyDecl.swiftTypeName)")
134144
tyDecl.initializers = try await tyDecl.initializers._mapAsync { initDecl in
135145
dylib.log.logLevel = .trace
136146

Sources/JExtractSwift/Swift2JavaVisitor.swift

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,12 @@ final class Swift2JavaVisitor: SyntaxVisitor {
5757
}
5858

5959
let importedNominal = ImportedNominalType(
60-
name: ImportedTypeName(
61-
swiftTypeName: fullName,
62-
javaType: .class(
63-
package: targetJavaPackage,
64-
name: fullName
65-
),
66-
swiftMangledName: nominal.mangledNameFromComment
60+
swiftTypeName: fullName,
61+
javaType: .class(
62+
package: targetJavaPackage,
63+
name: fullName
6764
),
65+
swiftMangledName: nominal.mangledNameFromComment,
6866
kind: kind
6967
)
7068

@@ -77,7 +75,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
7775
return .skipChildren
7876
}
7977

80-
currentTypeName = importedNominalType.name.swiftTypeName
78+
currentTypeName = importedNominalType.swiftTypeName
8179
return .visitChildren
8280
}
8381

@@ -96,7 +94,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
9694
return .skipChildren
9795
}
9896

99-
currentTypeName = importedNominalType.name.swiftTypeName
97+
currentTypeName = importedNominalType.swiftTypeName
10098
return .visitChildren
10199
}
102100

@@ -149,7 +147,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
149147
let fullName = "\(node.name.text)(\(argumentLabelsStr))"
150148

151149
var funcDecl = ImportedFunc(
152-
parentName: currentTypeName.map { translator.importedTypes[$0] }??.name,
150+
parentName: currentTypeName.map { translator.importedTypes[$0] }??.importedTypeName,
153151
identifier: fullName,
154152
returnType: javaResultType,
155153
parameters: params
@@ -180,7 +178,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
180178
return .skipChildren
181179
}
182180

183-
self.log.info("Import initializer: \(node.kind) \(currentType.name.javaType.description)")
181+
self.log.info("Import initializer: \(node.kind) \(currentType.javaType.description)")
184182
let params: [ImportedParam]
185183
do {
186184
params = try node.signature.parameterClause.parameters.map { param in
@@ -200,9 +198,9 @@ final class Swift2JavaVisitor: SyntaxVisitor {
200198
"init(\(params.compactMap { $0.effectiveName ?? "_" }.joined(separator: ":")))"
201199

202200
var funcDecl = ImportedFunc(
203-
parentName: currentType.name,
201+
parentName: currentType.importedTypeName,
204202
identifier: initIdentifier,
205-
returnType: currentType.name,
203+
returnType: currentType.importedTypeName,
206204
parameters: params
207205
)
208206
funcDecl.isInit = true
@@ -213,7 +211,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
213211
funcDecl.swiftMangledName = mangledName
214212
}
215213

216-
log.info("Record initializer method in \(currentType.name.javaType.description): \(funcDecl.identifier)")
214+
log.info("Record initializer method in \(currentType.javaType.description): \(funcDecl.identifier)")
217215
translator.importedTypes[currentTypeName]!.initializers.append(funcDecl)
218216

219217
return .skipChildren

Sources/JExtractSwift/SwiftDylib.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ package struct SwiftDylib { // FIXME: remove this entire utility; replace with
3333

3434
package func fillInTypeMangledName(_ decl: ImportedNominalType) async throws -> ImportedNominalType {
3535
// TODO: this is hacky, not precise at all and will be removed entirely
36-
guard decl.name.swiftMangledName.isEmpty else {
36+
guard decl.swiftMangledName == nil else {
3737
// it was already processed
3838
return decl
3939
}
4040

4141
var decl = decl
4242
let names = try await nmSymbolNames(grepDemangled: [
43-
decl.name.swiftTypeName,
43+
decl.swiftTypeName,
4444
"type metadata for",
4545
])
4646
if let name = names.first {
47-
log.trace("Selected mangled name for '\(decl.name.javaType.description)': \(name)")
48-
decl.name.swiftMangledName = name.mangledName
47+
log.trace("Selected mangled name for '\(decl.javaType.description)': \(name)")
48+
decl.swiftMangledName = name.mangledName
4949
}
5050

5151
return decl

Sources/JExtractSwift/TranslatedType.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ extension Swift2JavaVisitor {
102102
)
103103
}
104104

105+
// If this is the Swift "Int" type, it's primitive in Java but might
106+
// map to either "int" or "long" depending whether the platform is
107+
// 32-bit or 64-bit.
108+
if parent == nil, name == "Int" {
109+
return TranslatedType(
110+
cCompatibleConvention: .direct,
111+
originalSwiftType: "\(raw: name)",
112+
cCompatibleSwiftType: "Swift.\(raw: name)",
113+
cCompatibleJavaMemoryLayout: .int,
114+
javaType: translator.javaPrimitiveForSwiftInt
115+
)
116+
}
117+
105118
// Identify the various pointer types from the standard library.
106119
if let (requiresArgument, _, _) = name.isNameOfSwiftPointerType {
107120
// Dig out the pointee type if needed.
@@ -220,10 +233,16 @@ extension TranslatedType {
220233
javaType: javaType
221234
)
222235
}
223-
224236
}
237+
225238
enum CCompatibleJavaMemoryLayout {
239+
/// A primitive Java type.
226240
case primitive(JavaType)
241+
242+
/// The Swift "Int" type, which may be either a Java int (32-bit platforms) or
243+
/// Java long (64-bit platforms).
244+
case int
245+
227246
case memorySegment
228247
}
229248

Sources/JavaTypes/JavaType+SwiftNames.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,6 @@ extension JavaType {
6363
case "Float": self = .float
6464
case "Double": self = .double
6565
case "Void": self = .void
66-
67-
/// NOTE: This is only correct for 64-bit platforms.
68-
case "Int": self = .long
69-
7066
default: return nil
7167
}
7268
}

0 commit comments

Comments
 (0)