From 270fab189fba6a04620bb1487cf4aa420d1a9007 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 21 Jul 2016 19:06:12 +0300 Subject: [PATCH] translator: add function extensions --- .../kotlinnative/translator/BlockCodegen.kt | 57 +++++++++++++++---- .../kotlinnative/translator/FileTranslator.kt | 1 + .../translator/FunctionCodegen.kt | 27 +++++++-- .../translator/ProjectTranslator.kt | 9 +-- .../translator/PropertyCodegen.kt | 4 +- .../kotlinnative/translator/StructCodegen.kt | 6 +- .../translator/TranslationState.kt | 1 + .../translator/llvm/generators.kt | 7 ++- .../translator/llvm/types/LLVMBooleanType.kt | 1 + .../translator/llvm/types/LLVMByteType.kt | 1 + .../translator/llvm/types/LLVMCharType.kt | 1 + .../translator/llvm/types/LLVMDoubleType.kt | 1 + .../translator/llvm/types/LLVMFunctionType.kt | 4 +- .../translator/llvm/types/LLVMIntType.kt | 1 + .../translator/llvm/types/LLVMShortType.kt | 1 + .../translator/llvm/types/LLVMType.kt | 1 + .../tests/input/function_extensions_1.txt | 1 + .../tests/kotlin/function_extensions_1.kt | 7 +++ 18 files changed, 103 insertions(+), 28 deletions(-) create mode 100644 translator/src/test/kotlin/tests/input/function_extensions_1.txt create mode 100644 translator/src/test/kotlin/tests/kotlin/function_extensions_1.kt diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index a93441c12b0..4a4ff961346 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -68,6 +68,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, expr) is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr) is KtReturnExpression -> evaluateReturnInstruction(expr.firstChild, scopeDepth) + is KtThisExpression -> evaluateThisExpression(expr, scopeDepth) is PsiWhiteSpace -> null is PsiElement -> evaluatePsiElement(expr, scopeDepth) null -> null @@ -75,6 +76,10 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM } } + private fun evaluateThisExpression(expr: KtThisExpression, scopeDepth: Int): LLVMSingleValue? { + return variableManager.getLLVMvalue("this") + } + fun evaluateStringTemplateExpression(expr: KtStringTemplateExpression): LLVMSingleValue? { val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr) val type = (receiveValue as TypedCompileTimeConstant).type @@ -87,11 +92,12 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM private fun evaluateCallableReferenceExpression(expr: KtCallableReferenceExpression): LLVMSingleValue? { val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!! - return LLVMMapStandardType(expr.text.substring(2), kotlinType, LLVMVariableScope()) + return LLVMInstanceOfStandardType(expr.text.substring(2), kotlinType, LLVMVariableScope()) } private fun evaluateDotExpression(expr: KtDotQualifiedExpression, scopeDepth: Int): LLVMSingleValue? { - val receiverName = expr.receiverExpression.text + val receiverExpr = expr.receiverExpression + val receiverName = receiverExpr.text val selectorExpr = expr.selectorExpression!! var receiver = variableManager.getLLVMvalue(receiverName) @@ -99,13 +105,37 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM if (receiver.pointer == 2) { receiver = codeBuilder.loadAndGetVariable(receiver) } - return evaluateMemberMethodOrField(receiver, selectorExpr.text, scopeDepth, expr.lastChild) + when (receiver.type) { + is LLVMReferenceType -> return evaluateMemberMethodOrField(receiver, selectorExpr.text, scopeDepth, expr.lastChild) + else -> return evaluateExtensionExpression(receiverExpr, selectorExpr as KtCallExpression, scopeDepth) + } } - val clazz = state.classes[receiverName] ?: return null + val clazz = state.classes[receiverName] ?: return evaluateExtensionExpression(receiverExpr, selectorExpr as KtCallExpression, scopeDepth) + return evaluateClassScopedDotExpression(clazz, selectorExpr, scopeDepth) } + private fun evaluateExtensionExpression(receiver: KtExpression, selector: KtCallExpression, scopeDepth: Int): LLVMSingleValue? { + val receiverType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver) + val standartType = LLVMMapStandardType(receiverType!!.type!!) + val function = selector.firstChild.firstChild.text + val names = parseArgList(selector, scopeDepth) + val extensionCodegen = state.extensionFunctions[standartType.toString()]!![function]!! + val receiverExpression = evaluateExpression(receiver, scopeDepth + 1)!! + + val typeThisArgument = when (standartType) { + is LLVMReferenceType -> LLVMVariable("type", standartType, pointer = 1) + else -> LLVMVariable("type", standartType, pointer = 0) + } + + val args = mutableListOf(loadArgumentIfRequired(receiverExpression, typeThisArgument)) + + args.addAll(loadArgsIfRequired(names, extensionCodegen.args)) + + return evaluateFunctionCallExpression(LLVMVariable(extensionCodegen.fullName, extensionCodegen.returnType!!.type, scope = LLVMVariableScope()), args) + } + private fun evaluateClassScopedDotExpression(clazz: ClassCodegen, selector: KtExpression, scopeDepth: Int): LLVMSingleValue? = when (selector) { is KtCallExpression -> evaluateCallExpression(selector, scopeDepth, clazz) @@ -266,16 +296,21 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM return null } - private fun loadArgsIfRequired(names: List, args: List) = names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue { + private fun loadArgumentIfRequired(value: LLVMSingleValue, argument: LLVMVariable): LLVMSingleValue { var result = value - if (result.pointer > 0 && args[i].pointer == 0) { - result = codeBuilder.getNewVariable(args[i].type) + if (result.pointer > 0 && argument.pointer == 0) { + result = codeBuilder.getNewVariable(argument.type) codeBuilder.loadVariable(result, value as LLVMVariable) } return result - }).toList() + } + + private fun loadArgsIfRequired(names: List, args: List) = + names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue { + return loadArgumentIfRequired(value, args[i]) + }).toList() private fun evaluateConstructorCallExpression(function: LLVMVariable, names: List): LLVMSingleValue? { val store = codeBuilder.getNewVariable(function.type) @@ -457,7 +492,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM codeBuilder.addComment("start when expression") val whenExpression = expr.subjectExpression val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!! - val expressionType = LLVMMapStandardType("type", kotlinType, LLVMVariableScope()).type + val expressionType = LLVMMapStandardType(kotlinType) val targetExpression = evaluateExpression(whenExpression, scopeDepth + 1)!! @@ -524,7 +559,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM private fun executeIfExpression(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, ifExpression: KtIfExpression, scopeDepth: Int): LLVMVariable? { val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1) val kotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, ifExpression)!!.type!! - val expressionType = LLVMMapStandardType("type", kotlinType, LLVMVariableScope()).type + val expressionType = LLVMInstanceOfStandardType("type", kotlinType, LLVMVariableScope()).type val resultVariable = codeBuilder.getNewVariable(expressionType, pointer = 1) codeBuilder.allocStackPointedVarAsValue(resultVariable) val thenLabel = codeBuilder.getNewLabel(prefix = "if") @@ -586,7 +621,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM } is LLVMConstant -> { if (assignExpression.type is LLVMNullType) { - val reference = LLVMMapStandardType(identifier, variable.type) + val reference = LLVMInstanceOfStandardType(identifier, variable.type) if (state.classes.containsKey(variable.type.toString().dropLast(1))) { (reference.type as LLVMReferenceType).prefix = "class" } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt index ffd8f50188c..6359f9e2f46 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt @@ -1,6 +1,7 @@ package org.kotlinnative.translator import org.jetbrains.kotlin.psi.* +import org.kotlinnative.translator.debug.printFile class FileTranslator(val state: TranslationState, val file: KtFile) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index f8204a2cd42..a2937975465 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -2,6 +2,7 @@ package org.kotlinnative.translator import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments +import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration import org.jetbrains.kotlin.resolve.BindingContext import org.kotlinnative.translator.llvm.* import org.kotlinnative.translator.llvm.types.LLVMFunctionType @@ -20,15 +21,18 @@ class FunctionCodegen(override val state: TranslationState, var name = function.fqName.toString() var args = LinkedList() + val isExtensionDeclaration = function.isExtensionDeclaration() + var functionNamePrefix = "" + val fullName: String + get() = functionNamePrefix + name init { val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!! args.addAll(descriptor.valueParameters.map { - LLVMMapStandardType(it.name.toString(), it.type) + LLVMInstanceOfStandardType(it.name.toString(), it.type) }) - - returnType = LLVMMapStandardType("instance", descriptor.returnType!!) + returnType = LLVMInstanceOfStandardType("instance", descriptor.returnType!!) val retType = returnType!!.type when (retType) { is LLVMReferenceType -> { @@ -88,13 +92,28 @@ class FunctionCodegen(override val state: TranslationState, actualArgs.add(returnType!!) } + if (isExtensionDeclaration) { + val receiverParameter = state.bindingContext.get(BindingContext.FUNCTION, function)!!.extensionReceiverParameter!! + val receiverType = receiverParameter.type + val translatorType = LLVMMapStandardType(receiverType) + + val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType, HashMap()) + extensionFunctionsOfThisType.put(name, this) + state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType) + + val classVal = LLVMVariable("classvariable.this", translatorType, pointer = 0) + variableManager.addVariable("this", classVal, 0) + actualArgs.add(classVal) + functionNamePrefix += translatorType.toString() + "." + } + if (this_type != null) { actualArgs.add(this_type) } actualArgs.addAll(args) - codeBuilder.addLLVMCode(LLVMFunctionDescriptor(function.fqName.toString(), actualArgs, actualReturnType, external, state.arm)) + codeBuilder.addLLVMCode(LLVMFunctionDescriptor(fullName, actualArgs, actualReturnType, external, state.arm)) return external } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt index b77299d4f1d..d1a7635269c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt @@ -1,8 +1,5 @@ package org.kotlinnative.translator -import org.jetbrains.kotlin.psi.* -import org.kotlinnative.translator.llvm.LLVMBuilder - class ProjectTranslator(val state: TranslationState) { private var codeBuilder = state.codeBuilder @@ -25,7 +22,11 @@ class ProjectTranslator(val state: TranslationState) { clazz.generate() } - for (function in state.functions.values) { + for (function in state.functions.values.filter { it.isExtensionDeclaration }) { + function.generate() + } + + for (function in state.functions.values.filter { !it.isExtensionDeclaration }) { function.generate() } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt index 358b2df2e1d..78f50d0a2d4 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt @@ -4,7 +4,7 @@ import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.resolve.BindingContext import org.kotlinnative.translator.llvm.LLVMBuilder -import org.kotlinnative.translator.llvm.LLVMMapStandardType +import org.kotlinnative.translator.llvm.LLVMInstanceOfStandardType import org.kotlinnative.translator.llvm.LLVMVariable import org.kotlinnative.translator.llvm.LLVMVariableScope @@ -17,7 +17,7 @@ class PropertyCodegen(val state: TranslationState, val variableManager: Variable val kotlinType = varInfo.type val value = varInfo.value if (kotlinType.nameIfStandardType != null) { - val variableType = LLVMMapStandardType(property.name ?: return, kotlinType).type + val variableType = LLVMInstanceOfStandardType(property.name ?: return, kotlinType).type val variable = LLVMVariable(property.name.toString(), variableType, property.name.toString(), LLVMVariableScope(), pointer = 1) variableManager.addGlobalVariable(property.name.toString(), variable) codeBuilder.declareGlobalVariable(variable, variableType.parseArg(value.toString())) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt index 8d615f8e0e1..38ee6f1f2e9 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt @@ -33,7 +33,7 @@ abstract class StructCodegen(open val state: TranslationState, var methods = HashMap() abstract val structName: String val fullName: String - get() = "${if (type.location.size > 0) "${type.location.joinToString(".")}." else ""}$structName" + get() = "${if (type.location.size > 0) "${type.location.joinToString(".")}." else ""}$structName" fun generate(declarations: List) { @@ -49,7 +49,7 @@ abstract class StructCodegen(open val state: TranslationState, } } - val classVal = LLVMVariable("classvariable.this", type, pointer = 1) + val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive()) 0 else 1) variableManager.addVariable("this", classVal, 0) for (function in methods.values) { @@ -156,7 +156,7 @@ abstract class StructCodegen(open val state: TranslationState, protected fun resolveType(field: KtNamedDeclaration, ktType: KotlinType): LLVMClassVariable { val annotations = parseFieldAnnotations(field) - val result = LLVMMapStandardType(field.name!!, ktType, LLVMRegisterScope()) + val result = LLVMInstanceOfStandardType(field.name!!, ktType, LLVMRegisterScope()) if (result.type is LLVMReferenceType) { val type = result.type as LLVMReferenceType diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index c91cb42c4a8..ba328149cec 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -30,6 +30,7 @@ class TranslationState(val environment: KotlinCoreEnvironment, val bindingContex var objects = HashMap() var properties = HashMap() val codeBuilder = LLVMBuilder(arm) + val extensionFunctions = HashMap>() } fun parseAndAnalyze(sources: List, disposer: Disposable, arm: Boolean = false): TranslationState { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt index 5b251eb5682..1e1397ec8e7 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -12,7 +12,7 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnTy "${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).byRef) "byval" else ""} %${s.label}" }?.joinToString()}) ${if (arm) "#0" else ""}" -fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope()): LLVMVariable = when { +fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope()): LLVMVariable = when { type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), name, scope, pointer = 1) type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope) type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope) @@ -22,4 +22,7 @@ fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMR type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope) type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(type.toString().dropLast(1)), name, scope, pointer = 1) else -> LLVMVariable(name, LLVMReferenceType(type.toString()), name, scope, pointer = 1) -} \ No newline at end of file +} + +fun LLVMMapStandardType(type: KotlinType): LLVMType = + LLVMInstanceOfStandardType("type", type, LLVMRegisterScope()).type diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt index 821749e78f8..a498725265f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt @@ -45,6 +45,7 @@ class LLVMBooleanType() : LLVMType() { override val align = 4 override var size: Int = 1 override val defaultValue = "0" + override fun isPrimitive() = true override fun toString() = "i1" } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt index 72c2b5a90aa..ef609eaeaa0 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMByteType.kt @@ -26,4 +26,5 @@ class LLVMByteType() : LLVMType() { override var size: Int = 1 override fun toString(): String = "i8" override val defaultValue = "0" + override fun isPrimitive() = true } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt index e4b56c9ec66..e72ac891f62 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt @@ -26,4 +26,5 @@ class LLVMCharType() : LLVMType() { override var size: Int = 1 override fun toString(): String = "i8" override val defaultValue = "0" + override fun isPrimitive() = true } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt index c93d84af35e..f4462b696ad 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt @@ -22,4 +22,5 @@ class LLVMDoubleType() : LLVMType() { override var size: Int = 8 override fun toString() = "double" override val defaultValue = "0.0" + override fun isPrimitive() = true } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt index 59df26e8372..77a7e63ad6c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt @@ -1,7 +1,7 @@ package org.kotlinnative.translator.llvm.types import org.jetbrains.kotlin.types.KotlinType -import org.kotlinnative.translator.llvm.LLVMMapStandardType +import org.kotlinnative.translator.llvm.LLVMInstanceOfStandardType import org.kotlinnative.translator.llvm.LLVMVariable class LLVMFunctionType(type: KotlinType) : LLVMType() { @@ -14,7 +14,7 @@ class LLVMFunctionType(type: KotlinType) : LLVMType() { val returnType: LLVMVariable init { - val types = type.arguments.map { LLVMMapStandardType("", it.type) }.toList() + val types = type.arguments.map { LLVMInstanceOfStandardType("", it.type) }.toList() returnType = types.last() arguments = types.dropLast(1) } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt index 8c6990869c8..d1f9505dfe3 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt @@ -60,4 +60,5 @@ class LLVMIntType() : LLVMType() { override val defaultValue = "0" override fun toString() = "i32" + override fun isPrimitive() = true } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt index 03b64879bb3..d88f131f645 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt @@ -27,4 +27,5 @@ class LLVMShortType() : LLVMType() { override val defaultValue = "0" override fun toString(): String = "i16" + override fun isPrimitive() = true } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt index 81bf4c5a323..455cb208874 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt @@ -28,6 +28,7 @@ abstract class LLVMType() : Cloneable { abstract val align: Int abstract var size: Int abstract val defaultValue: String + open fun isPrimitive(): Boolean = false } fun parseLLVMType(type: String): LLVMType = when (type) { diff --git a/translator/src/test/kotlin/tests/input/function_extensions_1.txt b/translator/src/test/kotlin/tests/input/function_extensions_1.txt new file mode 100644 index 00000000000..5c8cd72bbef --- /dev/null +++ b/translator/src/test/kotlin/tests/input/function_extensions_1.txt @@ -0,0 +1 @@ +function_extensions_1(118) == 291 diff --git a/translator/src/test/kotlin/tests/kotlin/function_extensions_1.kt b/translator/src/test/kotlin/tests/kotlin/function_extensions_1.kt new file mode 100644 index 00000000000..8629bc20b33 --- /dev/null +++ b/translator/src/test/kotlin/tests/kotlin/function_extensions_1.kt @@ -0,0 +1,7 @@ +fun Int.compareTo(x: Int) : Int{ + return this + x + 5 +} + +fun function_extensions_1(x : Int): Int { + return x.compareTo(1) + 39.compareTo(123) +}