@@ -20,13 +20,16 @@ fileprivate let SwiftJavaConfigFileName = "swift-java.config"
2020@main
2121struct Java2SwiftBuildToolPlugin : SwiftJavaPluginProtocol , BuildToolPlugin {
2222
23- var pluginName : String = " swift-java-javac "
23+ var pluginName : String = " swift-java "
2424 var verbose : Bool = getEnvironmentBool ( " SWIFT_JAVA_VERBOSE " )
2525
2626 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) ' " )
2828 guard let sourceModule = target. sourceModule else { return [ ] }
2929
30+ let executable = try context. tool ( named: " Java2Swift " ) . url
31+ var commands : [ Command ] = [ ]
32+
3033 // Note: Target doesn't have a directoryURL counterpart to directory,
3134 // so we cannot eliminate this deprecation warning.
3235 let sourceDir = target. directory. string
@@ -35,14 +38,17 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
3538 // which we are generating Swift wrappers for Java classes.
3639 let configFile = URL ( filePath: sourceDir)
3740 . 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 ?? [ ]
4046
4147 /// Find the manifest files from other Java2Swift executions in any targets
4248 /// this target depends on.
4349 var dependentConfigFiles : [ ( String , URL ) ] = [ ]
4450 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)")
4652 let dependencyURL = URL ( filePath: target. directory. string)
4753
4854 // Look for a config file within this target.
@@ -60,13 +66,13 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
6066 for dependency in target. dependencies {
6167 switch dependency {
6268 case . target( let target) :
63- log ( " Dependency target: \( target. name) " )
69+ // log("Dependency target: \(target.name)")
6470 searchForConfigFiles ( in: target)
6571
6672 case . product( let product) :
67- log ( " Dependency product: \( product. name) " )
73+ // log("Dependency product: \(product.name)")
6874 for target in product. targets {
69- log ( " Dependency product: \( product. name) , target: \( target. name) " )
75+ // log("Dependency product: \(product.name), target: \(target.name)")
7076 searchForConfigFiles ( in: target)
7177 }
7278
@@ -77,17 +83,14 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
7783
7884 // Process indirect target dependencies.
7985 for dependency in target. recursiveTargetDependencies {
80- log ( " Recursive dependency target: \( dependency. name) " )
86+ // log("Recursive dependency target: \(dependency.name)")
8187 searchForConfigFiles ( in: dependency)
8288 }
8389
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+
9194 arguments += dependentConfigFiles. flatMap { moduleAndConfigFile in
9295 let ( moduleName, configFile) = moduleAndConfigFile
9396 return [
@@ -102,12 +105,14 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
102105// return []
103106// }
104107 let classes = config. classes ?? [ : ]
108+ print ( " Classes to wrap: \( classes. map ( \. key) ) " )
105109
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 )
108113 let outputSwiftFiles = classes. map { ( javaClassName, swiftName) in
109114 let swiftNestedName = swiftName. replacingOccurrences ( of: " . " , with: " + " )
110- return outputDirectory . appending ( path: " \( swiftNestedName) .swift " )
115+ return outputDirectoryGenerated . appending ( path: " \( swiftNestedName) .swift " )
111116 }
112117
113118 arguments += [
@@ -147,19 +152,77 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
147152 }
148153 }
149154
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+ }
151201
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 ] {
152210 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 )
163213 ]
164214 }
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+ }
165228}
0 commit comments