Skip to content
Merged
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: 4 additions & 0 deletions Plugins/PluginsShared/SwiftJavaPluginProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ extension SwiftJavaPluginProtocol {
func log(_ message: @autoclosure () -> String, terminator: String = "\n") {
print("[\(pluginName)] \(message())", terminator: terminator)
}

func warn(_ message: @autoclosure () -> String, terminator: String = "\n") {
print("[\(pluginName)][warning] \(message())", terminator: terminator)
}
}
58 changes: 34 additions & 24 deletions Plugins/SwiftJavaPlugin/SwiftJavaPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -242,30 +242,40 @@ extension SwiftJavaBuildToolPlugin {
func outputFilePath(context: PluginContext, generated: Bool, filename: String) -> URL {
outputDirectory(context: context, generated: generated).appending(path: filename)
}
}

func getExtractedJavaStdlibModules() -> [String] {
let fileManager = FileManager.default
let sourcesPath = URL(fileURLWithPath: #filePath)
.deletingLastPathComponent()
.deletingLastPathComponent()
.appendingPathComponent("Sources")
.appendingPathComponent("JavaStdlib")

guard let stdlibDirContents = try? fileManager.contentsOfDirectory(
at: sourcesPath,
includingPropertiesForKeys: [.isDirectoryKey],
options: [.skipsHiddenFiles]
) else {
return []
}

return stdlibDirContents.compactMap { url in
guard let resourceValues = try? url.resourceValues(forKeys: [.isDirectoryKey]),
let isDirectory = resourceValues.isDirectory,
isDirectory else {
return nil
func getExtractedJavaStdlibModules() -> [String] {
let fileManager = FileManager.default
log("Search for JavaStdlib inside: \(#filePath)")
let sourcesPath = URL(fileURLWithPath: #filePath)
.deletingLastPathComponent()
.deletingLastPathComponent()
.deletingLastPathComponent()
.appendingPathComponent("Sources")
.appendingPathComponent("JavaStdlib")

guard let stdlibDirContents = try? fileManager.contentsOfDirectory(
at: sourcesPath,
includingPropertiesForKeys: [.isDirectoryKey],
options: [.skipsHiddenFiles]
) else {
warn("Unable to find Java standard library Swift wrappers! Expected \(sourcesPath) to exist." +
"May be unable to wrap-java types involving Java standard library types.")
return []
}
return url.lastPathComponent
}.sorted()

return stdlibDirContents.compactMap { url in
let swiftJavaConfigURL = url.appending(path: "swift-java.config")
guard fileManager.fileExists(atPath: swiftJavaConfigURL.absoluteString) else {
warn("Expected JavaStdlib directory \(url) to contain swift-java.config but it was missing!")
return nil
}

guard let resourceValues = try? url.resourceValues(forKeys: [.isDirectoryKey]),
let isDirectory = resourceValues.isDirectory,
isDirectory else {
return nil
}
return url.lastPathComponent
}.sorted()
}
}
2 changes: 1 addition & 1 deletion Sources/SwiftJavaTool/Commands/WrapJavaCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ extension SwiftJava.WrapJavaCommand {
// Load all of the dependent configurations and associate them with Swift modules.
let dependentConfigs = try loadDependentConfigs(dependsOn: self.dependsOn).map { moduleName, config in
guard let moduleName else {
throw JavaToSwiftError.badConfigOption
throw JavaToSwiftError.badConfigOption(self.dependsOn.joined(separator: " "))
}
return (moduleName, config)
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/SwiftJavaTool/SwiftJava.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,14 @@ struct SwiftJava: AsyncParsableCommand {
}

enum JavaToSwiftError: Error {
case badConfigOption
case badConfigOption(String)
}

extension JavaToSwiftError: CustomStringConvertible {
var description: String {
switch self {
case .badConfigOption:
"configuration option must be of the form '<swift module name>=<path to config file>"
case .badConfigOption(let string):
"configuration option must be of the form '<swift module name>=<path to config file>. Was: \(string)"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,4 +198,46 @@ final class BasicWrapJavaTests: XCTestCase {
]
)
}

func test_wrapJava_inheritFromBiFunction() async throws {
let classpathURL = try await compileJava(
"""
package com.example;

import java.util.function.BiFunction;

interface CallMe<ValueType> extends BiFunction<ValueType, ValueType, ValueType> {
@Override
ValueType apply(
ValueType newest,
ValueType oldest
);
}
""")

try assertWrapJavaOutput(
javaClassNames: [
"java.util.function.BiFunction",
"com.example.CallMe",
],
classpath: [classpathURL],
expectedChunks: [
"""
@JavaInterface("com.example.CallMe", extends: BiFunction<ValueType, ValueType, ValueType>.self)
public struct CallMe<ValueType: AnyJavaObject> {
/**
* Java method `apply`.
*
* ### Java method signature
* ```java
* public abstract ValueType com.example.CallMe.apply(ValueType,ValueType)
* ```
*/
@JavaMethod(typeErasedResult: "ValueType!")
public func apply(_ arg0: ValueType?, _ arg1: ValueType?) -> ValueType!
}
""",
]
)
}
}
Loading