From 75333d8d719b29760de24e4afd6794cc77221d11 Mon Sep 17 00:00:00 2001 From: Iceman Date: Tue, 12 May 2026 17:51:16 +0900 Subject: [PATCH 1/2] Make SwiftNominalType.genericArguments as not null --- ...MSwift2JavaGenerator+JavaTranslation.swift | 4 ++-- ...ISwift2JavaGenerator+JavaTranslation.swift | 12 +++++----- .../Swift2JavaTranslator.swift | 6 ++--- .../SwiftTypes/SwiftType.swift | 24 +++++++++---------- .../TypealiasResolutionTests.swift | 10 ++++---- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift b/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift index c7347d53b..2686366ed 100644 --- a/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift +++ b/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift @@ -476,7 +476,7 @@ extension FFMSwift2JavaGenerator { } // Generic types are not supported yet. - guard swiftNominalType.genericArguments == nil else { + guard swiftNominalType.genericArguments.isEmpty else { throw JavaTranslationError.unhandledType(swiftType) } @@ -821,7 +821,7 @@ extension FFMSwift2JavaGenerator { } // Generic types are not supported yet. - guard swiftNominalType.genericArguments == nil else { + guard swiftNominalType.genericArguments.isEmpty else { throw JavaTranslationError.unhandledType(swiftType) } diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift index 3cff487af..1045bb3fc 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift @@ -481,13 +481,13 @@ extension JNISwift2JavaGenerator { let javaType = JavaType.class( package: moduleJavaPackages[nominalType.nominalTypeDecl.moduleName], name: nominalTypeName, - typeParameters: try nominalType.genericArguments?.map { swiftType in + typeParameters: try nominalType.genericArguments.map { swiftType in try translateGenericTypeParameter( swiftType, genericParameters: genericParameters, genericRequirements: genericRequirements, ) - } ?? [], + }, ) // We assume this is a JExtract class. @@ -918,13 +918,13 @@ extension JNISwift2JavaGenerator { let javaType = JavaType.class( package: moduleJavaPackages[nominalType.nominalTypeDecl.moduleName], name: nominalType.nominalTypeDecl.qualifiedName, - typeParameters: try nominalType.genericArguments?.map { swiftType in + typeParameters: try nominalType.genericArguments.map { swiftType in try translateGenericTypeParameter( swiftType, genericParameters: genericParameters, genericRequirements: genericRequirements, ) - } ?? [], + }, ) // We assume this is a JExtract class. @@ -1062,13 +1062,13 @@ extension JNISwift2JavaGenerator { // We assume this is a JExtract class. let typeParameters = - try nominalType.genericArguments?.map { swiftType in + try nominalType.genericArguments.map { swiftType in try translateGenericTypeParameter( swiftType, genericParameters: genericParameters, genericRequirements: genericRequirements, ) - } ?? [] + } return .class( package: moduleJavaPackages[nominalType.nominalTypeDecl.moduleName], diff --git a/Sources/JExtractSwiftLib/Swift2JavaTranslator.swift b/Sources/JExtractSwiftLib/Swift2JavaTranslator.swift index 7455bab6c..cb58e819e 100644 --- a/Sources/JExtractSwiftLib/Swift2JavaTranslator.swift +++ b/Sources/JExtractSwiftLib/Swift2JavaTranslator.swift @@ -181,10 +181,8 @@ extension Swift2JavaTranslator { func check(_ type: SwiftType) -> Bool { switch type { case .nominal(let nominal): - if let genericArguments = nominal.genericArguments { - if genericArguments.contains(where: check) { - return true - } + if nominal.genericArguments.contains(where: check) { + return true } return predicate(nominal.nominalTypeDecl) case .tuple(let tuple): diff --git a/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift b/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift index 97e2bf5fa..9f676556f 100644 --- a/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift +++ b/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift @@ -200,13 +200,13 @@ struct SwiftNominalType: Equatable { private var storedParent: Parent? var sugarName: SugarName? var nominalTypeDecl: SwiftNominalTypeDeclaration - var genericArguments: [SwiftType]? + var genericArguments: [SwiftType] init( parent: SwiftNominalType? = nil, sugarName: SugarName? = nil, nominalTypeDecl: SwiftNominalTypeDeclaration, - genericArguments: [SwiftType]? = nil + genericArguments: [SwiftType] = [] ) { self.storedParent = parent.map { .nominal($0) } ?? nominalTypeDecl.parent.map { .nominal(SwiftNominalType(nominalTypeDecl: $0)) } @@ -242,15 +242,15 @@ extension SwiftNominalType: CustomStringConvertible { switch sugarName { case .none: resultString += nominalTypeDecl.name - if let genericArguments { + if !genericArguments.isEmpty { resultString += "<\(genericArguments.map(\.description).joined(separator: ", "))>" } case .some(.optional): - resultString += "\(genericArguments![0])?" + resultString += "\(genericArguments[0])?" case .some(.array): - resultString += "[\(genericArguments![0])]" + resultString += "[\(genericArguments[0])]" case .some(.dictionary): - resultString += "[\(genericArguments![0]): \(genericArguments![1])]" + resultString += "[\(genericArguments[0]): \(genericArguments[1])]" } return resultString @@ -345,7 +345,7 @@ extension SwiftType { originalType: type, parent: nil, name: identifierType.name, - genericArguments: genericArgs, + genericArguments: genericArgs ?? [], lookupContext: lookupContext ) @@ -383,7 +383,7 @@ extension SwiftType { originalType: type, parent: parentType, name: memberType.name, - genericArguments: genericArgs, + genericArguments: genericArgs ?? [], lookupContext: lookupContext, module: moduleName ) @@ -433,7 +433,7 @@ extension SwiftType { originalType: TypeSyntax, parent: SwiftType?, name: TokenSyntax, - genericArguments: [SwiftType]?, + genericArguments: [SwiftType], lookupContext: SwiftTypeLookupContext, module: String? = nil ) throws { @@ -471,7 +471,7 @@ extension SwiftType { } else if let aliasDecl = typeDecl as? SwiftTypeAliasDeclaration { let aliasGenericParams = aliasDecl.syntax.genericParameterClause?.parameters.map { $0.name.text } ?? [] - let useSiteArgs = genericArguments ?? [] + let useSiteArgs = genericArguments // The alias's generic parameter count must match the use-site argument // count. Treat any mismatch (including use-site args on a non-generic @@ -514,7 +514,7 @@ extension SwiftType { SwiftNominalType( parent: parent?.asNominalType, nominalTypeDecl: nominalTypeDecl, - genericArguments: nil + genericArguments: [] ) ) } @@ -533,7 +533,7 @@ extension SwiftType { parent: nominal.parent, sugarName: nominal.sugarName, nominalTypeDecl: nominal.nominalTypeDecl, - genericArguments: nominal.genericArguments?.map { + genericArguments: nominal.genericArguments.map { $0.substituting(genericParameters: substitutions) } ) diff --git a/Tests/JExtractSwiftTests/TypealiasResolutionTests.swift b/Tests/JExtractSwiftTests/TypealiasResolutionTests.swift index aca0fbd10..55cabb115 100644 --- a/Tests/JExtractSwiftTests/TypealiasResolutionTests.swift +++ b/Tests/JExtractSwiftTests/TypealiasResolutionTests.swift @@ -126,7 +126,7 @@ struct TypealiasResolutionTests { return } #expect(nominal.nominalTypeDecl.name == "Optional") - let arg0 = try #require(nominal.genericArguments?.first) + let arg0 = try #require(nominal.genericArguments.first) #expect(arg0.description == "Int64", "Expected substituted T to be Int64, got \(arg0)") } @@ -154,7 +154,7 @@ struct TypealiasResolutionTests { return } #expect(nominal.nominalTypeDecl.name == "Dictionary") - let args = try #require(nominal.genericArguments) + let args = nominal.genericArguments #expect(args.count == 2) #expect(args[0].description == "String") #expect(args[1].description == "Int64") @@ -295,7 +295,7 @@ struct TypealiasResolutionTests { return } #expect(nominal.nominalTypeDecl.name == "Optional") - #expect(nominal.genericArguments?.first?.description == "Int64") + #expect(nominal.genericArguments.first?.description == "Int64") } @Test("Typealias to array sugar resolves to an array") @@ -320,7 +320,7 @@ struct TypealiasResolutionTests { return } #expect(nominal.nominalTypeDecl.name == "Array") - #expect(nominal.genericArguments?.first?.description == "Int8") + #expect(nominal.genericArguments.first?.description == "Int8") } // ==== ----------------------------------------------------------------------- @@ -410,7 +410,7 @@ struct TypealiasResolutionTests { return } #expect(nominal.nominalTypeDecl.name == "Optional") - #expect(nominal.genericArguments?.first?.description == "Int64") + #expect(nominal.genericArguments.first?.description == "Int64") } // ==== ----------------------------------------------------------------------- From 30165b8761f38589bce20b2a36054e1d6d5ff56a Mon Sep 17 00:00:00 2001 From: Iceman Date: Wed, 13 May 2026 10:19:37 +0900 Subject: [PATCH 2/2] Fix implicit merge conflicts --- Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift b/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift index 9f676556f..69480ee27 100644 --- a/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift +++ b/Sources/JExtractSwiftLib/SwiftTypes/SwiftType.swift @@ -596,7 +596,7 @@ extension SwiftNominalTypeDeclaration { return SwiftNominalType( parent: parent?.asSwiftNominalType, nominalTypeDecl: self, - genericArguments: genericArguments.isEmpty ? nil : genericArguments + genericArguments: genericArguments ) }