Skip to content

[jextract] Prepare all inputs before analyze() #222

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

Merged
merged 1 commit into from
Apr 16, 2025
Merged
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
23 changes: 15 additions & 8 deletions Sources/JExtractSwift/Swift2Java.swift
Original file line number Diff line number Diff line change
@@ -74,16 +74,23 @@ public struct SwiftToJava: ParsableCommand {
}
}

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

try translator.analyze(file: file.path)
try translator.writeExportedJavaSources(outputDirectory: outputDirectoryJava)
try translator.writeSwiftThunkSources(outputDirectory: outputDirectorySwift)

log.debug("[swift-java] Imported interface file: \(file.path)")
// Register files to the translator.
for file in allFiles {
guard canExtract(from: file) else {
continue
}
guard let data = fileManager.contents(atPath: file.path) else {
continue
}
guard let text = String(data:data, encoding: .utf8) else {
continue
}
translator.add(filePath: file.path, text: text)
}

try translator.analyze()
try translator.writeSwiftThunkSources(outputDirectory: outputDirectorySwift)
try translator.writeExportedJavaSources(outputDirectory: outputDirectoryJava)
try translator.writeExportedJavaModule(outputDirectory: outputDirectoryJava)
print("[swift-java] Generated Java sources (\(packageName)) in: \(outputDirectoryJava)/")
print("[swift-java] Imported Swift module '\(swiftModule)': " + "done.".green)
50 changes: 29 additions & 21 deletions Sources/JExtractSwift/Swift2JavaTranslator.swift
Original file line number Diff line number Diff line change
@@ -24,6 +24,15 @@ public final class Swift2JavaTranslator {

package var log = Logger(label: "translator", logLevel: .info)

// ==== Input

struct Input {
let filePath: String
let syntax: Syntax
}

var inputs: [Input] = []

// ==== Output configuration
let javaPackage: String

@@ -39,7 +48,7 @@ public final class Swift2JavaTranslator {
/// type representation.
package var importedTypes: [String: ImportedNominalType] = [:]

public var swiftStdlibTypes: SwiftStandardLibraryTypes
package var swiftStdlibTypes: SwiftStandardLibraryTypes

let symbolTable: SwiftSymbolTable
let nominalResolution: NominalTypeResolution = NominalTypeResolution()
@@ -78,43 +87,42 @@ extension Swift2JavaTranslator {
/// a checked truncation operation at the Java/Swift board.
var javaPrimitiveForSwiftInt: JavaType { .long }

public func analyze(
package func add(filePath: String, text: String) {
log.trace("Adding: \(filePath)")
let sourceFileSyntax = Parser.parse(source: text)
self.nominalResolution.addSourceFile(sourceFileSyntax)
self.inputs.append(Input(filePath: filePath, syntax: Syntax(sourceFileSyntax)))
}

/// Convenient method for analyzing single file.
package func analyze(
file: String,
text: String? = nil
text: String
) throws {
guard text != nil || FileManager.default.fileExists(atPath: file) else {
throw Swift2JavaTranslatorError(message: "Missing input file: \(file)")
}

log.trace("Analyze: \(file)")
let text = try text ?? String(contentsOfFile: file)

try analyzeSwiftInterface(interfaceFilePath: file, text: text)

log.debug("Done processing: \(file)")
self.add(filePath: file, text: text)
try self.analyze()
}

package func analyzeSwiftInterface(interfaceFilePath: String, text: String) throws {
let sourceFileSyntax = Parser.parse(source: text)

addSourceFile(sourceFileSyntax)
/// Analyze registered inputs.
func analyze() throws {
prepareForTranslation()

let visitor = Swift2JavaVisitor(
moduleName: self.swiftModuleName,
targetJavaPackage: self.javaPackage,
translator: self
)
visitor.walk(sourceFileSyntax)
}

package func addSourceFile(_ sourceFile: SourceFileSyntax) {
nominalResolution.addSourceFile(sourceFile)
for input in self.inputs {
log.trace("Analyzing \(input.filePath)")
visitor.walk(input.syntax)
}
}

package func prepareForTranslation() {
nominalResolution.bindExtensions()

// Prepare symbol table for nominal type names.
for (_, node) in nominalResolution.topLevelNominalTypes {
symbolTable.parsedModule.addNominalTypeDeclaration(node, parent: nil)
}
4 changes: 2 additions & 2 deletions Tests/JExtractSwiftTests/Asserts/LoweringAssertions.swift
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ func assertLoweredFunction(
_ inputDecl: DeclSyntax,
javaPackage: String = "org.swift.mypackage",
swiftModuleName: String = "MyModule",
sourceFile: SourceFileSyntax? = nil,
sourceFile: String? = nil,
enclosingType: TypeSyntax? = nil,
expectedCDecl: DeclSyntax,
expectedCFunction: String,
@@ -37,7 +37,7 @@ func assertLoweredFunction(
)

if let sourceFile {
translator.addSourceFile(sourceFile)
translator.add(filePath: "Fake.swift", text: sourceFile)
}

translator.prepareForTranslation()