KT-12810 IDL: support special modifiers(e.g. getter and setter)

This commit is contained in:
Sergey Mashkov
2016-08-19 14:32:10 +03:00
parent e1eba8f5c8
commit 8ae5ecf4ff
7 changed files with 155 additions and 63 deletions
+7 -2
View File
@@ -12,7 +12,7 @@ fun generateFunction(repository: Repository, function: Operation, functionName:
function.attributes.map { it.call }.toSet().let { attributes ->
GenerateFunction(
name = functionName,
returnType = mapType(repository, function.returnType).let { mapped -> if (nativeGetterOrSetter == NativeGetterOrSetter.GETTER) mapped.toNullable() else mapped },
returnType = mapType(repository, function.returnType).let { mapped -> if (nativeGetterOrSetter == NativeGetterOrSetter.GETTER) mapped.toNullableIfNonPrimitive() else mapped },
arguments = function.parameters.map {
GenerateAttribute(
name = it.name,
@@ -31,7 +31,12 @@ fun generateFunction(repository: Repository, function: Operation, functionName:
}
fun generateFunctions(repository: Repository, function: Operation): List<GenerateFunction> {
val realFunction = if (function.name == "") null else generateFunction(repository, function, function.name, NativeGetterOrSetter.NONE)
val realFunction = when {
function.name == "" -> null
function.getterOrSetter() == NativeGetterOrSetter.NONE -> generateFunction(repository, function, function.name, NativeGetterOrSetter.NONE)
function.name == "get" || function.name == "set" -> null
else -> generateFunction(repository, function, function.name, NativeGetterOrSetter.NONE)
}
val getterOrSetterFunction = when (function.getterOrSetter()) {
NativeGetterOrSetter.NONE -> null
NativeGetterOrSetter.GETTER -> generateFunction(repository, function, "get")
@@ -63,14 +63,21 @@ private fun Appendable.renderArgumentsDeclaration(args: List<GenerateAttribute>,
StringBuilder().apply { renderAttributeDeclaration(it, it.override, false, omitDefaults) }
}
private fun renderCall(call: GenerateFunctionCall) = "${call.name.replaceKeywords()}(${call.arguments.joinToString(", ") { it.replaceKeywords() }})"
private fun renderCall(call: GenerateFunctionCall) = "${call.name.replaceKeywords()}(${call.arguments.joinToString(separator = ", ", transform = String::replaceKeywords)})"
private fun Appendable.renderFunctionDeclaration(f: GenerateFunction, override: Boolean, commented: Boolean, level: Int = 1) {
indent(commented, level)
if (f.nativeGetterOrSetter == NativeGetterOrSetter.GETTER
&& !f.returnType.nullable
&& f.returnType != DynamicType) {
appendln("@Suppress(\"NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE\")")
indent(commented, level)
}
when (f.nativeGetterOrSetter) {
NativeGetterOrSetter.GETTER -> append("operator @nativeGetter ")
NativeGetterOrSetter.SETTER -> append("operator @nativeSetter ")
NativeGetterOrSetter.GETTER -> { appendln("@nativeGetter"); indent(commented, level); append("operator ") }
NativeGetterOrSetter.SETTER -> { appendln("@nativeSetter"); indent(commented, level); append("operator ") }
NativeGetterOrSetter.NONE -> {}
}
@@ -217,7 +224,9 @@ fun betterFunction(f1: GenerateFunction, f2: GenerateFunction): GenerateFunction
f1.copy(
arguments = f1.arguments
.zip(f2.arguments)
.map { it.first.copy(type = it.map { it.type }.betterType(), name = it.map { it.name }.betterName()) }
.map { it.first.copy(type = it.map { it.type }.betterType(), name = it.map { it.name }.betterName()) },
nativeGetterOrSetter = listOf(f1.nativeGetterOrSetter, f2.nativeGetterOrSetter)
.firstOrNull { it != NativeGetterOrSetter.NONE } ?: NativeGetterOrSetter.NONE
)
private fun <F, T> Pair<F, F>.map(block: (F) -> T) = block(first) to block(second)
@@ -74,3 +74,15 @@ private fun <T: Type> T.withNullabilityImpl(nullable: Boolean): T = if (this.nul
fun <T: Type> T.withNullability(nullable: Boolean): T = withNullabilityImpl(this.nullable or nullable)
fun <T: Type> T.toNullable(): T = withNullabilityImpl(true)
fun <T: Type> T.dropNullable(): T = withNullabilityImpl(false)
@Suppress("UNCHECKED_CAST")
fun <T: Type> T.toNullableIfNonPrimitive(): T = when (this) {
is UnitType -> UnitType
is DynamicType -> DynamicType
is SimpleType -> when (this.type) {
"Int", "Short", "Byte", "Float", "Double", "Boolean", "Long" -> this
else -> this.toNullable()
}
else -> this.toNullable()
} as T