Skip to content

Commit c904839

Browse files
authored
Merge pull request #83 from DougGregor/java2swift-api-cleanup
Rework Java2Swift to operate entirely on Java2Swift.config files
2 parents 4b3387d + 18a105a commit c904839

File tree

13 files changed

+408
-402
lines changed

13 files changed

+408
-402
lines changed

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,19 @@ Java2Swift: $(BUILD_DIR)/debug/Java2Swift
7070

7171
generate-JavaKit: Java2Swift
7272
mkdir -p Sources/JavaKit/generated
73-
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKit -o Sources/JavaKit/generated java.lang.Object=JavaObject java.util.Enumeration java.lang.Throwable java.lang.Exception java.lang.RuntimeException java.lang.Error=JavaError
73+
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKit -o Sources/JavaKit/generated Sources/JavaKit/Java2Swift.config
7474

7575
generate-JavaKitReflection: Java2Swift generate-JavaKit
7676
mkdir -p Sources/JavaKitReflection/generated
77-
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitReflection --manifests Sources/JavaKit/generated/JavaKit.swift2java -o Sources/JavaKitReflection/generated java.lang.reflect.Method java.lang.reflect.Type java.lang.reflect.Constructor java.lang.reflect.Parameter java.lang.reflect.ParameterizedType java.lang.reflect.Executable java.lang.reflect.AnnotatedType java.lang.reflect.TypeVariable java.lang.reflect.WildcardType java.lang.reflect.GenericArrayType java.lang.reflect.AccessibleObject java.lang.annotation.Annotation java.lang.reflect.GenericDeclaration java.lang.reflect.Field
77+
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitReflection --depends-on JavaKit=Sources/JavaKit/Java2Swift.config -o Sources/JavaKitReflection/generated Sources/JavaKitReflection/Java2Swift.config
7878

7979
generate-JavaKitJar: Java2Swift generate-JavaKit
8080
mkdir -p Sources/JavaKitJar/generated
81-
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitJar --manifests Sources/JavaKit/generated/JavaKit.swift2java -o Sources/JavaKitJar/generated java.util.jar.Attributes java.util.jar.JarEntry java.util.jar.JarFile java.util.jar.JarInputStream java.util.jar.JarOutputStream java.util.jar.Manifest
81+
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitJar --depends-on JavaKit=Sources/JavaKit/Java2Swift.config -o Sources/JavaKitJar/generated Sources/JavaKitJar/Java2Swift.config
8282

8383
generate-JavaKitNetwork: Java2Swift generate-JavaKit
8484
mkdir -p Sources/JavaKitNetwork/generated
85-
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitNetwork --manifests Sources/JavaKit/generated/JavaKit.swift2java -o Sources/JavaKitNetwork/generated java.net.URI java.net.URL java.net.URLClassLoader
85+
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitNetwork --depends-on JavaKit=Sources/JavaKit/Java2Swift.config -o Sources/JavaKitNetwork/generated Sources/JavaKitNetwork/Java2Swift.config
8686

8787
javakit-generate: generate-JavaKit generate-JavaKitReflection generate-JavaKitJar generate-JavaKitNetwork
8888

Plugins/Java2SwiftPlugin/Configuration.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414

1515
/// Configuration for the Java2Swift translation tool, provided on a per-target
1616
/// basis.
17+
///
18+
/// Note: there is a copy of this struct in the Java2Swift library. They
19+
/// must be kept in sync.
1720
struct Configuration: Codable {
1821
/// The Java class path that should be passed along to the Java2Swift tool.
1922
var classPath: String? = nil
2023

2124
/// The Java classes that should be translated to Swift. The keys are
2225
/// canonical Java class names (e.g., java.util.Vector) and the values are
23-
/// the corresponding Swift names (e.g., JavaVector). If the value is `nil`,
24-
/// then the Java class name will be used for the Swift name, too.
25-
var classes: [String: String?] = [:]
26+
/// the corresponding Swift names (e.g., JavaVector).
27+
var classes: [String: String] = [:]
2628
}

Plugins/Java2SwiftPlugin/Java2SwiftPlugin.swift

Lines changed: 24 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import Foundation
1616
import PackagePlugin
1717

18+
fileprivate let Java2SwiftConfigFileName = "Java2Swift.config"
19+
1820
@main
1921
struct Java2SwiftBuildToolPlugin: BuildToolPlugin {
2022
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
@@ -24,42 +26,39 @@ struct Java2SwiftBuildToolPlugin: BuildToolPlugin {
2426
// so we cannot eliminate this deprecation warning.
2527
let sourceDir = target.directory.string
2628

27-
// Read a configuration file JavaKit.config from the target that provides
28-
// information needed to call Java2Swift.
29+
// The name of the configuration file JavaKit.config from the target for
30+
// which we are generating Swift wrappers for Java classes.
2931
let configFile = URL(filePath: sourceDir)
3032
.appending(path: "Java2Swift.config")
3133
let configData = try Data(contentsOf: configFile)
3234
let config = try JSONDecoder().decode(Configuration.self, from: configData)
3335

3436
/// Find the manifest files from other Java2Swift executions in any targets
3537
/// this target depends on.
36-
var manifestFiles: [URL] = []
37-
func searchForManifestFiles(in target: any Target) {
38+
var dependentConfigFiles: [(String, URL)] = []
39+
func searchForConfigFiles(in target: any Target) {
3840
let dependencyURL = URL(filePath: target.directory.string)
3941

40-
// Look for a checked-in manifest file.
41-
let generatedManifestURL = dependencyURL
42-
.appending(path: "generated")
43-
.appending(path: "\(target.name).swift2java")
44-
let generatedManifestString = generatedManifestURL
42+
// Look for a config file within this target.
43+
let dependencyConfigURL = dependencyURL
44+
.appending(path: Java2SwiftConfigFileName)
45+
let dependencyConfigString = dependencyConfigURL
4546
.path(percentEncoded: false)
4647

47-
if FileManager.default.fileExists(atPath: generatedManifestString) {
48-
manifestFiles.append(generatedManifestURL)
48+
if FileManager.default.fileExists(atPath: dependencyConfigString) {
49+
dependentConfigFiles.append((target.name, dependencyConfigURL))
4950
}
50-
51-
// TODO: Look for a manifest file that was built by the plugin itself.
5251
}
5352

5453
// Process direct dependencies of this target.
5554
for dependency in target.dependencies {
5655
switch dependency {
5756
case .target(let target):
58-
searchForManifestFiles(in: target)
57+
searchForConfigFiles(in: target)
5958

6059
case .product(let product):
6160
for target in product.targets {
62-
searchForManifestFiles(in: target)
61+
searchForConfigFiles(in: target)
6362
}
6463

6564
@unknown default:
@@ -69,16 +68,7 @@ struct Java2SwiftBuildToolPlugin: BuildToolPlugin {
6968

7069
// Process indirect target dependencies.
7170
for dependency in target.recursiveTargetDependencies {
72-
searchForManifestFiles(in: dependency)
73-
}
74-
75-
/// Determine the list of Java classes that will be translated into Swift,
76-
/// along with the names of the corresponding Swift types. This will be
77-
/// passed along to the Java2Swift tool.
78-
let classes = config.classes.map { (javaClassName, swiftName) in
79-
(javaClassName, swiftName ?? javaClassName.defaultSwiftNameForJavaClass)
80-
}.sorted { (lhs, rhs) in
81-
lhs.0 < rhs.0
71+
searchForConfigFiles(in: dependency)
8272
}
8373

8474
let outputDirectory = context.pluginWorkDirectoryURL
@@ -88,27 +78,26 @@ struct Java2SwiftBuildToolPlugin: BuildToolPlugin {
8878
"--module-name", sourceModule.name,
8979
"--output-directory", outputDirectory.path(percentEncoded: false),
9080
]
91-
if let classPath = config.classPath {
92-
arguments += ["-cp", classPath]
93-
}
94-
arguments += manifestFiles.flatMap { manifestFile in
95-
[ "--manifests", manifestFile.path(percentEncoded: false) ]
96-
}
97-
arguments += classes.map { (javaClassName, swiftName) in
98-
"\(javaClassName)=\(swiftName)"
81+
arguments += dependentConfigFiles.flatMap { moduleAndConfigFile in
82+
let (moduleName, configFile) = moduleAndConfigFile
83+
return [
84+
"--depends-on",
85+
"\(moduleName)=\(configFile.path(percentEncoded: false))"
86+
]
9987
}
88+
arguments.append(configFile.path(percentEncoded: false))
10089

10190
/// Determine the set of Swift files that will be emitted by the Java2Swift
10291
/// tool.
103-
let outputSwiftFiles = classes.map { (javaClassName, swiftName) in
92+
let outputSwiftFiles = config.classes.map { (javaClassName, swiftName) in
10493
outputDirectory.appending(path: "\(swiftName).swift")
10594
} + [
10695
outputDirectory.appending(path: "\(sourceModule.name).swift2java")
10796
]
10897

10998
return [
11099
.buildCommand(
111-
displayName: "Wrapping \(classes.count) Java classes target \(sourceModule.name) in Swift",
100+
displayName: "Wrapping \(config.classes.count) Java classes target \(sourceModule.name) in Swift",
112101
executable: try context.tool(named: "Java2Swift").url,
113102
arguments: arguments,
114103
inputFiles: [ configFile ],
@@ -139,16 +128,3 @@ func findJavaHome() -> String {
139128

140129
fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.")
141130
}
142-
143-
extension String {
144-
/// For a String that's of the form java.util.Vector, return the "Vector"
145-
/// part.
146-
fileprivate var defaultSwiftNameForJavaClass: String {
147-
if let dotLoc = lastIndex(of: ".") {
148-
let afterDot = index(after: dotLoc)
149-
return String(self[afterDot...])
150-
}
151-
152-
return self
153-
}
154-
}

0 commit comments

Comments
 (0)