Skip to content

Commit f010c8e

Browse files
authored
wrap-java revamp and add generic methods, types, and supertypes support (#397)
1 parent 4669958 commit f010c8e

File tree

59 files changed

+2150
-624
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2150
-624
lines changed

Package.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ func findJavaHome() -> String {
1414
print("JAVA_HOME = \(home)")
1515
return home
1616
}
17+
if let opts = ProcessInfo.processInfo.environment["SWIFT_JAVA_JAVA_OPTS"] {
18+
print("SWIFT_JAVA_JAVA_OPTS = \(opts)")
19+
}
1720

1821
// This is a workaround for envs (some IDEs) which have trouble with
1922
// picking up env variables during the build process
@@ -420,7 +423,6 @@ let package = Package(
420423
.executableTarget(
421424
name: "SwiftJavaTool",
422425
dependencies: [
423-
.product(name: "Logging", package: "swift-log"),
424426
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
425427
.product(name: "SwiftSyntax", package: "swift-syntax"),
426428
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),

Plugins/SwiftJavaPlugin/SwiftJavaPlugin.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,11 @@ struct SwiftJavaBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
165165
log("No dependencies to fetch for target \(sourceModule.name)")
166166
}
167167

168+
// Add all the core Java stdlib modules as --depends-on
169+
let javaStdlibModules = getExtractedJavaStdlibModules()
170+
log("Include Java standard library SwiftJava modules: \(javaStdlibModules)")
171+
arguments += javaStdlibModules.flatMap { ["--depends-on", $0] }
172+
168173
if !outputSwiftFiles.isEmpty {
169174
arguments += [ configFile.path(percentEncoded: false) ]
170175

@@ -236,3 +241,29 @@ extension SwiftJavaBuildToolPlugin {
236241
outputDirectory(context: context, generated: generated).appending(path: filename)
237242
}
238243
}
244+
245+
func getExtractedJavaStdlibModules() -> [String] {
246+
let fileManager = FileManager.default
247+
let sourcesPath = URL(fileURLWithPath: #filePath)
248+
.deletingLastPathComponent()
249+
.deletingLastPathComponent()
250+
.appendingPathComponent("Sources")
251+
.appendingPathComponent("JavaStdlib")
252+
253+
guard let stdlibDirContents = try? fileManager.contentsOfDirectory(
254+
at: sourcesPath,
255+
includingPropertiesForKeys: [.isDirectoryKey],
256+
options: [.skipsHiddenFiles]
257+
) else {
258+
return []
259+
}
260+
261+
return stdlibDirContents.compactMap { url in
262+
guard let resourceValues = try? url.resourceValues(forKeys: [.isDirectoryKey]),
263+
let isDirectory = resourceValues.isDirectory,
264+
isDirectory else {
265+
return nil
266+
}
267+
return url.lastPathComponent
268+
}.sorted()
269+
}

Samples/JavaDependencySampleApp/Sources/JavaCommonsCSV/swift-java.config

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
{
22
"classes" : {
33
"org.apache.commons.io.FilenameUtils" : "FilenameUtils",
4-
"org.apache.commons.io.IOCase" : "IOCase",
54
"org.apache.commons.csv.CSVFormat" : "CSVFormat",
65
"org.apache.commons.csv.CSVParser" : "CSVParser",
76
"org.apache.commons.csv.CSVRecord" : "CSVRecord"
87
},
8+
"filterExclude" : [
9+
"org.apache.commons.csv.CSVFormat$Predefined",
10+
],
911
"dependencies" : [
1012
"org.apache.commons:commons-csv:1.12.0"
1113
]

Samples/JavaDependencySampleApp/ci-validate.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ set -e
44
set -x
55

66
# invoke resolve as part of a build run
7-
swift run --disable-sandbox
7+
swift build \
8+
--disable-experimental-prebuilts \
9+
--disable-sandbox
810

911
# explicitly invoke resolve without explicit path or dependency
1012
# the dependencies should be uses from the --swift-module

Samples/SwiftJavaExtractJNISampleApp/Sources/MySwiftLibrary/NestedTypes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ public enum NestedEnum {
4444
public struct OneStruct {
4545
public init() {}
4646
}
47-
}
47+
}

Samples/SwiftJavaExtractJNISampleApp/src/main/java/com/example/swift/HelloJava2SwiftJNI.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
// Import swift-extract generated sources
1818

19-
// Import javakit/swiftkit support libraries
20-
2119
import org.swift.swiftkit.core.SwiftArena;
2220
import org.swift.swiftkit.core.SwiftLibraries;
2321

Sources/JavaStdlib/JavaLangReflect/Method+Utilities.swift

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,41 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
extension Method {
16+
1617
/// Whether this is a 'public' method.
1718
public var isPublic: Bool {
18-
return (getModifiers() & 1) != 0
19+
return (getModifiers() & 0x00000001) != 0
20+
}
21+
22+
/// Whether this is a 'private' method.
23+
public var isPrivate: Bool {
24+
return (getModifiers() & 0x00000002) != 0
1925
}
2026

2127
/// Whether this is a 'protected' method.
2228
public var isProtected: Bool {
23-
return (getModifiers() & 4) != 0
29+
return (getModifiers() & 0x00000004) != 0
30+
}
31+
32+
/// Whether this is a 'package' method.
33+
///
34+
/// The "default" access level in Java is 'package', it is signified by lack of a different access modifier.
35+
public var isPackage: Bool {
36+
return !isPublic && !isPrivate && !isProtected
2437
}
2538

2639
/// Whether this is a 'static' method.
2740
public var isStatic: Bool {
28-
return (getModifiers() & 0x08) != 0
41+
return (getModifiers() & 0x00000008) != 0
2942
}
3043

3144
/// Whether this is a 'native' method.
3245
public var isNative: Bool {
33-
return (getModifiers() & 256) != 0
46+
return (getModifiers() & 0x00000100) != 0
47+
}
48+
49+
/// Whether this is a 'final' method.
50+
public var isFinal: Bool {
51+
return (getModifiers() & 0x00000010) != 0
3452
}
3553
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import CSwiftJavaJNI
16+
import SwiftJava
17+
18+
// FIXME: all interfaces should ahve these https://github.com/swiftlang/swift-java/issues/430
19+
extension TypeVariable {
20+
21+
@JavaMethod
22+
public func toString() -> String
23+
24+
@JavaMethod
25+
public func getClass() -> JavaClass<JavaObject>!
26+
27+
@JavaMethod
28+
public func equals(_ arg0: JavaObject?) -> Bool
29+
30+
@JavaMethod
31+
public func hashCode() -> Int32
32+
33+
}
34+
35+
// FIXME: All Java objects are Hashable, we should handle that accordingly.
36+
extension TypeVariable: Hashable {
37+
38+
public func hash(into hasher: inout Hasher) {
39+
guard let pojo = self.as(JavaObject.self) else {
40+
return
41+
}
42+
43+
hasher.combine(pojo.hashCode())
44+
}
45+
46+
public static func == (lhs: TypeVariable<D>, rhs: TypeVariable<D>) -> Bool {
47+
guard let lhpojo: JavaObject = lhs.as(JavaObject.self) else {
48+
return false
49+
}
50+
guard let rhpojo: JavaObject = rhs.as(JavaObject.self) else {
51+
return false
52+
}
53+
54+
return lhpojo.equals(rhpojo)
55+
}
56+
57+
}
58+
59+
extension TypeVariable {
60+
public var description: String {
61+
toString()
62+
}
63+
}

Sources/JavaStdlib/JavaLangReflect/generated/Executable.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ open class Executable: AccessibleObject {
1111
@JavaMethod
1212
open func getModifiers() -> Int32
1313

14-
@JavaMethod
15-
open func getTypeParameters() -> [TypeVariable<JavaObject>?]
16-
1714
@JavaMethod
1815
open func getParameterTypes() -> [JavaClass<JavaObject>?]
1916

Sources/JavaStdlib/JavaLangReflect/generated/ParameterizedType.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,24 @@ public struct ParameterizedType {
1616
@JavaMethod
1717
public func getTypeName() -> String
1818
}
19+
20+
extension ParameterizedType {
21+
22+
@JavaMethod
23+
public func toString() -> String
24+
25+
@JavaMethod
26+
public func getClass() -> JavaClass<JavaObject>!
27+
28+
@JavaMethod
29+
public func equals(_ arg0: JavaObject?) -> Bool
30+
31+
@JavaMethod
32+
public func hashCode() -> Int32
33+
}
34+
35+
extension ParameterizedType: CustomStringConvertible {
36+
public var description: String {
37+
toString()
38+
}
39+
}

0 commit comments

Comments
 (0)