Skip elements for which we cannot generate bridge.
This commit is contained in:
committed by
Sergey Bogolepov
parent
81eb6b2be6
commit
8a816adcbe
+29
-15
@@ -12,7 +12,8 @@ class BridgeBuilderResult(
|
|||||||
val kotlinFile: KotlinFile,
|
val kotlinFile: KotlinFile,
|
||||||
val nativeBridges: NativeBridges,
|
val nativeBridges: NativeBridges,
|
||||||
val propertyAccessorBridgeBodies: Map<PropertyAccessor, String>,
|
val propertyAccessorBridgeBodies: Map<PropertyAccessor, String>,
|
||||||
val functionBridgeBodies: Map<FunctionStub, List<String>>
|
val functionBridgeBodies: Map<FunctionStub, List<String>>,
|
||||||
|
val excludedStubs: Set<StubIrElement>
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -64,6 +65,7 @@ class StubIrBridgeBuilder(
|
|||||||
|
|
||||||
private val propertyAccessorBridgeBodies = mutableMapOf<PropertyAccessor, String>()
|
private val propertyAccessorBridgeBodies = mutableMapOf<PropertyAccessor, String>()
|
||||||
private val functionBridgeBodies = mutableMapOf<FunctionStub, List<String>>()
|
private val functionBridgeBodies = mutableMapOf<FunctionStub, List<String>>()
|
||||||
|
private val excludedStubs = mutableSetOf<StubIrElement>()
|
||||||
|
|
||||||
private val bridgeGeneratingVisitor = object : StubIrVisitor<StubContainer?, Unit> {
|
private val bridgeGeneratingVisitor = object : StubIrVisitor<StubContainer?, Unit> {
|
||||||
override fun visitClass(element: ClassStub, owner: StubContainer?) {
|
override fun visitClass(element: ClassStub, owner: StubContainer?) {
|
||||||
@@ -83,11 +85,16 @@ class StubIrBridgeBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunction(element: FunctionStub, owner: StubContainer?) {
|
override fun visitFunction(element: FunctionStub, owner: StubContainer?) {
|
||||||
when {
|
try {
|
||||||
element.external -> tryProcessCCallAnnotation(element)
|
when {
|
||||||
element.isOptionalObjCMethod() -> {}
|
element.external -> tryProcessCCallAnnotation(element)
|
||||||
owner != null && owner.isInterface -> {}
|
element.isOptionalObjCMethod() -> { }
|
||||||
else -> generateBridgeBody(element)
|
owner != null && owner.isInterface -> { }
|
||||||
|
else -> generateBridgeBody(element)
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
context.log("Warning: cannot generate bridge for ${element.name}.")
|
||||||
|
excludedStubs += element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,15 +113,21 @@ class StubIrBridgeBuilder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitProperty(element: PropertyStub, owner: StubContainer?) {
|
override fun visitProperty(element: PropertyStub, owner: StubContainer?) {
|
||||||
when (val kind = element.kind) {
|
try {
|
||||||
is PropertyStub.Kind.Constant -> { }
|
when (val kind = element.kind) {
|
||||||
is PropertyStub.Kind.Val -> {
|
is PropertyStub.Kind.Constant -> {
|
||||||
visitPropertyAccessor(kind.getter, owner)
|
}
|
||||||
}
|
is PropertyStub.Kind.Val -> {
|
||||||
is PropertyStub.Kind.Var -> {
|
visitPropertyAccessor(kind.getter, owner)
|
||||||
visitPropertyAccessor(kind.getter, owner)
|
}
|
||||||
visitPropertyAccessor(kind.setter, owner)
|
is PropertyStub.Kind.Var -> {
|
||||||
|
visitPropertyAccessor(kind.getter, owner)
|
||||||
|
visitPropertyAccessor(kind.setter, owner)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
context.log("Warning: cannot generate bridge for ${element.name}.")
|
||||||
|
excludedStubs += element
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +287,8 @@ class StubIrBridgeBuilder(
|
|||||||
kotlinFile,
|
kotlinFile,
|
||||||
simpleBridgeGenerator.prepare(),
|
simpleBridgeGenerator.prepare(),
|
||||||
propertyAccessorBridgeBodies.toMap(),
|
propertyAccessorBridgeBodies.toMap(),
|
||||||
functionBridgeBodies.toMap()
|
functionBridgeBodies.toMap(),
|
||||||
|
excludedStubs.toSet()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-17
@@ -229,10 +229,7 @@ data class StubIrBuilderResult(
|
|||||||
/**
|
/**
|
||||||
* Produces [StubIrBuilderResult] for given [KotlinPlatform] using [InteropConfiguration].
|
* Produces [StubIrBuilderResult] for given [KotlinPlatform] using [InteropConfiguration].
|
||||||
*/
|
*/
|
||||||
class StubIrBuilder(
|
class StubIrBuilder(private val context: StubIrContext) {
|
||||||
private val context: StubIrContext,
|
|
||||||
private val verbose: Boolean = false
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val configuration = context.configuration
|
private val configuration = context.configuration
|
||||||
private val nativeIndex: NativeIndex = context.nativeIndex
|
private val nativeIndex: NativeIndex = context.nativeIndex
|
||||||
@@ -292,17 +289,11 @@ class StubIrBuilder(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun log(message: String) {
|
|
||||||
if (verbose) {
|
|
||||||
println(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun generateStubsForWrappedMacro(macro: WrappedMacroDef) {
|
private fun generateStubsForWrappedMacro(macro: WrappedMacroDef) {
|
||||||
try {
|
try {
|
||||||
generateStubsForGlobal(GlobalDecl(macro.name, macro.type, isConst = true))
|
generateStubsForGlobal(GlobalDecl(macro.name, macro.type, isConst = true))
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log("Warning: cannot generate stubs for macro ${macro.name}")
|
context.log("Warning: cannot generate stubs for macro ${macro.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +301,7 @@ class StubIrBuilder(
|
|||||||
try {
|
try {
|
||||||
addStubs(MacroConstantStubBuilder(buildingContext, constant).build())
|
addStubs(MacroConstantStubBuilder(buildingContext, constant).build())
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log("Warning: cannot generate stubs for constant ${constant.name}")
|
context.log("Warning: cannot generate stubs for constant ${constant.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +309,7 @@ class StubIrBuilder(
|
|||||||
try {
|
try {
|
||||||
addStubs(EnumStubBuilder(buildingContext, enumDef).build())
|
addStubs(EnumStubBuilder(buildingContext, enumDef).build())
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log("Warning: cannot generate definition for enum ${enumDef.spelling}")
|
context.log("Warning: cannot generate definition for enum ${enumDef.spelling}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +317,7 @@ class StubIrBuilder(
|
|||||||
try {
|
try {
|
||||||
addStubs(FunctionStubBuilder(buildingContext, func).build())
|
addStubs(FunctionStubBuilder(buildingContext, func).build())
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log("Warning: cannot generate stubs for function ${func.name}")
|
context.log("Warning: cannot generate stubs for function ${func.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,7 +325,7 @@ class StubIrBuilder(
|
|||||||
try {
|
try {
|
||||||
addStubs(StructStubBuilder(buildingContext, decl).build())
|
addStubs(StructStubBuilder(buildingContext, decl).build())
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log("Warning: cannot generate definition for struct ${decl.spelling}")
|
context.log("Warning: cannot generate definition for struct ${decl.spelling}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -342,7 +333,7 @@ class StubIrBuilder(
|
|||||||
try {
|
try {
|
||||||
addStubs(TypedefStubBuilder(buildingContext, typedefDef).build())
|
addStubs(TypedefStubBuilder(buildingContext, typedefDef).build())
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log("Warning: cannot generate typedef ${typedefDef.name}")
|
context.log("Warning: cannot generate typedef ${typedefDef.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,7 +341,7 @@ class StubIrBuilder(
|
|||||||
try {
|
try {
|
||||||
addStubs(GlobalStubBuilder(buildingContext, global).build())
|
addStubs(GlobalStubBuilder(buildingContext, global).build())
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log("Warning: cannot generate stubs for global ${global.name}")
|
context.log("Warning: cannot generate stubs for global ${global.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -11,6 +11,7 @@ import java.io.File
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class StubIrContext(
|
class StubIrContext(
|
||||||
|
val log: (String) -> Unit,
|
||||||
val configuration: InteropConfiguration,
|
val configuration: InteropConfiguration,
|
||||||
val nativeIndex: NativeIndex,
|
val nativeIndex: NativeIndex,
|
||||||
val imports: Imports,
|
val imports: Imports,
|
||||||
@@ -85,12 +86,9 @@ class StubIrContext(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StubIrDriver(
|
class StubIrDriver(private val context: StubIrContext) {
|
||||||
private val context: StubIrContext,
|
|
||||||
private val verbose: Boolean = false
|
|
||||||
) {
|
|
||||||
fun run(outKtFile: File, outCFile: File, entryPoint: String?) {
|
fun run(outKtFile: File, outCFile: File, entryPoint: String?) {
|
||||||
val builderResult = StubIrBuilder(context, verbose).build()
|
val builderResult = StubIrBuilder(context).build()
|
||||||
val bridgeBuilderResult = StubIrBridgeBuilder(context, builderResult).build()
|
val bridgeBuilderResult = StubIrBridgeBuilder(context, builderResult).build()
|
||||||
outKtFile.bufferedWriter().use { ktFile ->
|
outKtFile.bufferedWriter().use { ktFile ->
|
||||||
File(outCFile.absolutePath).bufferedWriter().use { cFile ->
|
File(outCFile.absolutePath).bufferedWriter().use { cFile ->
|
||||||
|
|||||||
+4
@@ -215,6 +215,8 @@ class StubIrTextEmitter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunction(element: FunctionStub, owner: StubContainer?) {
|
override fun visitFunction(element: FunctionStub, owner: StubContainer?) {
|
||||||
|
if (element in bridgeBuilderResult.excludedStubs) return
|
||||||
|
|
||||||
val modality = renderMemberModality(element.modality, owner)
|
val modality = renderMemberModality(element.modality, owner)
|
||||||
element.annotations.forEach {
|
element.annotations.forEach {
|
||||||
out(renderAnnotation(it))
|
out(renderAnnotation(it))
|
||||||
@@ -242,6 +244,8 @@ class StubIrTextEmitter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitProperty(element: PropertyStub, owner: StubContainer?) {
|
override fun visitProperty(element: PropertyStub, owner: StubContainer?) {
|
||||||
|
if (element in bridgeBuilderResult.excludedStubs) return
|
||||||
|
|
||||||
val modality = renderMemberModality(element.modality, owner)
|
val modality = renderMemberModality(element.modality, owner)
|
||||||
val receiver = if (element.receiverType != null) "${renderStubType(element.receiverType)}." else ""
|
val receiver = if (element.receiverType != null) "${renderStubType(element.receiverType)}." else ""
|
||||||
val name = if (owner?.isTopLevelContainer == true) {
|
val name = if (owner?.isTopLevelContainer == true) {
|
||||||
|
|||||||
+8
-2
@@ -239,8 +239,14 @@ private fun processCLib(args: Array<String>, additionalArgs: Map<String, Any> =
|
|||||||
File(nativeLibsDir).mkdirs()
|
File(nativeLibsDir).mkdirs()
|
||||||
val outCFile = tempFiles.create(libName, ".${language.sourceFileExtension}")
|
val outCFile = tempFiles.create(libName, ".${language.sourceFileExtension}")
|
||||||
|
|
||||||
val stubIrContext = StubIrContext(configuration, nativeIndex, imports, flavor, libName)
|
val logger = if (verbose) {
|
||||||
val stubIrDriver = StubIrDriver(stubIrContext, verbose)
|
{ message: String -> println(message) }
|
||||||
|
} else {
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
val stubIrContext = StubIrContext(logger, configuration, nativeIndex, imports, flavor, libName)
|
||||||
|
val stubIrDriver = StubIrDriver(stubIrContext)
|
||||||
stubIrDriver.run(outKtFile, File(outCFile.absolutePath), entryPoint)
|
stubIrDriver.run(outKtFile, File(outCFile.absolutePath), entryPoint)
|
||||||
|
|
||||||
// TODO: if a library has partially included headers, then it shouldn't be used as a dependency.
|
// TODO: if a library has partially included headers, then it shouldn't be used as a dependency.
|
||||||
|
|||||||
Reference in New Issue
Block a user