diff --git a/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/MySwiftLibrary.swift b/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/MySwiftLibrary.swift index e278326e0..b362879fc 100644 --- a/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/MySwiftLibrary.swift +++ b/Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/MySwiftLibrary.swift @@ -52,6 +52,14 @@ public func echoUnsignedInt(i: UInt32, j: UInt64) -> UInt64 { return UInt64(i) + j } +public func returnUnsignedByte(b: UInt8) -> UInt8 { + return b +} + +public func returnLargestUnsignedByte() -> UInt8 { + return UInt8.max +} + // ==== Internal helpers func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) { diff --git a/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MySwiftLibraryTest.java b/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MySwiftLibraryTest.java index 6da2fd4b0..27e1aa95f 100644 --- a/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MySwiftLibraryTest.java +++ b/Samples/SwiftJavaExtractJNISampleApp/src/test/java/com/example/swift/MySwiftLibraryTest.java @@ -68,4 +68,14 @@ void globalUnsignedIntEcho() { long l = 1200; assertEquals(1212, MySwiftLibrary.echoUnsignedInt(12, 1200)); } + + @Test + void returnUnsignedByte_negative() { + assertEquals(-50, MySwiftLibrary.returnUnsignedByte((byte) -50)); + } + + @Test + void returnLargestUnsignedByte() { + assertEquals(-1, MySwiftLibrary.returnLargestUnsignedByte()); + } } \ No newline at end of file diff --git a/Sources/JExtractSwiftLib/Common/TypeAnnotations.swift b/Sources/JExtractSwiftLib/Common/TypeAnnotations.swift index 2cb8a0a1d..ff0d2dde3 100644 --- a/Sources/JExtractSwiftLib/Common/TypeAnnotations.swift +++ b/Sources/JExtractSwiftLib/Common/TypeAnnotations.swift @@ -18,16 +18,12 @@ import SwiftJavaConfigurationShared /// Determine if the given type needs any extra annotations that should be included /// in Java sources when the corresponding Java type is rendered. func getTypeAnnotations(swiftType: SwiftType, config: Configuration) -> [JavaAnnotation] { - if config.effectiveUnsignedNumbersMode == .annotate { - switch swiftType { - case .array(let wrapped) where wrapped.isUnsignedInteger: - return [JavaAnnotation.unsigned] - case _ where swiftType.isUnsignedInteger: - return [JavaAnnotation.unsigned] - default: - break - } + switch swiftType { + case .array(let wrapped) where wrapped.isUnsignedInteger: + return [JavaAnnotation.unsigned] + case _ where swiftType.isUnsignedInteger: + return [JavaAnnotation.unsigned] + default: + return [] } - - return [] } diff --git a/Sources/JExtractSwiftLib/Configuration+Extensions.swift b/Sources/JExtractSwiftLib/Configuration+Extensions.swift deleted file mode 100644 index 042d86100..000000000 --- a/Sources/JExtractSwiftLib/Configuration+Extensions.swift +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2024 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -import SwiftJavaConfigurationShared -import JavaTypes - -extension Configuration { - public var effectiveUnsignedNumericsMode: UnsignedNumericsMode { - switch effectiveUnsignedNumbersMode { - case .annotate: .ignoreSign - case .wrapGuava: .wrapUnsignedGuava - } - } -} \ No newline at end of file diff --git a/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift b/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift index d3a2626bb..da1914d45 100644 --- a/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift +++ b/Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator+JavaTranslation.swift @@ -336,16 +336,6 @@ extension FFMSwift2JavaGenerator { // If the result type should cause any annotations on the method, include them here. let parameterAnnotations: [JavaAnnotation] = getTypeAnnotations(swiftType: swiftType, config: config) - // If we need to handle unsigned integers do so here - if config.effectiveUnsignedNumbersMode.needsConversion { - if let unsignedWrapperType = JavaType.unsignedWrapper(for: swiftType) { - return TranslatedParameter( - javaParameters: [ - JavaParameter(name: parameterName, type: unsignedWrapperType, annotations: parameterAnnotations) - ], conversion: .call(.placeholder, function: "UnsignedNumbers.toPrimitive", withArena: false)) - } - } - // If there is a 1:1 mapping between this Swift type and a C type, that can // be expressed as a Java primitive type. if let cType = try? CType(cdeclType: swiftType) { @@ -593,57 +583,12 @@ extension FFMSwift2JavaGenerator { } } - func unsignedResultConversion(_ from: SwiftType, to javaType: JavaType, - mode: JExtractUnsignedIntegerMode) -> JavaConversionStep { - switch mode { - case .annotate: - return .placeholder // no conversions - - case .wrapGuava: - guard let typeName = javaType.fullyQualifiedClassName else { - fatalError("Missing target class name for result conversion step from \(from) to \(javaType)") - } - - switch from { - case .nominal(let nominal): - switch nominal.nominalTypeDecl.knownTypeKind { - case .uint8: - return .call(.placeholder, function: "\(typeName).fromIntBits", withArena: false) - case .uint16: - return .placeholder // no conversion, UInt16 can be returned as-is and will be seen as char by Java - case .uint32: - return .call(.placeholder, function: "\(typeName).fromIntBits", withArena: false) - case .uint64: - return .call(.placeholder, function: "\(typeName).fromLongBits", withArena: false) - default: - fatalError("unsignedResultConversion: Unsupported conversion from \(from) to \(javaType)") - } - default: - fatalError("unsignedResultConversion: Unsupported conversion from \(from) to \(javaType)") - } - } - } - /// Translate a Swift API result to the user-facing Java API result. func translateResult( swiftResult: SwiftResult, loweredResult: LoweredResult ) throws -> TranslatedResult { let swiftType = swiftResult.type - - // If we need to handle unsigned integers do so here - if config.effectiveUnsignedNumbersMode.needsConversion { - if let unsignedWrapperType = JavaType.unsignedWrapper(for: swiftType) /* and we're in safe wrapper mode */ { - return TranslatedResult( - javaResultType: unsignedWrapperType, - outParameters: [], - conversion: unsignedResultConversion( - swiftType, to: unsignedWrapperType, - mode: self.config.effectiveUnsignedNumbersMode) - ) - } - } - // If the result type should cause any annotations on the method, include them here. let resultAnnotations: [JavaAnnotation] = getTypeAnnotations(swiftType: swiftType, config: config) diff --git a/Sources/JExtractSwiftLib/JNI/JNIJavaTypeTranslator.swift b/Sources/JExtractSwiftLib/JNI/JNIJavaTypeTranslator.swift index 9bd9a7d83..491331bce 100644 --- a/Sources/JExtractSwiftLib/JNI/JNIJavaTypeTranslator.swift +++ b/Sources/JExtractSwiftLib/JNI/JNIJavaTypeTranslator.swift @@ -18,13 +18,6 @@ import SwiftJavaConfigurationShared enum JNIJavaTypeTranslator { static func translate(knownType: SwiftKnownTypeDeclKind, config: Configuration) -> JavaType? { - let unsigned = config.effectiveUnsignedNumbersMode - guard unsigned == .annotate else { - // We do not support wrap mode in JNI mode currently; - // In the future this is where it would be interesting to implement Kotlin UInt support. - return nil - } - switch knownType { case .bool: return .boolean diff --git a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift index 553b3e10b..a9369ccd7 100644 --- a/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift +++ b/Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaTranslation.swift @@ -365,18 +365,6 @@ extension JNISwift2JavaGenerator { // If the result type should cause any annotations on the method, include them here. let parameterAnnotations: [JavaAnnotation] = getTypeAnnotations(swiftType: swiftType, config: config) - // If we need to handle unsigned integers do so here - if config.effectiveUnsignedNumbersMode.needsConversion { - if let unsignedWrapperType = JavaType.unsignedWrapper(for: swiftType) { - return TranslatedParameter( - parameter: JavaParameter(name: parameterName, type: unsignedWrapperType, annotations: parameterAnnotations), - conversion: unsignedResultConversion( - swiftType, to: unsignedWrapperType, - mode: self.config.effectiveUnsignedNumbersMode) - ) - } - } - switch swiftType { case .nominal(let nominalType): let nominalTypeName = nominalType.nominalTypeDecl.qualifiedName @@ -489,20 +477,6 @@ extension JNISwift2JavaGenerator { } } - func unsignedResultConversion( - _ from: SwiftType, - to javaType: JavaType, - mode: JExtractUnsignedIntegerMode - ) -> JavaNativeConversionStep { - switch mode { - case .annotate: - return .placeholder // no conversions - - case .wrapGuava: - fatalError("JExtract in JNI mode does not support the \(JExtractUnsignedIntegerMode.wrapGuava) unsigned numerics mode") - } - } - func convertToAsync( translatedFunctionSignature: inout TranslatedFunctionSignature, nativeFunctionSignature: inout NativeFunctionSignature, diff --git a/Sources/JExtractSwiftLib/JavaTypes/JavaType+SwiftKit.swift b/Sources/JExtractSwiftLib/JavaTypes/JavaType+SwiftKit.swift index 7319b2942..7914761e2 100644 --- a/Sources/JExtractSwiftLib/JavaTypes/JavaType+SwiftKit.swift +++ b/Sources/JExtractSwiftLib/JavaTypes/JavaType+SwiftKit.swift @@ -16,75 +16,6 @@ import JavaTypes extension JavaType { - /// Try to map a Swift type name (e.g., from the module Swift) over to a - /// primitive Java type, or fail otherwise. - public init?(swiftTypeName: String, WHT_unsigned unsigned: UnsignedNumericsMode) { - switch swiftTypeName { - case "Bool": self = .boolean - - case "Int8": self = .byte - case "UInt8": - self = switch unsigned { - case .ignoreSign: .byte - case .wrapUnsignedGuava: JavaType.guava.primitives.UnsignedInteger - } - - case "Int16": self = .short - case "UInt16": self = .char - - case "Int32": self = .int - case "UInt32": - self = switch unsigned { - case .ignoreSign: .int - case .wrapUnsignedGuava: JavaType.guava.primitives.UnsignedInteger - } - - case "Int64": self = .long - case "UInt64": - self = switch unsigned { - case .ignoreSign: .long - case .wrapUnsignedGuava: JavaType.guava.primitives.UnsignedLong - } - - case "Float": self = .float - case "Double": self = .double - case "Void": self = .void - default: return nil - } - } -} - -extension JavaType { - - static func unsignedWrapper(for swiftType: SwiftType) -> JavaType? { - switch swiftType { - case .nominal(let nominal): - switch nominal.nominalTypeDecl.knownTypeKind { - case .uint8: return guava.primitives.UnsignedInteger - case .uint16: return .char // no wrapper necessary, we can express it as 'char' natively in Java - case .uint32: return guava.primitives.UnsignedInteger - case .uint64: return guava.primitives.UnsignedLong - default: return nil - } - default: return nil - } - } - - /// Known types from the Google Guava library - enum guava { - enum primitives { - static let package = "com.google.common.primitives" - - static var UnsignedInteger: JavaType { - .class(package: primitives.package, name: "UnsignedInteger") - } - - static var UnsignedLong: JavaType { - .class(package: primitives.package, name: "UnsignedLong") - } - } - } - /// The description of the type org.swift.swiftkit.core.SimpleCompletableFuture static func simpleCompletableFuture(_ T: JavaType) -> JavaType { .class(package: "org.swift.swiftkit.core", name: "SimpleCompletableFuture", typeParameters: [T.boxedType]) diff --git a/Sources/SwiftJava/BridgedValues/JavaValue+Integers.swift b/Sources/SwiftJava/BridgedValues/JavaValue+Integers.swift index 005753eb6..aed3dd53a 100644 --- a/Sources/SwiftJava/BridgedValues/JavaValue+Integers.swift +++ b/Sources/SwiftJava/BridgedValues/JavaValue+Integers.swift @@ -22,11 +22,11 @@ extension UInt8: JavaValue { public static var javaType: JavaType { .byte } /// Retrieve the JNI value. - public func getJNIValue(in environment: JNIEnvironment) -> JNIType { JNIType(self) } + public func getJNIValue(in environment: JNIEnvironment) -> JNIType { JNIType(bitPattern: self) } /// Initialize from a JNI value. public init(fromJNI value: JNIType, in environment: JNIEnvironment) { - self = Self(value) + self = Self(bitPattern: value) } public static func jniMethodCall( @@ -238,11 +238,11 @@ extension UInt32: JavaValue { public static var javaType: JavaType { .int } /// Retrieve the JNI value. - public func getJNIValue(in environment: JNIEnvironment) -> JNIType { JNIType(self) } + public func getJNIValue(in environment: JNIEnvironment) -> JNIType { JNIType(bitPattern: self) } /// Initialize from a JNI value. public init(fromJNI value: JNIType, in environment: JNIEnvironment) { - self = Self(value) + self = Self(bitPattern: value) } public static func jniMethodCall( @@ -353,10 +353,36 @@ extension UInt64: JavaValue { public static var jvalueKeyPath: WritableKeyPath { \.j } - public func getJNIValue(in environment: JNIEnvironment) -> JNIType { JNIType(self) } + public func getJNIValue(in environment: JNIEnvironment) -> JNIType { + // `jlong` is always 64-bit, no matter the system pointer size. + // Due to differences in JNI headers between Android, JDK and how Swift sees these type imports + // we have to handle this a bit differently. + // + // On 32-bit, the standard JDK jlong is defined in C as `long long`, which yields Swift `Int64` + // On 64-bit, the standard JDK jlong is defined in C as `long`, which yields Swift `Int` + // On Android it's correctly marked as int64_t, always yielding `Int64` in Swift. + #if os(Android) || _pointerBitWidth(_32) + return Int64(bitPattern: self) + #else + return Int(bitPattern: UInt(self)) + #endif + } public init(fromJNI value: JNIType, in environment: JNIEnvironment) { - self = UInt64(value) + // `jlong` is always 64-bit, no matter the system pointer size. + // Due to differences in JNI headers between Android, JDK and how Swift sees these type imports + // we have to handle this a bit differently. + // + // On 32-bit, the standard JDK jlong is defined in C as `long long`, which yields Swift `Int64` + // On 64-bit, the standard JDK jlong is defined in C as `long`, which yields Swift `Int` + // On Android it's correctly marked as int64_t, always yielding `Int64` in Swift. + #if os(Android) || _pointerBitWidth(_32) + // In this case `jlong` is seen in Swift as `Int64`. + self = UInt64(bitPattern: value) + #else + // In this case `jlong` is since as just `Int`, which is always Int64 + self = UInt64(bitPattern: Int64(value)) + #endif } public static var javaType: JavaType { .long } diff --git a/Sources/SwiftJavaConfigurationShared/Configuration.swift b/Sources/SwiftJavaConfigurationShared/Configuration.swift index 6e3e2a52b..93ee97bf0 100644 --- a/Sources/SwiftJavaConfigurationShared/Configuration.swift +++ b/Sources/SwiftJavaConfigurationShared/Configuration.swift @@ -45,11 +45,6 @@ public struct Configuration: Codable { public var writeEmptyFiles: Bool? // FIXME: default it to false, but that plays not nice with Codable - public var unsignedNumbersMode: JExtractUnsignedIntegerMode? - public var effectiveUnsignedNumbersMode: JExtractUnsignedIntegerMode { - unsignedNumbersMode ?? .default - } - public var minimumInputAccessLevelMode: JExtractMinimumAccessLevelMode? public var effectiveMinimumInputAccessLevelMode: JExtractMinimumAccessLevelMode { minimumInputAccessLevelMode ?? .default diff --git a/Sources/SwiftJavaConfigurationShared/JExtract/JExtractUnsignedIntegerMode.swift b/Sources/SwiftJavaConfigurationShared/JExtract/JExtractUnsignedIntegerMode.swift deleted file mode 100644 index b53a2c6b7..000000000 --- a/Sources/SwiftJavaConfigurationShared/JExtract/JExtractUnsignedIntegerMode.swift +++ /dev/null @@ -1,56 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the Swift.org open source project -// -// Copyright (c) 2025 Apple Inc. and the Swift.org project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of Swift.org project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -/// Configures how Swift unsigned integers should be extracted by jextract. -public enum JExtractUnsignedIntegerMode: String, Codable { - /// Treat unsigned Swift integers as their signed equivalents in Java signatures, - /// however annotate them using the `@Unsigned` annotation which serves as a hint - /// to users of APIs with unsigned integers that a given parameter or return type - /// is actually unsigned, and must be treated carefully. - /// - /// Specifically negative values of a `@Unchecked long` must be interpreted carefully as - /// a value larger than the Long.MAX_VALUE can represent in Java. - case annotate - - /// Wrap any unsigned Swift integer values in an explicit `Unsigned...` wrapper types. - /// - /// This mode trades off performance, due to needing to allocate the type-safe wrapper objects around - /// primitive values, however allows to retain static type information about the unsignedness of - /// unsigned number types in the Java side of generated bindings. - case wrapGuava - -// /// If possible, use a wider Java signed integer type to represent an Unsigned Swift integer type. -// /// For example, represent a Swift `UInt32` (width equivalent to Java `int`) as a Java signed `long`, -// /// because UInt32's max value is possible to be stored in a signed Java long (64bit). -// /// -// /// Since it is not possible to widen a value beyond 64bits (Java `long`), the Long type would be wrapped -// case widenOrWrap -// -// /// Similar to `widenOrWrap`, however instead of wrapping `UInt64` as an `UnsignedLong` in Java, -// /// only annotate it as `@Unsigned long`. -// case widenOrAnnotate -} - - -extension JExtractUnsignedIntegerMode { - public var needsConversion: Bool { - switch self { - case .annotate: false - case .wrapGuava: true - } - } - - public static var `default`: Self { - .annotate - } -} diff --git a/Sources/SwiftJavaDocumentation/Documentation.docc/SupportedFeatures.md b/Sources/SwiftJavaDocumentation/Documentation.docc/SupportedFeatures.md index 7161a26c9..370f33925 100644 --- a/Sources/SwiftJavaDocumentation/Documentation.docc/SupportedFeatures.md +++ b/Sources/SwiftJavaDocumentation/Documentation.docc/SupportedFeatures.md @@ -116,8 +116,6 @@ as their bit-width equivalents. This is potentially dangerous because values lar *signed* type in Java, e.g. `200` stored in an `UInt8` in Swift, would be interpreted as a `byte` of value `-56`, because Java's `byte` type is _signed_. -#### Unsigned numbers mode: annotate (default) - Because in many situations the data represented by such numbers is merely passed along, and not interpreted by Java, this may be safe to pass along. However, interpreting unsigned values incorrectly like this can lead to subtle mistakes on the Java side. @@ -135,35 +133,6 @@ on the Java side. | `Float` | `float` | | `Double` | `double` | -#### Unsigned numbers mode: wrapGuava - -You can configure `jextract` (in FFM mode) to instead import unsigned values as their unsigned type-safe representations -as offered by the Guava library: `UnsignedLong` or `UnsignedInt`. To enable this mode pass the `--unsigned-numbers-mode wrapGuava` -command line option, or set the corresponding configuration value in `swift-java.config` (TODO). - -This approach is type-safe, however it incurs a performance penalty for allocating a wrapper class for every -unsigned integer parameter passed to and from native Swift functions. - -SwiftJava _does not_ vendor or provide the Guava library as a dependency, and when using this mode -you are expected to add a Guava dependency to your Java project. - -> You can read more about the unsigned integers support - -| Swift type | Java type | -|------------|--------------------------------------------------------| -| `Int8` | `byte` | -| `UInt8` | `com.google.common.primitives.UnsignedInteger` (class) | -| `Int16` | `short` | -| `UInt16` | `char` | -| `Int32` | `int` | -| `UInt32` | `com.google.common.primitives.UnsignedInteger` (class)️ | -| `Int64` | `long` | -| `UInt64` | `com.google.common.primitives.UnsignedLong` (class) | -| `Float` | `float` | -| `Double` | `double` | - -> Note: The `wrapGuava` mode is currently only available in FFM mode of jextract. - ### Enums > Note: Enums are currently only supported in JNI mode. diff --git a/Sources/SwiftJavaTool/Commands/JExtractCommand.swift b/Sources/SwiftJavaTool/Commands/JExtractCommand.swift index 775ab6040..5309b1dc7 100644 --- a/Sources/SwiftJavaTool/Commands/JExtractCommand.swift +++ b/Sources/SwiftJavaTool/Commands/JExtractCommand.swift @@ -61,9 +61,6 @@ extension SwiftJava { @Flag(help: "Some build systems require an output to be present when it was 'expected', even if empty. This is used by the JExtractSwiftPlugin build plugin, but otherwise should not be necessary.") var writeEmptyFiles: Bool = false - @Option(help: "The mode of generation to use for the output files. Used with jextract mode. By default, unsigned Swift types are imported as their bit-width compatible signed Java counterparts, and annotated using the '@Unsigned' annotation. You may choose the 'wrapGuava' mode in order to import types as class wrapper types (`UnsignedInteger` et al) defined by the Google Guava library's `com.google.common.primitives' package. that ensure complete type-safety with regards to unsigned values, however they incur an allocation and performance overhead.") - var unsignedNumbersMode: JExtractUnsignedIntegerMode? - @Option(help: "The lowest access level of Swift declarations that should be extracted, defaults to 'public'.") var minimumInputAccessLevelMode: JExtractMinimumAccessLevelMode? @@ -105,7 +102,6 @@ extension SwiftJava.JExtractCommand { let enableJavaCallbacks = CommandLine.arguments.contains("--enable-java-callbacks") ? true : nil configure(&config.enableJavaCallbacks, overrideWith: enableJavaCallbacks) - configure(&config.unsignedNumbersMode, overrideWith: self.unsignedNumbersMode) configure(&config.minimumInputAccessLevelMode, overrideWith: self.minimumInputAccessLevelMode) configure(&config.memoryManagementMode, overrideWith: self.memoryManagementMode) configure(&config.asyncFuncMode, overrideWith: self.asyncFuncMode) @@ -131,14 +127,7 @@ extension SwiftJava.JExtractCommand { /// Check if the configured modes are compatible, and fail if not func checkModeCompatibility(config: Configuration) throws { - if config.effectiveMode == .jni { - switch config.effectiveUnsignedNumbersMode { - case .annotate: - () // OK - case .wrapGuava: - throw IllegalModeCombinationError("JNI mode does not support '\(JExtractUnsignedIntegerMode.wrapGuava)' Unsigned integer mode! \(Self.helpMessage())") - } - } else if config.effectiveMode == .ffm { + if config.effectiveMode == .ffm { guard config.effectiveMemoryManagementMode == .explicit else { throw IllegalModeCombinationError("FFM mode does not support '\(self.memoryManagementMode ?? .default)' memory management mode! \(Self.helpMessage())") } @@ -175,7 +164,6 @@ struct IllegalModeCombinationError: Error { } extension JExtractGenerationMode: ExpressibleByArgument {} -extension JExtractUnsignedIntegerMode: ExpressibleByArgument {} extension JExtractMinimumAccessLevelMode: ExpressibleByArgument {} extension JExtractMemoryManagementMode: ExpressibleByArgument {} extension JExtractAsyncFuncMode: ExpressibleByArgument {} diff --git a/Tests/JExtractSwiftTests/JNI/JNIUnsignedNumberTests.swift b/Tests/JExtractSwiftTests/JNI/JNIUnsignedNumberTests.swift index 0833b21f3..ae8592ecb 100644 --- a/Tests/JExtractSwiftTests/JNI/JNIUnsignedNumberTests.swift +++ b/Tests/JExtractSwiftTests/JNI/JNIUnsignedNumberTests.swift @@ -46,7 +46,6 @@ final class JNIUnsignedNumberTests { @Test("Import: UInt32 (annotate)") func jni_unsignedInt_annotate() throws { var config = Configuration() - config.unsignedNumbersMode = .annotate try assertOutput( input: "public func unsignedInt(_ arg: UInt32)", @@ -97,36 +96,9 @@ final class JNIUnsignedNumberTests { ) } - @Test("Import: return UInt64 (wrap, unsupported)") - func jni_return_unsignedLongWrap() throws { - var config = Configuration() - config.unsignedNumbersMode = .wrapGuava - - try assertOutput( - input: "public func returnUnsignedLong() -> UInt64", - config: config, - .jni, .java, - detectChunkByInitialLines: 2, - expectedChunks: [ - // we do not import in wrap mode - """ - public final class SwiftModule { - static final String LIB_NAME = "SwiftModule"; - - static { - System.loadLibrary(LIB_NAME); - } - - } - """, - ] - ) - } - @Test("Import: take UInt64 return UInt32 (annotate)") func jni_echo_unsignedLong_annotate() throws { - var config = Configuration() - config.unsignedNumbersMode = .annotate + let config = Configuration() try assertOutput( input: "public func unsignedLong(first: UInt64, second: UInt32) -> UInt32", diff --git a/Tests/JExtractSwiftTests/UnsignedNumberTests.swift b/Tests/JExtractSwiftTests/UnsignedNumberTests.swift index f3f784098..f2e9f7cd5 100644 --- a/Tests/JExtractSwiftTests/UnsignedNumberTests.swift +++ b/Tests/JExtractSwiftTests/UnsignedNumberTests.swift @@ -65,46 +65,6 @@ final class UnsignedNumberTests { ) } - @Test( - "Import: UInt32 (wrap)", - arguments: [ - ( - JExtractGenerationMode.ffm, - /* expected chunks */ - [ - """ - /** - * {@snippet lang=c : - * void swiftjava_SwiftModule_unsignedInt__(uint32_t arg) - * } - */ - private static class swiftjava_SwiftModule_unsignedInt__ { - private static final FunctionDescriptor DESC = FunctionDescriptor.ofVoid( - /* arg: */SwiftValueLayout.SWIFT_UINT32 - ); - """, - """ - public static void unsignedInt(com.google.common.primitives.UnsignedInteger arg) { - swiftjava_SwiftModule_unsignedInt__.call(UnsignedNumbers.toPrimitive(arg)); - } - """, - ] - ), - // JNI mode does not support the "wrap" mode - ]) - func unsignedInt_wrap(mode: JExtractGenerationMode, expectedChunks: [String]) throws { - var config = Configuration() - config.unsignedNumbersMode = .wrapGuava - - try assertOutput( - input: "public func unsignedInt(_ arg: UInt32)", - config: config, - mode, .java, - detectChunkByInitialLines: 2, - expectedChunks: expectedChunks - ) - } - @Test( "Import: UInt32 (annotate)", arguments: [ @@ -145,7 +105,6 @@ final class UnsignedNumberTests { ]) func unsignedIntAnnotate(mode: JExtractGenerationMode, expectedChunks: [String]) throws { var config = Configuration() - config.unsignedNumbersMode = .annotate try assertOutput( input: "public func unsignedInt(_ arg: UInt32)", @@ -208,46 +167,6 @@ final class UnsignedNumberTests { ) } - @Test( - "Import: return UInt64 (wrap)", - arguments: [ - ( - JExtractGenerationMode.ffm, - /* expected chunks */ - [ - """ - /** - * {@snippet lang=c : - * uint64_t swiftjava_SwiftModule_returnUnsignedLong(void) - * } - */ - private static class swiftjava_SwiftModule_returnUnsignedLong { - private static final FunctionDescriptor DESC = FunctionDescriptor.of( - /* -> */SwiftValueLayout.SWIFT_UINT64 - ); - """, - """ - public static com.google.common.primitives.UnsignedLong returnUnsignedLong() { - return com.google.common.primitives.UnsignedLong.fromLongBits(swiftjava_SwiftModule_returnUnsignedLong.call()); - } - """, - ] - ), - // JNI mode does not support "wrap" mode - ]) - func return_unsignedLongWrap(mode: JExtractGenerationMode, expectedChunks: [String]) throws { - var config = Configuration() - config.unsignedNumbersMode = .wrapGuava - - try assertOutput( - input: "public func returnUnsignedLong() -> UInt64", - config: config, - mode, .java, - detectChunkByInitialLines: 2, - expectedChunks: expectedChunks - ) - } - @Test( "Import: return UInt64 (annotate)", arguments: [ @@ -290,7 +209,6 @@ final class UnsignedNumberTests { ]) func return_unsignedLong_annotate(mode: JExtractGenerationMode, expectedChunks: [String]) throws { var config = Configuration() - config.unsignedNumbersMode = .annotate try assertOutput( input: "public func returnUnsignedLong() -> UInt64", @@ -341,7 +259,6 @@ final class UnsignedNumberTests { ]) func take_unsignedLong_annotate(mode: JExtractGenerationMode, expectedChunks: [String]) throws { var config = Configuration() - config.unsignedNumbersMode = .annotate try assertOutput( input: "public func takeUnsignedLong(arg: UInt64)", @@ -395,8 +312,7 @@ final class UnsignedNumberTests { ), ]) func echo_unsignedLong_annotate(mode: JExtractGenerationMode, expectedChunks: [String]) throws { - var config = Configuration() - config.unsignedNumbersMode = .annotate + let config = Configuration() try assertOutput( input: "public func unsignedLong(first: UInt64, second: UInt32) -> UInt32",