Skip to content
Open
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
3 changes: 1 addition & 2 deletions Plugins/JExtractSwiftPlugin/JExtractSwiftPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
$0.pathExtension == "swift"
}

// Output Swift files are just Java filename based converted to Swift files one-to-one
// Output files are flattened filenames of the inputs, with the appended +SwiftJava suffix.
var outputSwiftFiles: [URL] = swiftFiles.compactMap { sourceFileURL in
guard sourceFileURL.isFileURL else {
return nil as URL?
Expand All @@ -104,7 +104,6 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
fatalError("Could not get relative path for source file \(sourceFilePath)")
}
let outputURL = outputSwiftDirectory
.appending(path: String(sourceFilePath.dropFirst(sourceDir.count).dropLast(sourceFileURL.lastPathComponent.count + 1)))

let inputFileName = sourceFileURL.deletingPathExtension().lastPathComponent
return outputURL.appending(path: "\(inputFileName)+SwiftJava.swift")
Expand Down
4 changes: 4 additions & 0 deletions Plugins/SwiftJavaPlugin/SwiftJavaPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ struct SwiftJavaBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {

let displayName = "Wrapping \(classes.count) Java classes in Swift target '\(sourceModule.name)'"
log("Prepared: \(displayName)")

for f in outputSwiftFiles {
log("Swift output file: \(f)")
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo remove this

commands += [
.buildCommand(
displayName: displayName,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift.org project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

public final class SwiftTypeInSubDirectory {
public init() {}

public func hello() -> Int {
12
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"javaPackage": "com.example.swift"
"javaPackage": "com.example.swift",
"logLevel": "trace"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift.org project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

package com.example.swift;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.swift.swiftkit.core.SwiftLibraries;
import org.swift.swiftkit.ffm.AllocatingSwiftArena;

import java.io.File;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.*;

public class SwiftTypeInSubDirectoryTest {

@Test
void test_MySwiftClass_voidMethod() {
try (var arena = AllocatingSwiftArena.ofConfined()) {
SwiftTypeInSubDirectory o = SwiftTypeInSubDirectory.init(arena);
var num = o.hello();
assertEquals(12, num);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift.org project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

public final class SwiftTypeInSubDirectory {
public init() {}

public func hello() -> Int {
12
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"javaPackage": "com.example.swift",
"mode": "jni",
"logLevel": ["debug"]
"logLevel": "debug"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Swift.org project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

package com.example.swift;

import org.junit.jupiter.api.Test;
import org.swift.swiftkit.core.SwiftArena;

import static org.junit.jupiter.api.Assertions.*;

public class SwiftTypeInSubDirectoryTest {

@Test
void test_SwiftTypeInSubDirectory_hello() {
try (var arena = SwiftArena.ofConfined()) {
SwiftTypeInSubDirectory o = SwiftTypeInSubDirectory.init(arena);
var num = o.hello();
assertEquals(12, num);
}
}

}
6 changes: 5 additions & 1 deletion Sources/JExtractSwiftLib/CodePrinter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

import Foundation

let PATH_SEPARATOR = "/" // TODO: Windows
#if os(Windows)
let PATH_SEPARATOR = "\\"
#else
let PATH_SEPARATOR = "/"
#endif

public struct CodePrinter {
var contents: String = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@ extension FFMSwift2JavaGenerator {
}

package func writeSwiftExpectedEmptySources() throws {
let pendingFileCount = self.expectedOutputSwiftFiles.count
let pendingFileCount = self.expectedOutputSwiftFileNames.count
guard pendingFileCount > 0 else {
return // no need to write any empty files, yay
}

print("[swift-java] Write empty [\(self.expectedOutputSwiftFiles.count)] 'expected' files in: \(swiftOutputDirectory)/")
log.info("[swift-java] Write empty [\(self.expectedOutputSwiftFileNames.count)] 'expected' files in: \(swiftOutputDirectory)/")

for expectedFileName in self.expectedOutputSwiftFiles {
log.debug("Write SwiftPM-'expected' empty file: \(expectedFileName.bold)")

for expectedFileName in self.expectedOutputSwiftFileNames {
log.info("Write SwiftPM-'expected' empty file: \(expectedFileName.bold)")

var printer = CodePrinter()
printer.print("// Empty file generated on purpose")
Expand All @@ -55,7 +54,7 @@ extension FFMSwift2JavaGenerator {
javaPackagePath: nil,
filename: moduleFilename) {
log.info("Generated: \(moduleFilenameBase.bold).swift (at \(outputFile.absoluteString))")
self.expectedOutputSwiftFiles.remove(moduleFilename)
self.expectedOutputSwiftFileNames.remove(moduleFilename)
}
} catch {
log.warning("Failed to write to Swift thunks: \(moduleFilename)")
Expand Down Expand Up @@ -93,7 +92,9 @@ extension FFMSwift2JavaGenerator {
javaPackagePath: nil,
filename: filename) {
log.info("Done writing Swift thunks to: \(outputFile.absoluteString)")
self.expectedOutputSwiftFiles.remove(filename)
// log.info("REMOVE FROM: \(expectedOutputSwiftFileNames)")
// log.info("REMOVE FROM THE: \(filename)")
self.expectedOutputSwiftFileNames.remove(filename)
}
} catch {
log.warning("Failed to write to Swift thunks: \(filename), error: \(error)")
Expand Down
28 changes: 19 additions & 9 deletions Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ package class FFMSwift2JavaGenerator: Swift2JavaGenerator {

/// Because we need to write empty files for SwiftPM, keep track which files we didn't write yet,
/// and write an empty file for those.
var expectedOutputSwiftFiles: Set<String>
///
/// Since Swift files in SwiftPM builds needs to be unique, we use this fact to flatten paths into plain names here.
/// For uniqueness checking "did we write this file already", just checking the name should be sufficient.
var expectedOutputSwiftFileNames: Set<String>

package init(
config: Configuration,
Expand All @@ -57,19 +60,26 @@ package class FFMSwift2JavaGenerator: Swift2JavaGenerator {
self.javaOutputDirectory = javaOutputDirectory
self.lookupContext = translator.lookupContext

// If we are forced to write empty files, construct the expected outputs
// If we are forced to write empty files, construct the expected outputs.
// It is sufficient to use file names only, since SwiftPM requires names to be unique within a module anyway.
if translator.config.writeEmptyFiles ?? false {
self.expectedOutputSwiftFiles = Set(translator.inputs.compactMap { (input) -> String? in
guard let filePathPart = input.path.split(separator: "/\(translator.swiftModuleName)/").last else {
self.expectedOutputSwiftFileNames = Set(translator.inputs.compactMap { (input) -> String? in
// guard let filePathPart = input.path.split(separator: "/\(translator.swiftModuleName)/").last else {
// return nil
// }
// return String(filePathPart.replacing(".swift", with: "+SwiftJava.swift"))
guard let fileName = input.path.split(separator: PATH_SEPARATOR).last else {
return nil
}

return String(filePathPart.replacing(".swift", with: "+SwiftJava.swift"))
guard fileName.hasSuffix(".swift") else {
return nil
}
return String(fileName.replacing(".swift", with: "+SwiftJava.swift"))
})
self.expectedOutputSwiftFiles.insert("\(translator.swiftModuleName)Module+SwiftJava.swift")
self.expectedOutputSwiftFiles.insert("Foundation+SwiftJava.swift")
self.expectedOutputSwiftFileNames.insert("\(translator.swiftModuleName)Module+SwiftJava.swift")
self.expectedOutputSwiftFileNames.insert("Foundation+SwiftJava.swift")
} else {
self.expectedOutputSwiftFiles = []
self.expectedOutputSwiftFileNames = []
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ extension JNISwift2JavaGenerator {
}

package func writeSwiftExpectedEmptySources() throws {
let pendingFileCount = self.expectedOutputSwiftFiles.count
let pendingFileCount = self.expectedOutputSwiftFileNames.count
guard pendingFileCount > 0 else {
return // no need to write any empty files, yay
}
print("[swift-java] Write empty [\(self.expectedOutputSwiftFiles.count)] 'expected' files in: \(swiftOutputDirectory)/")
for expectedFileName in self.expectedOutputSwiftFiles {
logger.debug("Write SwiftPM-'expected' empty file: \(expectedFileName.bold)")

logger.info("[swift-java] Write empty [\(self.expectedOutputSwiftFileNames.count)] 'expected' files in: \(swiftOutputDirectory)/")

for expectedFileName in self.expectedOutputSwiftFileNames {
logger.info("Write SwiftPM-'expected' empty file: \(expectedFileName.bold)")


var printer = CodePrinter()
Expand All @@ -61,7 +61,7 @@ extension JNISwift2JavaGenerator {
filename: moduleFilename
) {
logger.info("Generated: \(moduleFilenameBase.bold).swift (at \(outputFile.absoluteString))")
self.expectedOutputSwiftFiles.remove(moduleFilename)
self.expectedOutputSwiftFileNames.remove(moduleFilename)
}

// === All types
Expand Down Expand Up @@ -96,7 +96,7 @@ extension JNISwift2JavaGenerator {
javaPackagePath: nil,
filename: filename) {
logger.info("Done writing Swift thunks to: \(outputFile.absoluteString)")
self.expectedOutputSwiftFiles.remove(filename)
self.expectedOutputSwiftFileNames.remove(filename)
}
} catch {
logger.warning("Failed to write to Swift thunks: \(filename), error: \(error)")
Expand Down
30 changes: 20 additions & 10 deletions Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ package class JNISwift2JavaGenerator: Swift2JavaGenerator {

/// Because we need to write empty files for SwiftPM, keep track which files we didn't write yet,
/// and write an empty file for those.
var expectedOutputSwiftFiles: Set<String>
///
/// Since Swift files in SwiftPM builds needs to be unique, we use this fact to flatten paths into plain names here.
/// For uniqueness checking "did we write this file already", just checking the name should be sufficient.
var expectedOutputSwiftFileNames: Set<String>

package init(
config: Configuration,
Expand All @@ -64,27 +67,34 @@ package class JNISwift2JavaGenerator: Swift2JavaGenerator {
self.javaClassLookupTable = javaClassLookupTable
self.lookupContext = translator.lookupContext

// If we are forced to write empty files, construct the expected outputs
// If we are forced to write empty files, construct the expected outputs.
// It is sufficient to use file names only, since SwiftPM requires names to be unique within a module anyway.
if translator.config.writeEmptyFiles ?? false {
self.expectedOutputSwiftFiles = Set(translator.inputs.compactMap { (input) -> String? in
guard let filePathPart = input.path.split(separator: "/\(translator.swiftModuleName)/").last else {
self.expectedOutputSwiftFileNames = Set(translator.inputs.compactMap { (input) -> String? in
// guard let filePathPart = input.path.split(separator: "/\(translator.swiftModuleName)/").last else {
// return nil
// }
// return String(filePathPart.replacing(".swift", with: "+SwiftJava.swift"))
guard let fileName = input.path.split(separator: PATH_SEPARATOR).last else {
return nil
}

return String(filePathPart.replacing(".swift", with: "+SwiftJava.swift"))
guard fileName.hasSuffix(".swift") else {
return nil
}
return String(fileName.replacing(".swift", with: "+SwiftJava.swift"))
})
self.expectedOutputSwiftFiles.insert("\(translator.swiftModuleName)Module+SwiftJava.swift")
self.expectedOutputSwiftFiles.insert("Foundation+SwiftJava.swift")
self.expectedOutputSwiftFileNames.insert("\(translator.swiftModuleName)Module+SwiftJava.swift")
self.expectedOutputSwiftFileNames.insert("Foundation+SwiftJava.swift")
} else {
self.expectedOutputSwiftFiles = []
self.expectedOutputSwiftFileNames = []
}
}

func generate() throws {
try writeSwiftThunkSources()
try writeExportedJavaSources()

let pendingFileCount = self.expectedOutputSwiftFiles.count
let pendingFileCount = self.expectedOutputSwiftFileNames.count
if pendingFileCount > 0 {
print("[swift-java] Write empty [\(pendingFileCount)] 'expected' files in: \(swiftOutputDirectory)/")
try writeSwiftExpectedEmptySources()
Expand Down
Loading