Fix few problems in generation of C bindings. (#1453)
This commit is contained in:
+46
-13
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
|
||||
private enum class ScopeKind {
|
||||
TOP,
|
||||
@@ -87,7 +88,27 @@ private val cKeywords = setOf(
|
||||
"_Alignas", "_Alignof", "_Atomic", "_Generic", "_Noreturn", "_Static_assert", "_Thread_local",
|
||||
// Not exactly keywords, but reserved or standard-defined.
|
||||
"and", "not", "or", "xor",
|
||||
"bool", "complex", "imaginary"
|
||||
"bool", "complex", "imaginary",
|
||||
|
||||
// C++ keywords not listed above.
|
||||
"alignas", "alignof", "and_eq", "asm",
|
||||
"bitand", "bitor", "bool",
|
||||
"catch", "char16_t", "char32_t", "class", "compl", "constexpr", "const_cast",
|
||||
"decltype", "delete", "dynamic_cast",
|
||||
"explicit", "export",
|
||||
"false", "friend",
|
||||
"inline",
|
||||
"mutable",
|
||||
"namespace", "new", "noexcept", "not_eq", "nullptr",
|
||||
"operator", "or_eq",
|
||||
"private", "protected", "public",
|
||||
"reinterpret_cast",
|
||||
"static_assert",
|
||||
"template", "this", "thread_local", "throw", "true", "try", "typeid", "typename",
|
||||
"using",
|
||||
"virtual",
|
||||
"wchar_t",
|
||||
"xor_eq"
|
||||
)
|
||||
|
||||
private val cnameAnnotation = FqName("konan.internal.CName")
|
||||
@@ -253,6 +274,9 @@ private class ExportedElement(val kind: ElementKind,
|
||||
val isClass = declaration is ClassDescriptor && declaration.kind != ClassKind.ENUM_ENTRY
|
||||
val isEnumEntry = declaration is ClassDescriptor && declaration.kind == ClassKind.ENUM_ENTRY
|
||||
|
||||
|
||||
fun KotlinType.includeToSignature() = !this.isUnit()
|
||||
|
||||
fun makeCFunctionSignature(shortName: Boolean): List<Pair<String, ClassDescriptor>> {
|
||||
if (!isFunction) {
|
||||
throw Error("only for functions")
|
||||
@@ -267,9 +291,11 @@ private class ExportedElement(val kind: ElementKind,
|
||||
else -> uniqueName(original, shortName) to TypeUtils.getClassDescriptor(original.returnType!!)!!
|
||||
}
|
||||
val uniqueNames = owner.paramsToUniqueNames(original.explicitParameters)
|
||||
val params = ArrayList(original.explicitParameters.mapIndexed { idx, it ->
|
||||
uniqueNames[idx] to TypeUtils.getClassDescriptor(it.type)!!
|
||||
})
|
||||
val params = ArrayList(original.explicitParameters
|
||||
.filter { it.type.includeToSignature() }
|
||||
.map { it ->
|
||||
uniqueNames[it]!! to TypeUtils.getClassDescriptor(it.type)!!
|
||||
})
|
||||
return listOf(returned) + params
|
||||
}
|
||||
|
||||
@@ -285,9 +311,11 @@ private class ExportedElement(val kind: ElementKind,
|
||||
else -> original.returnType!!
|
||||
}
|
||||
val returnedClass = TypeUtils.getClassDescriptor(returnedType)!!
|
||||
val params = ArrayList(original.allParameters.map {
|
||||
owner.translateTypeBridge(TypeUtils.getClassDescriptor(it.type)!!)
|
||||
})
|
||||
val params = ArrayList(original.allParameters
|
||||
.filter { it.type.includeToSignature() }
|
||||
.map {
|
||||
owner.translateTypeBridge(TypeUtils.getClassDescriptor(it.type)!!)
|
||||
})
|
||||
if (owner.isMappedToReference(returnedClass) || owner.isMappedToString(returnedClass)) {
|
||||
params += "KObjHeader**"
|
||||
}
|
||||
@@ -359,7 +387,9 @@ private class ExportedElement(val kind: ElementKind,
|
||||
"((${owner.translateType(clazz)}){ .pinned = CreateStablePointer(${name})})"
|
||||
}
|
||||
else -> {
|
||||
assert(clazz.isValueType)
|
||||
assert(clazz.isValueType) {
|
||||
println(clazz.toString())
|
||||
}
|
||||
name
|
||||
}
|
||||
}
|
||||
@@ -434,6 +464,9 @@ private class ExportedElement(val kind: ElementKind,
|
||||
val original = descriptor.original
|
||||
addUsedType(original.correspondingProperty.type, set)
|
||||
}
|
||||
is ClassDescriptor -> {
|
||||
set += descriptor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -463,16 +496,16 @@ internal class CAdapterGenerator(
|
||||
private lateinit var outputStreamWriter: PrintWriter
|
||||
private val paramNamesRecorded = mutableMapOf<String, Int>()
|
||||
|
||||
internal fun paramsToUniqueNames(params: List<ParameterDescriptor>): List<String> {
|
||||
internal fun paramsToUniqueNames(params: List<ParameterDescriptor>): Map<ParameterDescriptor, String> {
|
||||
paramNamesRecorded.clear()
|
||||
return params.map {
|
||||
return params.associate {
|
||||
val name = translateName(it.name.asString())
|
||||
val count = paramNamesRecorded.getOrDefault(name, 0)
|
||||
paramNamesRecorded[name] = count + 1
|
||||
if (count == 0) {
|
||||
name
|
||||
it to name
|
||||
} else {
|
||||
"$name${count.toString()}"
|
||||
it to "$name${count.toString()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -671,7 +704,7 @@ internal class CAdapterGenerator(
|
||||
element.isClass ->
|
||||
output("/* Type for ${element.name} = */ ${element.cname}, ", indent)
|
||||
element.isEnumEntry ->
|
||||
output("/* enum entry getter ${element.name} = */ ${element.cname}_impl", indent)
|
||||
output("/* enum entry getter ${element.name} = */ ${element.cname}_impl,", indent)
|
||||
// TODO: handle properties.
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user