From 65a4097308e5f589f5325add16eb26b2a9713934 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 19 Mar 2026 09:30:05 +0900 Subject: [PATCH 1/7] render generic parameter with typealias --- .../JavaClassTranslator.swift | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/Sources/SwiftJavaToolLib/JavaClassTranslator.swift b/Sources/SwiftJavaToolLib/JavaClassTranslator.swift index 48cf33132..d2678281b 100644 --- a/Sources/SwiftJavaToolLib/JavaClassTranslator.swift +++ b/Sources/SwiftJavaToolLib/JavaClassTranslator.swift @@ -112,19 +112,6 @@ struct JavaClassTranslator { swiftTypeName.splitSwiftTypeName().name } - /// The generic parameter clause for the Swift version of the Java class. - var genericParameters: [String] { - if javaTypeParameters.isEmpty { - return [] - } - - let genericParameters = javaTypeParameters.map { param in - "\(param.getName()): AnyJavaObject" - } - - return genericParameters - } - /// Prepare translation for the given Java class (or interface). init(javaClass: JavaClass, translator: JavaTranslator) throws { let fullName = javaClass.getName() @@ -433,8 +420,14 @@ extension JavaClassTranslator { } } + let genericParameterTypeAliases: [DeclSyntax] = javaTypeParameters + .map { param in + let name = TokenSyntax("\(raw: param.getName())") + return DeclSyntax("public typealias \(name) = \(raw: swiftInnermostTypeName)_\(name)") + } + // Collect all of the members of this type. - let members = properties + enumDecls + initializers + instanceMethods + let members = genericParameterTypeAliases + properties + enumDecls + initializers + instanceMethods // Compute the "extends" clause for the superclass (of the struct // formulation) or the inheritance clause (for the class @@ -470,6 +463,9 @@ extension JavaClassTranslator { interfacesStr = ", \(prefix): \(swiftInterfaces.map { "\($0).self" }.joined(separator: ", "))" } + let genericParameters = javaTypeParameters.map { param in + "\(swiftInnermostTypeName)_\(param.getName()): AnyJavaObject" + } let genericParameterClause = if genericParameters.isEmpty { "" @@ -559,7 +555,9 @@ extension JavaClassTranslator { return try renderMethod( method, implementedInSwift: /*FIXME:*/ false, - genericParameters: genericParameters, + genericParameters: javaTypeParameters.map { param in + "\(param.getName()): AnyJavaObject" + }, whereClause: staticMemberWhereClause ) } catch { @@ -578,7 +576,7 @@ extension JavaClassTranslator { // Specify the specialization arguments when needed. let extSpecialization: String - if genericParameters.isEmpty { + if javaTypeParameters.isEmpty { extSpecialization = "<\(swiftTypeName)>" } else { extSpecialization = "" From 4e4cc0d9021d38bffdd522d2c14eaade78b528b1 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 19 Mar 2026 10:21:23 +0900 Subject: [PATCH 2/7] Fix detecting rule of generic parameter in JavaMethod macro --- Sources/SwiftJavaMacros/JavaMethodMacro.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftJavaMacros/JavaMethodMacro.swift b/Sources/SwiftJavaMacros/JavaMethodMacro.swift index 3e685137a..a28e58a55 100644 --- a/Sources/SwiftJavaMacros/JavaMethodMacro.swift +++ b/Sources/SwiftJavaMacros/JavaMethodMacro.swift @@ -207,9 +207,17 @@ extension JavaMethodMacro: BodyMacro { } for contextNode in context.lexicalContext { + guard let enclosingTypeName = contextNode.asProtocol(NamedDeclSyntax.self)?.name else { + continue + } + if let decl = contextNode.asProtocol(WithGenericParametersSyntax.self) { if decl.genericParameterClause?.parameters.contains(where: { - $0.name.text == typeName + if $0.name.text == typeName { + return true + } + /// Generic parameters generated by wrap-java follow this format: `_` + return $0.name.text == "\(enclosingTypeName)_\(typeName)" }) == true { return true } From bf839361665543cadba77148d148f488ad85b81c Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 19 Mar 2026 10:21:34 +0900 Subject: [PATCH 3/7] Fix test fixtures --- .../JavaClassMacroTests.swift | 6 ++++-- .../Java2SwiftTests.swift | 8 ++++---- .../WrapJavaTests/BasicWrapJavaTests.swift | 4 +++- .../GenericsSubstitutionWrapJavaTests.swift | 8 ++++---- .../WrapJavaTests/GenericsWrapJavaTests.swift | 19 +++++++++++++------ 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Tests/SwiftJavaMacrosTests/JavaClassMacroTests.swift b/Tests/SwiftJavaMacrosTests/JavaClassMacroTests.swift index 130c38be4..d64a2fc7b 100644 --- a/Tests/SwiftJavaMacrosTests/JavaClassMacroTests.swift +++ b/Tests/SwiftJavaMacrosTests/JavaClassMacroTests.swift @@ -472,13 +472,15 @@ class JavaKitMacroTests: XCTestCase { assertMacroExpansion( """ @JavaClass("java.util.ArrayList") - open class ArrayList: JavaObject { + open class ArrayList: JavaObject { + public typealias E = ArrayList_E @JavaMethod open func add(_ arg0: E?) -> Bool } """, expandedSource: #""" - open class ArrayList: JavaObject { + open class ArrayList: JavaObject { + public typealias E = ArrayList_E open func add(_ arg0: E?) -> Bool { let arg0$erased = arg0.map { JavaObject(javaHolder: $0.javaHolder) diff --git a/Tests/SwiftJavaToolLibTests/Java2SwiftTests.swift b/Tests/SwiftJavaToolLibTests/Java2SwiftTests.swift index d32c02e79..b9a279022 100644 --- a/Tests/SwiftJavaToolLibTests/Java2SwiftTests.swift +++ b/Tests/SwiftJavaToolLibTests/Java2SwiftTests.swift @@ -71,7 +71,7 @@ class Java2SwiftTests: XCTestCase { "import SwiftJava", """ @JavaClass("java.lang.Class", extends: JavaObject.self) - public struct MyJavaClass { + public struct MyJavaClass { """, """ @JavaStaticMethod @@ -522,7 +522,7 @@ class Java2SwiftTests: XCTestCase { "import SwiftJava", """ @JavaClass("java.util.ArrayDeque", implements: Deque.self) - open class ArrayDeque: JavaObject { + open class ArrayDeque: JavaObject { """, ] ) @@ -541,7 +541,7 @@ class Java2SwiftTests: XCTestCase { "import SwiftJava", """ @JavaInterface("java.util.function.IntFunction") - public struct MyJavaIntFunction { + public struct MyJavaIntFunction { """, """ @JavaMethod(typeErasedResult: "R!") @@ -601,7 +601,7 @@ class Java2SwiftTests: XCTestCase { "import JavaLangReflect", """ @JavaClass("java.lang.reflect.Constructor") - open class Constructor: Executable { + open class Constructor: Executable { """, """ @JavaMethod diff --git a/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift b/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift index 533a82748..d06740f14 100644 --- a/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift +++ b/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift @@ -265,7 +265,9 @@ final class BasicWrapJavaTests: XCTestCase { expectedChunks: [ """ @JavaInterface("com.example.CallMe", extends: BiFunction.self) - public struct CallMe { + public struct CallMe { + public typealias ValueType = CallMe_ValueType + /// Java method `apply`. /// /// ### Java method signature diff --git a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift index 174ef4c66..f705e9394 100644 --- a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift +++ b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift @@ -45,7 +45,7 @@ final class GenericsSubstitutionWrapJavaTests: XCTestCase { expectedChunks: [ """ @JavaInterface("com.example.MyFunction") - public struct MyFunction { + public struct MyFunction { """, """ @JavaMethod(typeErasedResult: "R!") @@ -53,7 +53,7 @@ final class GenericsSubstitutionWrapJavaTests: XCTestCase { """, """ @JavaInterface("com.example.MyUnaryOperator", extends: MyFunction.self) - public struct MyUnaryOperator { + public struct MyUnaryOperator { """, """ @JavaMethod(typeErasedResult: "T!") @@ -87,7 +87,7 @@ final class GenericsSubstitutionWrapJavaTests: XCTestCase { expectedChunks: [ """ @JavaClass("com.example.ClassFunction") - open class ClassFunction: JavaObject { + open class ClassFunction: JavaObject { """, """ @JavaMethod(typeErasedResult: "R!") @@ -95,7 +95,7 @@ final class GenericsSubstitutionWrapJavaTests: XCTestCase { """, """ @JavaClass("com.example.ClassUnaryOperator") - open class ClassUnaryOperator: ClassFunction { + open class ClassUnaryOperator: ClassFunction { """, """ @JavaMethod(typeErasedResult: "T!") diff --git a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift index af36ab6fb..a7423a57c 100644 --- a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift +++ b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift @@ -56,7 +56,7 @@ final class GenericsWrapJavaTests: XCTestCase { """, """ @JavaClass("com.example.Pair") - open class Pair: JavaObject { + open class Pair: JavaObject { """, """ @JavaClass("com.example.ExampleSimpleClass") @@ -142,11 +142,15 @@ final class GenericsWrapJavaTests: XCTestCase { """, """ @JavaClass("com.example.Item") - open class Item: JavaObject { + open class Item: JavaObject { + public typealias T = Item_T """, """ @JavaClass("com.example.Pair") - open class Pair: JavaObject { + open class Pair: JavaObject { + public typealias First = Pair_First + + public typealias Second = Pair_Second """, """ @JavaClass("com.example.ExampleSimpleClass") @@ -374,7 +378,8 @@ final class GenericsWrapJavaTests: XCTestCase { """, """ @JavaClass("com.example.Kappa") - open class Kappa: JavaObject { + open class Kappa: JavaObject { + public typealias T = Kappa_T """, """ @JavaMethod(typeErasedResult: "T!") @@ -406,7 +411,8 @@ final class GenericsWrapJavaTests: XCTestCase { expectedChunks: [ """ @JavaClass("com.example.Optional") - open class Optional: JavaObject { + open class Optional: JavaObject { + public typealias T = Optional_T """, """ extension JavaClass { @@ -551,7 +557,8 @@ final class GenericsWrapJavaTests: XCTestCase { expectedChunks: [ """ @JavaInterface("com.example.Set", extends: Collection.self) - public struct Set { + public struct Set { + public typealias E = Set_E """ ] ) From bb0d3fb3e4ba4a37f7520201ec5bc9c652f640d7 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 19 Mar 2026 10:21:48 +0900 Subject: [PATCH 4/7] Regenerate all java types --- .../JavaLangReflect/generated/Constructor.swift | 4 +++- .../JavaLangReflect/generated/TypeVariable.swift | 4 +++- Sources/JavaStdlib/JavaUtil/generated/ArrayDeque.swift | 4 +++- Sources/JavaStdlib/JavaUtil/generated/ArrayList.swift | 4 +++- Sources/JavaStdlib/JavaUtil/generated/HashMap.swift | 6 +++++- Sources/JavaStdlib/JavaUtil/generated/HashSet.swift | 4 +++- .../JavaStdlib/JavaUtil/generated/JavaDictionary.swift | 6 +++++- Sources/JavaStdlib/JavaUtil/generated/PriorityQueue.swift | 4 +++- Sources/JavaStdlib/JavaUtil/generated/Queue.swift | 4 +++- Sources/JavaStdlib/JavaUtil/generated/Stack.swift | 4 +++- Sources/JavaStdlib/JavaUtil/generated/TreeMap.swift | 6 +++++- Sources/JavaStdlib/JavaUtil/generated/TreeSet.swift | 4 +++- .../JavaUtilFunction/generated/JavaBiConsumer.swift | 6 +++++- .../JavaUtilFunction/generated/JavaBiFunction.swift | 8 +++++++- .../JavaUtilFunction/generated/JavaBiPredicate.swift | 6 +++++- .../JavaUtilFunction/generated/JavaBinaryOperator.swift | 4 +++- .../JavaUtilFunction/generated/JavaConsumer.swift | 4 +++- .../JavaUtilFunction/generated/JavaDoubleFunction.swift | 4 +++- .../JavaUtilFunction/generated/JavaFunction.swift | 6 +++++- .../JavaUtilFunction/generated/JavaIntFunction.swift | 4 +++- .../JavaUtilFunction/generated/JavaLongFunction.swift | 4 +++- .../generated/JavaObjDoubleConsumer.swift | 4 +++- .../JavaUtilFunction/generated/JavaObjIntConsumer.swift | 4 +++- .../JavaUtilFunction/generated/JavaObjLongConsumer.swift | 4 +++- .../JavaUtilFunction/generated/JavaPredicate.swift | 4 +++- .../JavaUtilFunction/generated/JavaSupplier.swift | 4 +++- .../generated/JavaToDoubleBiFunction.swift | 6 +++++- .../JavaUtilFunction/generated/JavaToDoubleFunction.swift | 4 +++- .../JavaUtilFunction/generated/JavaToIntBiFunction.swift | 6 +++++- .../JavaUtilFunction/generated/JavaToIntFunction.swift | 4 +++- .../JavaUtilFunction/generated/JavaToLongBiFunction.swift | 6 +++++- .../JavaUtilFunction/generated/JavaToLongFunction.swift | 4 +++- .../JavaUtilFunction/generated/JavaUnaryOperator.swift | 4 +++- Sources/SwiftJava/generated/Enumeration.swift | 4 +++- Sources/SwiftJava/generated/JavaClass.swift | 4 +++- Sources/SwiftJava/generated/JavaCollection.swift | 4 +++- Sources/SwiftJava/generated/JavaIterator.swift | 4 +++- Sources/SwiftJava/generated/JavaOptional.swift | 4 +++- Sources/SwiftJava/generated/JavaSet.swift | 4 +++- Sources/SwiftJava/generated/List.swift | 4 +++- Sources/SwiftJava/generated/ListIterator.swift | 4 +++- 41 files changed, 145 insertions(+), 41 deletions(-) diff --git a/Sources/JavaStdlib/JavaLangReflect/generated/Constructor.swift b/Sources/JavaStdlib/JavaLangReflect/generated/Constructor.swift index 501309e4a..de9eb5718 100644 --- a/Sources/JavaStdlib/JavaLangReflect/generated/Constructor.swift +++ b/Sources/JavaStdlib/JavaLangReflect/generated/Constructor.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.lang.reflect.Constructor") -open class Constructor: Executable { +open class Constructor: Executable { + public typealias T = Constructor_T + /// Java method `getName`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaLangReflect/generated/TypeVariable.swift b/Sources/JavaStdlib/JavaLangReflect/generated/TypeVariable.swift index a9fe224ed..95d50c877 100644 --- a/Sources/JavaStdlib/JavaLangReflect/generated/TypeVariable.swift +++ b/Sources/JavaStdlib/JavaLangReflect/generated/TypeVariable.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.lang.reflect.TypeVariable", extends: Type.self) -public struct TypeVariable { +public struct TypeVariable { + public typealias D = TypeVariable_D + /// Java method `getGenericDeclaration`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtil/generated/ArrayDeque.swift b/Sources/JavaStdlib/JavaUtil/generated/ArrayDeque.swift index 68f89f7ec..9481a3597 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/ArrayDeque.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/ArrayDeque.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.ArrayDeque") -open class ArrayDeque: JavaObject { +open class ArrayDeque: JavaObject { + public typealias E = ArrayDeque_E + @JavaMethod @_nonoverride public convenience init(_ arg0: Int32, environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/ArrayList.swift b/Sources/JavaStdlib/JavaUtil/generated/ArrayList.swift index 53e6ec0a1..321a52482 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/ArrayList.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/ArrayList.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.ArrayList", implements: List.self, RandomAccess.self) -open class ArrayList: JavaObject { +open class ArrayList: JavaObject { + public typealias E = ArrayList_E + @JavaMethod @_nonoverride public convenience init(_ arg0: JavaCollection?, environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/HashMap.swift b/Sources/JavaStdlib/JavaUtil/generated/HashMap.swift index 55dd125a6..467b55e96 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/HashMap.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/HashMap.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.HashMap") -open class HashMap: JavaObject { +open class HashMap: JavaObject { + public typealias K = HashMap_K + + public typealias V = HashMap_V + @JavaMethod @_nonoverride public convenience init(_ arg0: Int32, environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/HashSet.swift b/Sources/JavaStdlib/JavaUtil/generated/HashSet.swift index d99169961..3fa96dc11 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/HashSet.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/HashSet.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.HashSet", implements: JavaSet.self) -open class HashSet: JavaObject { +open class HashSet: JavaObject { + public typealias E = HashSet_E + @JavaMethod @_nonoverride public convenience init(_ arg0: Int32, environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/JavaDictionary.swift b/Sources/JavaStdlib/JavaUtil/generated/JavaDictionary.swift index 3cf279d63..eb918b8c2 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/JavaDictionary.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/JavaDictionary.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.Dictionary") -open class JavaDictionary: JavaObject { +open class JavaDictionary: JavaObject { + public typealias K = JavaDictionary_K + + public typealias V = JavaDictionary_V + @JavaMethod @_nonoverride public convenience init(environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/PriorityQueue.swift b/Sources/JavaStdlib/JavaUtil/generated/PriorityQueue.swift index 02313144f..eabeca49d 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/PriorityQueue.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/PriorityQueue.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.PriorityQueue") -open class PriorityQueue: JavaObject { +open class PriorityQueue: JavaObject { + public typealias E = PriorityQueue_E + @JavaMethod @_nonoverride public convenience init(_ arg0: PriorityQueue?, environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/Queue.swift b/Sources/JavaStdlib/JavaUtil/generated/Queue.swift index c305724a2..d1c139728 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/Queue.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/Queue.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.Queue", extends: JavaCollection.self) -public struct Queue { +public struct Queue { + public typealias E = Queue_E + /// Java method `remove`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtil/generated/Stack.swift b/Sources/JavaStdlib/JavaUtil/generated/Stack.swift index dddc26665..f8e3c4f26 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/Stack.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/Stack.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.Stack") -open class Stack: JavaObject { +open class Stack: JavaObject { + public typealias E = Stack_E + @JavaMethod @_nonoverride public convenience init(environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/TreeMap.swift b/Sources/JavaStdlib/JavaUtil/generated/TreeMap.swift index 6924f8e01..8176b43bc 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/TreeMap.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/TreeMap.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.TreeMap") -open class TreeMap: JavaObject { +open class TreeMap: JavaObject { + public typealias K = TreeMap_K + + public typealias V = TreeMap_V + @JavaMethod @_nonoverride public convenience init(environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtil/generated/TreeSet.swift b/Sources/JavaStdlib/JavaUtil/generated/TreeSet.swift index 5872610cd..f45f1543d 100644 --- a/Sources/JavaStdlib/JavaUtil/generated/TreeSet.swift +++ b/Sources/JavaStdlib/JavaUtil/generated/TreeSet.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaClass("java.util.TreeSet") -open class TreeSet: JavaObject { +open class TreeSet: JavaObject { + public typealias E = TreeSet_E + @JavaMethod @_nonoverride public convenience init(_ arg0: JavaCollection?, environment: JNIEnvironment? = nil) diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiConsumer.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiConsumer.swift index ea799652a..04d4e104f 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiConsumer.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiConsumer.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.BiConsumer") -public struct JavaBiConsumer { +public struct JavaBiConsumer { + public typealias T = JavaBiConsumer_T + + public typealias U = JavaBiConsumer_U + /// Java method `accept`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiFunction.swift index 4c6117fed..6e1604dd2 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiFunction.swift @@ -3,7 +3,13 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.BiFunction") -public struct JavaBiFunction { +public struct JavaBiFunction { + public typealias T = JavaBiFunction_T + + public typealias U = JavaBiFunction_U + + public typealias R = JavaBiFunction_R + /// Java method `apply`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiPredicate.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiPredicate.swift index cb9d22cde..f4ddd3312 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiPredicate.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBiPredicate.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.BiPredicate") -public struct JavaBiPredicate { +public struct JavaBiPredicate { + public typealias T = JavaBiPredicate_T + + public typealias U = JavaBiPredicate_U + /// Java method `test`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBinaryOperator.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBinaryOperator.swift index f085d61f6..f11d68ddf 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBinaryOperator.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaBinaryOperator.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.BinaryOperator", extends: JavaBiFunction.self) -public struct JavaBinaryOperator { +public struct JavaBinaryOperator { + public typealias T = JavaBinaryOperator_T + /// Java method `apply`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaConsumer.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaConsumer.swift index b7c1a4905..cfcc813b7 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaConsumer.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaConsumer.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.Consumer") -public struct JavaConsumer { +public struct JavaConsumer { + public typealias T = JavaConsumer_T + /// Java method `accept`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaDoubleFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaDoubleFunction.swift index e5c23b216..d956613e5 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaDoubleFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaDoubleFunction.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.DoubleFunction") -public struct JavaDoubleFunction { +public struct JavaDoubleFunction { + public typealias R = JavaDoubleFunction_R + /// Java method `apply`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaFunction.swift index 1f60edbfd..d93fa5aba 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaFunction.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.Function") -public struct JavaFunction { +public struct JavaFunction { + public typealias T = JavaFunction_T + + public typealias R = JavaFunction_R + /// Java method `apply`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaIntFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaIntFunction.swift index 055d879e0..593cbdc3b 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaIntFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaIntFunction.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.IntFunction") -public struct JavaIntFunction { +public struct JavaIntFunction { + public typealias R = JavaIntFunction_R + /// Java method `apply`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaLongFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaLongFunction.swift index 41f01a081..cac467796 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaLongFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaLongFunction.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.LongFunction") -public struct JavaLongFunction { +public struct JavaLongFunction { + public typealias R = JavaLongFunction_R + /// Java method `apply`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjDoubleConsumer.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjDoubleConsumer.swift index cbe1b434e..25a914b8d 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjDoubleConsumer.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjDoubleConsumer.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ObjDoubleConsumer") -public struct JavaObjDoubleConsumer { +public struct JavaObjDoubleConsumer { + public typealias T = JavaObjDoubleConsumer_T + /// Java method `accept`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjIntConsumer.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjIntConsumer.swift index 330cf66d4..5c0fb4ea4 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjIntConsumer.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjIntConsumer.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ObjIntConsumer") -public struct JavaObjIntConsumer { +public struct JavaObjIntConsumer { + public typealias T = JavaObjIntConsumer_T + /// Java method `accept`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjLongConsumer.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjLongConsumer.swift index 4489888c4..459ad46a9 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjLongConsumer.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaObjLongConsumer.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ObjLongConsumer") -public struct JavaObjLongConsumer { +public struct JavaObjLongConsumer { + public typealias T = JavaObjLongConsumer_T + /// Java method `accept`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaPredicate.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaPredicate.swift index 6c3206a15..c0c688f25 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaPredicate.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaPredicate.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.Predicate") -public struct JavaPredicate { +public struct JavaPredicate { + public typealias T = JavaPredicate_T + /// Java method `test`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaSupplier.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaSupplier.swift index 00ee8e564..10297dd7b 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaSupplier.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaSupplier.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.Supplier") -public struct JavaSupplier { +public struct JavaSupplier { + public typealias T = JavaSupplier_T + /// Java method `get`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleBiFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleBiFunction.swift index e9333096f..d2f14bb48 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleBiFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleBiFunction.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ToDoubleBiFunction") -public struct JavaToDoubleBiFunction { +public struct JavaToDoubleBiFunction { + public typealias T = JavaToDoubleBiFunction_T + + public typealias U = JavaToDoubleBiFunction_U + /// Java method `applyAsDouble`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleFunction.swift index e68b50d4b..8d1c0a204 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToDoubleFunction.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ToDoubleFunction") -public struct JavaToDoubleFunction { +public struct JavaToDoubleFunction { + public typealias T = JavaToDoubleFunction_T + /// Java method `applyAsDouble`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntBiFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntBiFunction.swift index 2584e971b..e9f5079d0 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntBiFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntBiFunction.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ToIntBiFunction") -public struct JavaToIntBiFunction { +public struct JavaToIntBiFunction { + public typealias T = JavaToIntBiFunction_T + + public typealias U = JavaToIntBiFunction_U + /// Java method `applyAsInt`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntFunction.swift index fa7030850..3d04c59f2 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToIntFunction.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ToIntFunction") -public struct JavaToIntFunction { +public struct JavaToIntFunction { + public typealias T = JavaToIntFunction_T + /// Java method `applyAsInt`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongBiFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongBiFunction.swift index bf0ed0302..e2d4ce1cb 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongBiFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongBiFunction.swift @@ -3,7 +3,11 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ToLongBiFunction") -public struct JavaToLongBiFunction { +public struct JavaToLongBiFunction { + public typealias T = JavaToLongBiFunction_T + + public typealias U = JavaToLongBiFunction_U + /// Java method `applyAsLong`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongFunction.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongFunction.swift index ac235d606..07d068b33 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongFunction.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaToLongFunction.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.ToLongFunction") -public struct JavaToLongFunction { +public struct JavaToLongFunction { + public typealias T = JavaToLongFunction_T + /// Java method `applyAsLong`. /// /// ### Java method signature diff --git a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaUnaryOperator.swift b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaUnaryOperator.swift index d674ead5d..63133f6e7 100644 --- a/Sources/JavaStdlib/JavaUtilFunction/generated/JavaUnaryOperator.swift +++ b/Sources/JavaStdlib/JavaUtilFunction/generated/JavaUnaryOperator.swift @@ -3,7 +3,9 @@ import SwiftJava import SwiftJavaJNICore @JavaInterface("java.util.function.UnaryOperator", extends: JavaFunction.self) -public struct JavaUnaryOperator { +public struct JavaUnaryOperator { + public typealias T = JavaUnaryOperator_T + /// Java method `apply`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/Enumeration.swift b/Sources/SwiftJava/generated/Enumeration.swift index 6df84cefd..a46b12132 100644 --- a/Sources/SwiftJava/generated/Enumeration.swift +++ b/Sources/SwiftJava/generated/Enumeration.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaInterface("java.util.Enumeration") -public struct Enumeration { +public struct Enumeration { + public typealias E = Enumeration_E + /// Java method `asIterator`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/JavaClass.swift b/Sources/SwiftJava/generated/JavaClass.swift index 851441624..7d666cde2 100644 --- a/Sources/SwiftJava/generated/JavaClass.swift +++ b/Sources/SwiftJava/generated/JavaClass.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaClass("java.lang.Class") -open class JavaClass: JavaObject { +open class JavaClass: JavaObject { + public typealias T = JavaClass_T + /// Java method `getName`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/JavaCollection.swift b/Sources/SwiftJava/generated/JavaCollection.swift index 2901c1cb8..6571af561 100644 --- a/Sources/SwiftJava/generated/JavaCollection.swift +++ b/Sources/SwiftJava/generated/JavaCollection.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaInterface("java.util.Collection") -public struct JavaCollection { +public struct JavaCollection { + public typealias E = JavaCollection_E + /// Java method `remove`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/JavaIterator.swift b/Sources/SwiftJava/generated/JavaIterator.swift index b0458837d..6e0a99b50 100644 --- a/Sources/SwiftJava/generated/JavaIterator.swift +++ b/Sources/SwiftJava/generated/JavaIterator.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaInterface("java.util.Iterator") -public struct JavaIterator { +public struct JavaIterator { + public typealias E = JavaIterator_E + /// Java method `remove`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/JavaOptional.swift b/Sources/SwiftJava/generated/JavaOptional.swift index 1726fbc57..1738c5527 100644 --- a/Sources/SwiftJava/generated/JavaOptional.swift +++ b/Sources/SwiftJava/generated/JavaOptional.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaClass("java.util.Optional") -open class JavaOptional: JavaObject { +open class JavaOptional: JavaObject { + public typealias T = JavaOptional_T + /// Java method `get`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/JavaSet.swift b/Sources/SwiftJava/generated/JavaSet.swift index d83659144..8ec89becd 100644 --- a/Sources/SwiftJava/generated/JavaSet.swift +++ b/Sources/SwiftJava/generated/JavaSet.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaInterface("java.util.Set", extends: JavaCollection.self) -public struct JavaSet { +public struct JavaSet { + public typealias E = JavaSet_E + /// Java method `remove`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/List.swift b/Sources/SwiftJava/generated/List.swift index 07b7c98c5..4eb9542f5 100644 --- a/Sources/SwiftJava/generated/List.swift +++ b/Sources/SwiftJava/generated/List.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaInterface("java.util.List") -public struct List { +public struct List { + public typealias E = List_E + /// Java method `remove`. /// /// ### Java method signature diff --git a/Sources/SwiftJava/generated/ListIterator.swift b/Sources/SwiftJava/generated/ListIterator.swift index 0445951d6..13e59cd53 100644 --- a/Sources/SwiftJava/generated/ListIterator.swift +++ b/Sources/SwiftJava/generated/ListIterator.swift @@ -2,7 +2,9 @@ import SwiftJavaJNICore @JavaInterface("java.util.ListIterator", extends: JavaIterator.self) -public struct ListIterator { +public struct ListIterator { + public typealias E = ListIterator_E + /// Java method `remove`. /// /// ### Java method signature From b35004a219764515dcfd032d27a011bd435d6e23 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 19 Mar 2026 11:27:47 +0900 Subject: [PATCH 5/7] Add test case to generic super class --- .../WrapJavaTests/GenericsWrapJavaTests.swift | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift index a7423a57c..50d15783a 100644 --- a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift +++ b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift @@ -563,4 +563,33 @@ final class GenericsWrapJavaTests: XCTestCase { ] ) } + + func testWrapJavaGenericSuperClass() async throws { + let classpathURL = try await compileJava( + """ + package com.example; + + abstract class AbstractMap { } + + class TreeMap extends AbstractMap { } + """ + ) + + try assertWrapJavaOutput( + javaClassNames: [ + "com.example.AbstractMap", + "com.example.TreeMap", + ], + classpath: [classpathURL], + expectedChunks: [ + """ + @JavaInterface("com.example.TreeMap") + open class TreeMap: AbstractMap { + public typealias K = TreeMap_K + + public typealias V = TreeMap_V + """ + ] + ) + } } From 178cdd2b160d5300fe2f0accd7c6fd6fd0efbdd1 Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 19 Mar 2026 12:09:22 +0900 Subject: [PATCH 6/7] Care about generic super class --- .../JavaClassTranslator.swift | 28 ++++++++++++------- .../JavaParameterizedType.swift | 4 +-- .../WrapJavaTests/BasicWrapJavaTests.swift | 2 +- .../WrapJavaTests/GenericsWrapJavaTests.swift | 20 ++++++------- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/Sources/SwiftJavaToolLib/JavaClassTranslator.swift b/Sources/SwiftJavaToolLib/JavaClassTranslator.swift index d2678281b..f5578935f 100644 --- a/Sources/SwiftJavaToolLib/JavaClassTranslator.swift +++ b/Sources/SwiftJavaToolLib/JavaClassTranslator.swift @@ -118,39 +118,47 @@ struct JavaClassTranslator { self.javaClass = javaClass self.translator = translator self.translateAsClass = translator.translateAsClass && !javaClass.isInterface() - self.swiftTypeName = try translator.getSwiftTypeNameFromJavaClassName( + let swiftTypeName = try translator.getSwiftTypeNameFromJavaClassName( fullName, preferValueTypes: false, escapeMemberNames: false ) + self.swiftTypeName = swiftTypeName // Type parameters. - self.javaTypeParameters = javaClass.getTypeParameters().compactMap { $0 } + let javaTypeParameters = javaClass.getTypeParameters().compactMap { $0 } + self.javaTypeParameters = javaTypeParameters self.nestedClasses = translator.nestedClasses[fullName] ?? [] // Generic substitution. - self.substitution = SubstitutionMap(startingFrom: javaClass) + let substitution = SubstitutionMap(startingFrom: javaClass) + self.substitution = substitution // Superclass, incl parameter types (if any) if !javaClass.isInterface() { var javaSuperclass = javaClass.getSuperclass() var javaGenericSuperclass: Type? = javaClass.getGenericSuperclass() var swiftSuperclassName: String? = nil - var swiftSuperclassTypeArgs: [String] = [] + var swiftSuperclassTypeArgs: [String]? = nil while let javaSuperclassNonOpt = javaSuperclass { do { swiftSuperclassName = try translator.getSwiftTypeName(javaSuperclassNonOpt, preferValueTypes: false).swiftName - if let javaGenericSuperclass = javaGenericSuperclass?.as(ParameterizedType.self) { - for typeArg in javaGenericSuperclass.getActualTypeArguments() { - let mappedSwiftName = try translator.getSwiftTypeNameAsString( - typeArg!, + swiftSuperclassTypeArgs = try javaGenericSuperclass?.as(ParameterizedType.self)?.getActualTypeArguments() + .compactMap { typeArg in + guard let typeArg else { return nil } + + // When forwarding generics to the superclass + if javaTypeParameters.contains(where: { $0.getName() == typeArg.getTypeName() }) { + return "\(swiftTypeName.splitSwiftTypeName().name)_\(typeArg.getTypeName())" + } + + return try translator.getSwiftTypeNameAsString( + typeArg, substitution: substitution, preferValueTypes: false, outerOptional: .nonoptional ) - swiftSuperclassTypeArgs.append(mappedSwiftName) } - } break } catch { translator.logUntranslated("Unable to translate '\(fullName)' superclass: \(error)") diff --git a/Sources/SwiftJavaToolLib/JavaParameterizedType.swift b/Sources/SwiftJavaToolLib/JavaParameterizedType.swift index b9b980769..4386220b4 100644 --- a/Sources/SwiftJavaToolLib/JavaParameterizedType.swift +++ b/Sources/SwiftJavaToolLib/JavaParameterizedType.swift @@ -17,13 +17,13 @@ struct SwiftJavaParameterizedType { let name: String let typeArguments: [String] - init?(name: String?, typeArguments: [String]) { + init?(name: String?, typeArguments: [String]?) { guard let name else { return nil } self.name = name - self.typeArguments = typeArguments + self.typeArguments = typeArguments ?? [] } func render() -> String { diff --git a/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift b/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift index d06740f14..d2fefc3b8 100644 --- a/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift +++ b/Tests/SwiftJavaToolLibTests/WrapJavaTests/BasicWrapJavaTests.swift @@ -267,7 +267,7 @@ final class BasicWrapJavaTests: XCTestCase { @JavaInterface("com.example.CallMe", extends: BiFunction.self) public struct CallMe { public typealias ValueType = CallMe_ValueType - + /// Java method `apply`. /// /// ### Java method signature diff --git a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift index 50d15783a..b7c5557a3 100644 --- a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift +++ b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsWrapJavaTests.swift @@ -149,7 +149,7 @@ final class GenericsWrapJavaTests: XCTestCase { @JavaClass("com.example.Pair") open class Pair: JavaObject { public typealias First = Pair_First - + public typealias Second = Pair_Second """, """ @@ -568,26 +568,26 @@ final class GenericsWrapJavaTests: XCTestCase { let classpathURL = try await compileJava( """ package com.example; - + + class String {} abstract class AbstractMap { } - - class TreeMap extends AbstractMap { } + + class StringKeyMap extends AbstractMap { } """ ) try assertWrapJavaOutput( javaClassNames: [ + "com.example.String", "com.example.AbstractMap", - "com.example.TreeMap", + "com.example.StringKeyMap", ], classpath: [classpathURL], expectedChunks: [ """ - @JavaInterface("com.example.TreeMap") - open class TreeMap: AbstractMap { - public typealias K = TreeMap_K - - public typealias V = TreeMap_V + @JavaClass("com.example.StringKeyMap") + open class StringKeyMap: AbstractMap { + public typealias V = StringKeyMap_V """ ] ) From 81f696571ed68e418ca1633a40b12d0dd50044db Mon Sep 17 00:00:00 2001 From: Iceman Date: Thu, 19 Mar 2026 12:29:18 +0900 Subject: [PATCH 7/7] Small refactoring and fix test --- .../SwiftJavaToolLib/JavaClassTranslator.swift | 17 ++++++++--------- .../GenericsSubstitutionWrapJavaTests.swift | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Sources/SwiftJavaToolLib/JavaClassTranslator.swift b/Sources/SwiftJavaToolLib/JavaClassTranslator.swift index f5578935f..508e97caa 100644 --- a/Sources/SwiftJavaToolLib/JavaClassTranslator.swift +++ b/Sources/SwiftJavaToolLib/JavaClassTranslator.swift @@ -428,10 +428,12 @@ extension JavaClassTranslator { } } - let genericParameterTypeAliases: [DeclSyntax] = javaTypeParameters - .map { param in - let name = TokenSyntax("\(raw: param.getName())") - return DeclSyntax("public typealias \(name) = \(raw: swiftInnermostTypeName)_\(name)") + let swiftGenericParameterNames = javaTypeParameters.map { param in + "\(swiftInnermostTypeName)_\(param.getName())" + } + let genericParameterTypeAliases: [DeclSyntax] = zip(javaTypeParameters, swiftGenericParameterNames) + .map { javaDecl, swiftName in + DeclSyntax("public typealias \(raw: javaDecl.getName()) = \(raw: swiftName)") } // Collect all of the members of this type. @@ -471,14 +473,11 @@ extension JavaClassTranslator { interfacesStr = ", \(prefix): \(swiftInterfaces.map { "\($0).self" }.joined(separator: ", "))" } - let genericParameters = javaTypeParameters.map { param in - "\(swiftInnermostTypeName)_\(param.getName()): AnyJavaObject" - } let genericParameterClause = - if genericParameters.isEmpty { + if swiftGenericParameterNames.isEmpty { "" } else { - "<\(genericParameters.joined(separator: ", "))>" + "<\(swiftGenericParameterNames.map({ "\($0): AnyJavaObject" }).joined(separator: ", "))>" } // Emit the struct declaration describing the java class. diff --git a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift index f705e9394..d26226862 100644 --- a/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift +++ b/Tests/SwiftJavaToolLibTests/WrapJavaTests/GenericsSubstitutionWrapJavaTests.swift @@ -95,7 +95,7 @@ final class GenericsSubstitutionWrapJavaTests: XCTestCase { """, """ @JavaClass("com.example.ClassUnaryOperator") - open class ClassUnaryOperator: ClassFunction { + open class ClassUnaryOperator: ClassFunction { """, """ @JavaMethod(typeErasedResult: "T!")