Skip to content

Commit 83390a6

Browse files
authored
wrap-java: add the ability to filter exclude specific methods (#529)
1 parent 2343254 commit 83390a6

4 files changed

Lines changed: 36 additions & 7 deletions

File tree

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+SwiftThunkPrinting.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ extension JNISwift2JavaGenerator {
3131
return // no need to write any empty files, yay
3232
}
3333

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

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

Sources/SwiftJavaTool/Commands/WrapJavaCommand.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,10 @@ extension SwiftJava.WrapJavaCommand {
339339
let anyIncludeFilterMatched = includes.contains { include in
340340
if javaClassName.starts(with: include) {
341341
// TODO: lower to trace level
342-
log.info("Skip Java type: \(javaClassName) (does not match any include filter)")
343342
return true
344343
}
345344

345+
log.info("Skip Java type: \(javaClassName) (does not match any include filter)")
346346
return false
347347
}
348348

@@ -362,4 +362,5 @@ extension SwiftJava.WrapJavaCommand {
362362
// The class matches import filters, if any, and was not excluded.
363363
return true
364364
}
365+
365366
}

Sources/SwiftJavaTool/CommonOptions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ extension SwiftJava {
6565
@Option(name: .long, help: "While scanning a classpath, inspect ONLY types included in these packages")
6666
var filterInclude: [String] = []
6767

68-
@Option(name: .long, help: "While scanning a classpath, skip types which match the filter prefix")
68+
@Option(name: .long, help: "While scanning a classpath, skip types which match the filter prefix. You can exclude specific methods by using the `com.example.MyClass#method` format.")
6969
var filterExclude: [String] = []
7070

7171
@Option(help: "A path to a custom swift-java.config to use")

Sources/SwiftJavaToolLib/JavaClassTranslator.swift

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ struct JavaClassTranslator {
214214
for method in methods {
215215
guard let method else { continue }
216216

217-
guard shouldExtract(method: method) else {
217+
guard shouldExtract(method: method, config: translator.config) else {
218218
continue
219219
}
220220

@@ -257,7 +257,34 @@ extension JavaClassTranslator {
257257

258258
/// Determines whether a method should be extracted for translation.
259259
/// Only look at public and protected methods here.
260-
private func shouldExtract(method: Method) -> Bool {
260+
private func shouldExtract(method: Method, config: Configuration) -> Bool {
261+
// Check exclude filters, if they're applicable to methods:
262+
for exclude in config.filterExclude ?? [] where exclude.contains("#") {
263+
let split = exclude.split(separator: "#")
264+
guard split.count == 2 else {
265+
self.log.warning("Malformed method exclude filter, must have only one '#' marker: \(exclude)")
266+
continue // cannot use this filter, malformed
267+
}
268+
269+
let javaClassName = method.getDeclaringClass().getName()
270+
let javaMemberName = method.getName()
271+
272+
let className = split.first!
273+
let excludedName = split.dropFirst().first!
274+
275+
self.log.warning("Exclude filter: \(exclude) ||| \(javaClassName) / \(javaMemberName)")
276+
277+
if javaClassName.starts(with: className) {
278+
if excludedName.hasSuffix("*"), javaMemberName.starts(with: excludedName.dropLast()) {
279+
log.info("Skip Java member '\(javaClassName)#\(javaMemberName)', prefix exclude matched: \(exclude)")
280+
return false
281+
} else if javaMemberName == excludedName {
282+
log.info("Skip Java member '\(javaClassName)#\(javaMemberName)', exact exclude matched: \(exclude)")
283+
return false
284+
}
285+
}
286+
}
287+
261288
switch self.translator.config.effectiveMinimumInputAccessLevelMode {
262289
case .internal:
263290
return method.isPublic || method.isProtected || method.isPackage
@@ -579,7 +606,8 @@ extension JavaClassTranslator {
579606
package func renderConstructor(
580607
_ javaConstructor: Constructor<some AnyJavaObject>
581608
) throws -> DeclSyntax {
582-
let parameters = try translateJavaParameters(javaConstructor.getParameters()) + ["environment: JNIEnvironment? = nil"]
609+
let parameters: [FunctionParameterSyntax]
610+
parameters = try translateJavaParameters(javaConstructor.getParameters()) + ["environment: JNIEnvironment? = nil"]
583611
let parametersStr = parameters.map { $0.description }.joined(separator: ", ")
584612
let throwsStr = javaConstructor.throwsCheckedException ? "throws" : ""
585613
let accessModifier = javaConstructor.isPublic ? "public " : ""
@@ -987,7 +1015,7 @@ extension JavaClassTranslator {
9871015
continue
9881016
}
9891017

990-
guard shouldExtract(method: overriddenMethod) else {
1018+
guard shouldExtract(method: overriddenMethod, config: translator.config) else {
9911019
continue
9921020
}
9931021

0 commit comments

Comments
 (0)