@@ -20,13 +20,16 @@ fileprivate let SwiftJavaConfigFileName = "swift-java.config"
20
20
@main
21
21
struct Java2SwiftBuildToolPlugin : SwiftJavaPluginProtocol , BuildToolPlugin {
22
22
23
- var pluginName : String = " swift-java-javac "
23
+ var pluginName : String = " swift-java "
24
24
var verbose : Bool = getEnvironmentBool ( " SWIFT_JAVA_VERBOSE " )
25
25
26
26
func createBuildCommands( context: PluginContext , target: Target ) throws -> [ Command ] {
27
- log ( " Create build commands for: \( target. name) " )
27
+ log ( " Create build commands for target ' \( target. name) ' " )
28
28
guard let sourceModule = target. sourceModule else { return [ ] }
29
29
30
+ let executable = try context. tool ( named: " Java2Swift " ) . url
31
+ var commands : [ Command ] = [ ]
32
+
30
33
// Note: Target doesn't have a directoryURL counterpart to directory,
31
34
// so we cannot eliminate this deprecation warning.
32
35
let sourceDir = target. directory. string
@@ -35,14 +38,17 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
35
38
// which we are generating Swift wrappers for Java classes.
36
39
let configFile = URL ( filePath: sourceDir)
37
40
. appending ( path: SwiftJavaConfigFileName)
38
- let configData = try Data ( contentsOf: configFile)
39
- let config = try JSONDecoder ( ) . decode ( Configuration . self, from: configData)
41
+ let config = try readConfiguration ( sourceDir: sourceDir)
42
+
43
+ log ( " Config on path: \( configFile. path ( percentEncoded: false ) ) " )
44
+ log ( " Config was: \( config) " )
45
+ var javaDependencies = config. dependencies ?? [ ]
40
46
41
47
/// Find the manifest files from other Java2Swift executions in any targets
42
48
/// this target depends on.
43
49
var dependentConfigFiles : [ ( String , URL ) ] = [ ]
44
50
func searchForConfigFiles( in target: any Target ) {
45
- log ( " Search for config files in target: \( target. name) " )
51
+ // log("Search for config files in target: \(target.name)")
46
52
let dependencyURL = URL ( filePath: target. directory. string)
47
53
48
54
// Look for a config file within this target.
@@ -60,13 +66,13 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
60
66
for dependency in target. dependencies {
61
67
switch dependency {
62
68
case . target( let target) :
63
- log ( " Dependency target: \( target. name) " )
69
+ // log("Dependency target: \(target.name)")
64
70
searchForConfigFiles ( in: target)
65
71
66
72
case . product( let product) :
67
- log ( " Dependency product: \( product. name) " )
73
+ // log("Dependency product: \(product.name)")
68
74
for target in product. targets {
69
- log ( " Dependency product: \( product. name) , target: \( target. name) " )
75
+ // log("Dependency product: \(product.name), target: \(target.name)")
70
76
searchForConfigFiles ( in: target)
71
77
}
72
78
@@ -77,17 +83,14 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
77
83
78
84
// Process indirect target dependencies.
79
85
for dependency in target. recursiveTargetDependencies {
80
- log ( " Recursive dependency target: \( dependency. name) " )
86
+ // log("Recursive dependency target: \(dependency.name)")
81
87
searchForConfigFiles ( in: dependency)
82
88
}
83
89
84
- let outputDirectory = context. pluginWorkDirectoryURL
85
- . appending ( path: " generated " )
86
-
87
- var arguments : [ String ] = [
88
- " --module-name " , sourceModule. name,
89
- " --output-directory " , outputDirectory. path ( percentEncoded: false ) ,
90
- ]
90
+ var arguments : [ String ] = [ ]
91
+ arguments += argumentsModuleName ( sourceModule: sourceModule)
92
+ arguments += argumentsOutputDirectory ( context: context)
93
+
91
94
arguments += dependentConfigFiles. flatMap { moduleAndConfigFile in
92
95
let ( moduleName, configFile) = moduleAndConfigFile
93
96
return [
@@ -102,12 +105,14 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
102
105
// return []
103
106
// }
104
107
let classes = config. classes ?? [ : ]
108
+ print ( " Classes to wrap: \( classes. map ( \. key) ) " )
105
109
106
- /// Determine the set of Swift files that will be emitted by the Java2Swift
107
- /// tool.
110
+ /// Determine the set of Swift files that will be emitted by the Java2Swift tool.
111
+ // TODO: this is not precise and won't work with more advanced Java files, e.g. lambdas etc.
112
+ let outputDirectoryGenerated = self . outputDirectory ( context: context, generated: true )
108
113
let outputSwiftFiles = classes. map { ( javaClassName, swiftName) in
109
114
let swiftNestedName = swiftName. replacingOccurrences ( of: " . " , with: " + " )
110
- return outputDirectory . appending ( path: " \( swiftNestedName) .swift " )
115
+ return outputDirectoryGenerated . appending ( path: " \( swiftNestedName) .swift " )
111
116
}
112
117
113
118
arguments += [
@@ -147,19 +152,77 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
147
152
}
148
153
}
149
154
150
- let executable = try context. tool ( named: " Java2Swift " ) . url
155
+ var fetchDependenciesOutputFiles : [ URL ] = [ ]
156
+ if let dependencies = config. dependencies, !dependencies. isEmpty {
157
+ let displayName = " Fetch (Java) dependencies for Swift target \( sourceModule. name) "
158
+ log ( " Prepared: \( displayName) " )
159
+
160
+ fetchDependenciesOutputFiles += [
161
+ outputFilePath ( context: context, generated: false , filename: " \( sourceModule. name) .swift-java.classpath " )
162
+ ]
163
+
164
+ commands += [
165
+ . buildCommand(
166
+ displayName: displayName,
167
+ executable: executable,
168
+ arguments: [
169
+ " --fetch " , configFile. path ( percentEncoded: false ) ,
170
+ " --module-name " , sourceModule. name,
171
+ " --output-directory " , outputDirectory ( context: context, generated: false ) . path ( percentEncoded: false )
172
+ ] ,
173
+ environment: [ : ] ,
174
+ inputFiles: [ configFile] ,
175
+ outputFiles: fetchDependenciesOutputFiles
176
+ )
177
+ ]
178
+ } else {
179
+ log ( " No dependencies to fetch for target \( sourceModule. name) " )
180
+ }
181
+
182
+ if !outputSwiftFiles. isEmpty {
183
+ commands += [
184
+ . buildCommand(
185
+ displayName: " Wrapping \( classes. count) Java classes in Swift target ' \( sourceModule. name) ' " ,
186
+ executable: executable,
187
+ arguments: arguments,
188
+ inputFiles: compiledClassFiles + fetchDependenciesOutputFiles + [
189
+ configFile
190
+ ] ,
191
+ outputFiles: outputSwiftFiles
192
+ )
193
+ ]
194
+ } else {
195
+ log ( " No Swift output files, skip wrapping " )
196
+ }
197
+
198
+ return commands
199
+ }
200
+ }
151
201
202
+ extension Java2SwiftBuildToolPlugin {
203
+ func argumentsModuleName( sourceModule: Target ) -> [ String ] {
204
+ return [
205
+ " --module-name " , sourceModule. name
206
+ ]
207
+ }
208
+
209
+ func argumentsOutputDirectory( context: PluginContext , generated: Bool = true ) -> [ String ] {
152
210
return [
153
- . buildCommand(
154
- displayName: " Wrapping \( classes. count) Java classes target in Swift target ' \( sourceModule. name) ' " ,
155
- executable: executable,
156
- arguments: arguments,
157
- inputFiles: compiledClassFiles + [
158
- configFile,
159
- context. cachedClasspathFile ( moduleName: sourceModule. name)
160
- ] ,
161
- outputFiles: outputSwiftFiles
162
- )
211
+ " --output-directory " ,
212
+ outputDirectory ( context: context, generated: generated) . path ( percentEncoded: false )
163
213
]
164
214
}
215
+
216
+ func outputDirectory( context: PluginContext , generated: Bool = true ) -> URL {
217
+ let dir = context. pluginWorkDirectoryURL
218
+ if generated {
219
+ return dir. appending ( path: " generated " )
220
+ } else {
221
+ return dir
222
+ }
223
+ }
224
+
225
+ func outputFilePath( context: PluginContext , generated: Bool , filename: String ) -> URL {
226
+ outputDirectory ( context: context, generated: generated) . appending ( path: filename)
227
+ }
165
228
}
0 commit comments