Skip to content

Refactor to converge many command line tools into a single "swift-java" #219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ DerivedData/
*.class
bin/
BuildLogic/out/
.index-build
.build-vscode
**/.index-build/
**/.build-vscode/

# Ignore gradle build artifacts
.gradle
Expand Down
20 changes: 10 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,29 +56,29 @@ SAMPLES_DIR := "Samples"
all:
@echo "Welcome to swift-java! There are several makefile targets to choose from:"
@echo " javakit-run: Run the JavaKit example program that uses Java libraries from Swift."
@echo " javakit-generate: Regenerate the Swift wrapper code for the various JavaKit libraries from Java. This only has to be done when changing the Java2Swift tool."
@echo " javakit-generate: Regenerate the Swift wrapper code for the various JavaKit libraries from Java. This only has to be done when changing the SwiftJava tool."

$(BUILD_DIR)/debug/libJavaKit.$(LIB_SUFFIX) $(BUILD_DIR)/debug/Java2Swift:
$(BUILD_DIR)/debug/libJavaKit.$(LIB_SUFFIX) $(BUILD_DIR)/debug/SwiftJava:
swift build

javakit-run:
cd Samples/JavaKitSampleApp && swift build && java -cp .build/plugins/outputs/javakitsampleapp/JavaKitExample/destination/JavaCompilerPlugin/Java -Djava.library.path=.build/debug com.example.swift.JavaKitSampleMain

Java2Swift: $(BUILD_DIR)/debug/Java2Swift
SwiftJava: $(BUILD_DIR)/debug/SwiftJava

generate-JavaKit: Java2Swift
generate-JavaKit: SwiftJava
mkdir -p Sources/JavaKit/generated
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKit -o Sources/JavaKit/generated Sources/JavaKit/swift-java.config
$(BUILD_DIR)/debug/SwiftJava --module-name JavaKit -o Sources/JavaKit/generated Sources/JavaKit/swift-java.config

generate-JavaKitCollection: Java2Swift
generate-JavaKitCollection: SwiftJava
mkdir -p Sources/JavaKitCollection/generated
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitCollection --depends-on JavaKit=Sources/JavaKit/swift-java.config -o Sources/JavaKitCollection/generated Sources/JavaKitCollection/swift-java.config
$(BUILD_DIR)/debug/SwiftJava --module-name JavaKitCollection --depends-on JavaKit=Sources/JavaKit/swift-java.config -o Sources/JavaKitCollection/generated Sources/JavaKitCollection/swift-java.config

generate-JavaKitFunction: Java2Swift
generate-JavaKitFunction: SwiftJava
mkdir -p Sources/JavaKitFunction/generated
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitFunction --depends-on JavaKit=Sources/JavaKit/swift-java.config -o Sources/JavaKitFunction/generated Sources/JavaKitFunction/swift-java.config
$(BUILD_DIR)/debug/SwiftJava --module-name JavaKitFunction --depends-on JavaKit=Sources/JavaKit/swift-java.config -o Sources/JavaKitFunction/generated Sources/JavaKitFunction/swift-java.config

generate-JavaKitReflection: Java2Swift generate-JavaKit generate-JavaKitCollection
generate-JavaKitReflection: SwiftJava generate-JavaKit generate-JavaKitCollection
mkdir -p Sources/JavaKitReflection/generated
$(BUILD_DIR)/debug/Java2Swift --module-name JavaKitReflection --depends-on JavaKit=Sources/JavaKit/swift-java.config --depends-on JavaKitCollection=Sources/JavaKitCollection/swift-java.config -o Sources/JavaKitReflection/generated Sources/JavaKitReflection/swift-java.config

Expand Down
35 changes: 14 additions & 21 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ let package = Package(
),

.executable(
name: "Java2Swift",
targets: ["Java2Swift"]
name: "SwiftJavaTool",
targets: ["SwiftJavaTool"]
),

// ==== Plugin for building Java code
Expand All @@ -101,17 +101,17 @@ let package = Package(

// ==== Plugin for wrapping Java classes in Swift
.plugin(
name: "Java2SwiftPlugin",
name: "SwiftJavaPlugin",
targets: [
"Java2SwiftPlugin"
"SwiftJavaPlugin"
]
),

// ==== jextract-swift (extract Java accessors from Swift interface files)

.executable(
name: "jextract-swift",
targets: ["JExtractSwiftTool"]
targets: ["SwiftJavaTool"]
),

// Support library written in Swift for SwiftKit "Java"
Expand Down Expand Up @@ -257,10 +257,10 @@ let package = Package(
),

.plugin(
name: "Java2SwiftPlugin",
name: "SwiftJavaPlugin",
capability: .buildTool(),
dependencies: [
"Java2Swift"
"SwiftJavaTool"
]
),

Expand Down Expand Up @@ -320,7 +320,7 @@ let package = Package(
),

.executableTarget(
name: "Java2Swift",
name: "SwiftJavaTool",
dependencies: [
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
Expand All @@ -330,6 +330,7 @@ let package = Package(
"JavaKitJar",
"JavaKitNetwork",
"Java2SwiftLib",
"JExtractSwift", // TODO: Swift2JavaLib
"JavaKitShared",
],

Expand All @@ -356,21 +357,11 @@ let package = Package(
]
),

.executableTarget(
name: "JExtractSwiftTool",
dependencies: [
"JExtractSwift",
],
swiftSettings: [
.swiftLanguageMode(.v5)
]
),

.plugin(
name: "JExtractSwiftPlugin",
capability: .buildTool(),
dependencies: [
"JExtractSwiftTool"
"SwiftJavaTool"
]
),
.plugin(
Expand All @@ -380,7 +371,7 @@ let package = Package(
permissions: [
]),
dependencies: [
"JExtractSwiftTool"
"SwiftJavaTool"
]
),

Expand Down Expand Up @@ -414,7 +405,9 @@ let package = Package(

.testTarget(
name: "Java2SwiftTests",
dependencies: ["Java2SwiftLib"],
dependencies: [
"Java2SwiftLib"
],
swiftSettings: [
.swiftLanguageMode(.v5),
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ final class JExtractSwiftCommandPlugin: SwiftJavaPluginProtocol, BuildToolPlugin
}

var arguments: [String] = [
"jextract",
"--swift-module", sourceModule.name,
"--package-name", javaPackage,
"--output-directory-java", context.outputDirectoryJava.path(percentEncoded: false),
Expand Down Expand Up @@ -135,7 +136,7 @@ final class JExtractSwiftCommandPlugin: SwiftJavaPluginProtocol, BuildToolPlugin

func runExtract(context: PluginContext, target: Target, arguments: [String]) throws {
let process = Process()
process.executableURL = try context.tool(named: "JExtractSwiftTool").url
process.executableURL = try context.tool(named: "SwiftJavaTool").url
process.arguments = arguments

do {
Expand Down
3 changes: 2 additions & 1 deletion Plugins/JExtractSwiftPlugin/JExtractSwiftPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")

func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
let toolURL = try context.tool(named: "JExtractSwiftTool").url
let toolURL = try context.tool(named: "SwiftJavaTool").url

guard let sourceModule = target.sourceModule else { return [] }

Expand Down Expand Up @@ -54,6 +54,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
let outputDirectorySwift = context.outputDirectorySwift

var arguments: [String] = [
"jextract",
"--swift-module", sourceModule.name,
"--package-name", javaPackage,
"--output-directory-java", outputDirectoryJava.path(percentEncoded: false),
Expand Down
2 changes: 1 addition & 1 deletion Plugins/JavaCompilerPlugin/JavaCompilerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct JavaCompilerBuildToolPlugin: BuildToolPlugin {

// The name of the configuration file JavaKit.config from the target for
// which we are generating Swift wrappers for Java classes.
let configFile = URL(filePath: sourceDir).appending(path: "Java2Swift.config")
let configFile = URL(filePath: sourceDir).appending(path: "swift-java.config")
let config: Configuration?

if let configData = try? Data(contentsOf: configFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import PackagePlugin
fileprivate let SwiftJavaConfigFileName = "swift-java.config"

@main
struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
struct SwiftJavaBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {

var pluginName: String = "swift-java"
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")
Expand All @@ -27,7 +27,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
log("Create build commands for target '\(target.name)'")
guard let sourceModule = target.sourceModule else { return [] }

let executable = try context.tool(named: "Java2Swift").url
let executable = try context.tool(named: "SwiftJavaTool").url
var commands: [Command] = []

// Note: Target doesn't have a directoryURL counterpart to directory,
Expand All @@ -44,7 +44,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
log("Config was: \(config)")
var javaDependencies = config.dependencies ?? []

/// Find the manifest files from other Java2Swift executions in any targets
/// Find the manifest files from other SwiftJava executions in any targets
/// this target depends on.
var dependentConfigFiles: [(String, URL)] = []
func searchForConfigFiles(in target: any Target) {
Expand Down Expand Up @@ -107,7 +107,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
let classes = config.classes ?? [:]
print("Classes to wrap: \(classes.map(\.key))")

/// Determine the set of Swift files that will be emitted by the Java2Swift tool.
/// Determine the set of Swift files that will be emitted by the SwiftJava tool.
// TODO: this is not precise and won't work with more advanced Java files, e.g. lambdas etc.
let outputDirectoryGenerated = self.outputDirectory(context: context, generated: true)
let outputSwiftFiles = classes.map { (javaClassName, swiftName) in
Expand Down Expand Up @@ -199,7 +199,7 @@ struct Java2SwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
}
}

extension Java2SwiftBuildToolPlugin {
extension SwiftJavaBuildToolPlugin {
func argumentsModuleName(sourceModule: Target) -> [String] {
return [
"--module-name", sourceModule.name
Expand Down
4 changes: 2 additions & 2 deletions Samples/JavaDependencySampleApp/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ let package = Package(
.swiftLanguageMode(.v5),
],
plugins: [
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
]
),

Expand All @@ -94,7 +94,7 @@ let package = Package(
],
plugins: [
// .plugin(name: "SwiftJavaBootstrapJavaPlugin", package: "swift-java"),
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
]
),

Expand Down
2 changes: 1 addition & 1 deletion Samples/JavaKitSampleApp/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ let package = Package(
plugins: [
.plugin(name: "JavaCompilerPlugin", package: "swift-java"),
.plugin(name: "JExtractSwiftPlugin", package: "swift-java"),
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
]
),
]
Expand Down
2 changes: 1 addition & 1 deletion Samples/JavaProbablyPrime/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ let package = Package(
.swiftLanguageMode(.v5)
],
plugins: [
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
]
),
]
Expand Down
2 changes: 1 addition & 1 deletion Samples/JavaProbablyPrime/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ swift run JavaProbablyPrime <very big number>

The package itself demonstrates how to:

* Use the Java2Swift build tool plugin to wrap the `java.math.BigInteger` type in Swift.
* Use the SwiftJava build tool plugin to wrap the `java.math.BigInteger` type in Swift.
* Create an instance of `BigInteger` in Swift and use its `isProbablyPrime`.
4 changes: 2 additions & 2 deletions Samples/JavaSieve/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ let package = Package(
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
],
plugins: [
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
]
),

Expand All @@ -75,7 +75,7 @@ let package = Package(
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
],
plugins: [
.plugin(name: "Java2SwiftPlugin", package: "swift-java"),
.plugin(name: "SwiftJavaPlugin", package: "swift-java"),
]
),
]
Expand Down
4 changes: 2 additions & 2 deletions Samples/JavaSieve/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

This package contains an example program that demonstrates importing a Java library distributed as a Jar file into Swift and using some APIs from that library. It demonstrates how to:

* Use the Java2Swift tool to discover the classes in a Jar file and make them available in Swift
* Layer Swift wrappers for Java classes as separate Swift modules using Java2Swift
* Use the SwiftJava tool to discover the classes in a Jar file and make them available in Swift
* Layer Swift wrappers for Java classes as separate Swift modules using SwiftJava
* Access static methods of Java classes from Swift

This example wraps an [open-source Java library](https://github.com/gazman-sdk/quadratic-sieve-Java) implementing the [Sieve of Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes) algorithm for finding prime numbers, among other algorithms. To get started, clone that repository and build a Jar file containing the library:
Expand Down
24 changes: 17 additions & 7 deletions Sources/JExtractSwift/Swift2Java.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ import JavaKitShared

/// Command-line utility, similar to `jextract` to export Swift types to Java.
public struct SwiftToJava: ParsableCommand {
public init() {}
public static var _commandName: String { "jextract" }

public static var configuration = CommandConfiguration(
commandName: Self._commandName,
abstract: "Generate Java wrappers for Swift code.")

public static var _commandName: String {
"jextract-swift"
}

public init() {}

@Option(help: "The package the generated Java code should be emitted into.")
var packageName: String
Expand All @@ -49,18 +52,23 @@ public struct SwiftToJava: ParsableCommand {
var input: [String]

public func run() throws {
let inputPaths = self.input.dropFirst().map { URL(string: $0)! }
let inputPaths = self.input.map { URL(string: $0)! }

let translator = Swift2JavaTranslator(
javaPackage: packageName,
swiftModuleName: swiftModule
)
translator.log.logLevel = logLevel

var allFiles: [URL] = []
let fileManager = FileManager.default
let log = translator.log


guard !inputPaths.isEmpty else {
log.warning("Input paths are empty!")
return
}

for path in inputPaths {
log.debug("Input path: \(path)")
if isDirectory(url: path) {
Expand All @@ -74,6 +82,8 @@ public struct SwiftToJava: ParsableCommand {
}
}

log.trace("Input file: \(allFiles)")

for file in allFiles where canExtract(from: file) {
translator.log.debug("Importing module '\(swiftModule)', file: \(file)")

Expand Down
4 changes: 2 additions & 2 deletions Sources/JExtractSwift/Swift2JavaVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,12 @@ extension InitializerDeclSyntax {
let isFailable = self.optionalMark != nil

if isFailable {
log.warning("Skip importing failable initializer: \(self)")
log.debug("Skip importing failable initializer: \(self)")
return false
}

// Ok, import it
log.warning("Import initializer: \(self)")
log.debug("Import initializer: \(self)")
return true
}
}
Expand Down
Loading
Loading