translator: add default functions arguments
This commit is contained in:
@@ -15,6 +15,9 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getFunctionResolvedCallWithAs
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||
import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
@@ -23,6 +26,7 @@ import org.kotlinnative.translator.llvm.*
|
||||
import org.kotlinnative.translator.llvm.types.*
|
||||
import java.rmi.UnexpectedException
|
||||
import java.util.*
|
||||
import kotlin.comparisons.compareBy
|
||||
|
||||
|
||||
abstract class BlockCodegen(val state: TranslationState, val variableManager: VariableManager, val codeBuilder: LLVMBuilder) {
|
||||
@@ -402,20 +406,28 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
}
|
||||
|
||||
private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: StructCodegen? = null, caller: LLVMVariable? = null): LLVMSingleValue? {
|
||||
val names = parseArgList(expr, scopeDepth)
|
||||
var names = parseArgList(expr, scopeDepth)
|
||||
var name = expr.firstChild.firstChild.text
|
||||
val targetFunction = state.bindingContext.get(BindingContext.CALL, expr.calleeExpression)
|
||||
val resolvedCall = state.bindingContext.get(BindingContext.RESOLVED_CALL, targetFunction)
|
||||
val functionDescriptor = expr.getFunctionResolvedCallWithAssert(state.bindingContext).candidateDescriptor
|
||||
val arguments = resolvedCall!!.valueArguments.toSortedMap(compareBy { it.index }).values
|
||||
|
||||
val external = state.externalFunctions.containsKey(name)
|
||||
val function = "$name${if (names.size > 0 && !external) LLVMType.mangleFunctionArguments(names) else ""}"
|
||||
val functionArguments = functionDescriptor.valueParameters.map { it -> it.type }.map { LLVMMapStandardType(it, state) }
|
||||
val function = "$name${if (!external) LLVMType.mangleFunctionTypes(functionArguments) else ""}"
|
||||
|
||||
|
||||
if (state.functions.containsKey(function) || state.externalFunctions.containsKey(function)) {
|
||||
val descriptor = state.functions[function] ?: state.externalFunctions[function] ?: return null
|
||||
names = parseNamedValueArguments(arguments, descriptor.defaultValues, scopeDepth)
|
||||
val args = loadArgsIfRequired(names, descriptor.args)
|
||||
return evaluateFunctionCallExpression(LLVMVariable(function, descriptor.returnType!!.type, scope = LLVMVariableScope()), args)
|
||||
}
|
||||
|
||||
if (state.classes.containsKey(name) || classScope?.structName == name) {
|
||||
val descriptor = state.classes[name] ?: classScope ?: return null
|
||||
val detectedConstructor = LLVMType.mangleFunctionArguments(names)
|
||||
val detectedConstructor = LLVMType.mangleFunctionTypes(functionArguments)
|
||||
val args = loadArgsIfRequired(names, descriptor.constructorFields[detectedConstructor]!!)
|
||||
return evaluateConstructorCallExpression(LLVMVariable(descriptor.fullName + detectedConstructor, descriptor.type, scope = LLVMVariableScope()), args)
|
||||
}
|
||||
@@ -545,21 +557,36 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
return result
|
||||
}
|
||||
|
||||
private fun parseArgList(expr: KtCallExpression, scopeDepth: Int): ArrayList<LLVMSingleValue> {
|
||||
private fun parseArgList(expr: KtCallExpression, scopeDepth: Int): List<LLVMSingleValue> {
|
||||
val args = expr.getValueArgumentsInParentheses()
|
||||
return parseValueArguments(args, scopeDepth)
|
||||
}
|
||||
|
||||
private fun parseValueArguments(args: List<ValueArgument>, scopeDepth: Int): ArrayList<LLVMSingleValue> {
|
||||
private fun parseValueArguments(args: List<ValueArgument>, scopeDepth: Int): List<LLVMSingleValue> {
|
||||
val result = ArrayList<LLVMSingleValue>()
|
||||
|
||||
for (arg in args) {
|
||||
val currentExpression = evaluateExpression(arg.getArgumentExpression(), scopeDepth) as LLVMSingleValue
|
||||
result.add(currentExpression)
|
||||
result.add(parseOneValueArgument(arg, scopeDepth))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun parseOneValueArgument(arg: ValueArgument, scopeDepth: Int): LLVMSingleValue {
|
||||
return evaluateExpression(arg.getArgumentExpression(), scopeDepth) as LLVMSingleValue
|
||||
}
|
||||
|
||||
private fun parseNamedValueArguments(args: MutableCollection<ResolvedValueArgument>, defaultValues: List<KtExpression?>, scopeDepth: Int): List<LLVMSingleValue> =
|
||||
args.mapIndexed(fun(i: Int, value: ResolvedValueArgument): LLVMSingleValue {
|
||||
return when (value) {
|
||||
is DefaultValueArgument -> evaluateExpression(defaultValues[i], scopeDepth)!!
|
||||
else -> {
|
||||
val expr = ((value as ExpressionValueArgument).valueArgument as KtValueArgument).getArgumentExpression()!!
|
||||
evaluateExpression(expr, scopeDepth)!!
|
||||
}
|
||||
}
|
||||
}).toList()
|
||||
|
||||
|
||||
private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable? {
|
||||
val operator = expr.operationToken
|
||||
if (operator == KtTokens.ELVIS) {
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.kotlinnative.translator.llvm.*
|
||||
import org.kotlinnative.translator.llvm.types.LLVMFunctionType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||
@@ -26,6 +32,7 @@ class FunctionCodegen(state: TranslationState,
|
||||
val fullName: String
|
||||
get() = functionNamePrefix + name
|
||||
val external: Boolean
|
||||
val defaultValues: List<KtExpression?>
|
||||
|
||||
init {
|
||||
val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!!
|
||||
@@ -50,6 +57,19 @@ class FunctionCodegen(state: TranslationState,
|
||||
state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType)
|
||||
}
|
||||
|
||||
defaultValues = mutableListOf()
|
||||
val valueParameters = descriptor.valueParameters
|
||||
for (index in valueParameters.indices) {
|
||||
val parameterDescriptor = valueParameters[index]
|
||||
if (parameterDescriptor.declaresDefaultValue()) {
|
||||
val initializer = (parameterDescriptor.source as KotlinSourceElement).psi
|
||||
val defaultValue = (initializer as KtParameter).defaultValue
|
||||
defaultValues.add(defaultValue!!)
|
||||
} else {
|
||||
defaultValues.add(null)
|
||||
}
|
||||
}
|
||||
|
||||
val retType = returnType!!.type
|
||||
when (retType) {
|
||||
is LLVMReferenceType -> {
|
||||
|
||||
@@ -39,7 +39,10 @@ abstract class LLVMType() : Cloneable {
|
||||
|
||||
companion object {
|
||||
fun mangleFunctionArguments(names: List<LLVMSingleValue>) =
|
||||
"_${names.joinToString(separator = "_", transform = { it.type!!.mangle() })}"
|
||||
mangleFunctionTypes(names.map { it.type!! })
|
||||
|
||||
fun mangleFunctionTypes(names: List<LLVMType>) =
|
||||
if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle() })}" else ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
function_default_arguments_1_mixed() == 76
|
||||
function_default_arguments_1_last_missed_Int(23) == 977
|
||||
function_default_arguments_1_last_present_Int(25) == 54
|
||||
function_default_arguments_1_position_third_only_Int(19) == 716
|
||||
function_default_arguments_1_position_all_reverse_Int(17) == 126
|
||||
function_default_arguments_1_position_all_right_order_Int(17) == 126
|
||||
function_default_arguments_1_position_all_default_Int(27) ==8268
|
||||
function_default_arguments_1_all_position() == 194
|
||||
function_default_arguments_1_add_class_arg() == 314
|
||||
@@ -0,0 +1,59 @@
|
||||
class function_default_arguments_1_argClass(val classArgument: Int)
|
||||
|
||||
fun function_default_arguments_1_add(x: Int, t: function_default_arguments_1_argClass = function_default_arguments_1_argClass(124), y: Int = 53, z: Int = 777): Int {
|
||||
return x + y
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_add_class(x: Int, t: function_default_arguments_1_argClass = function_default_arguments_1_argClass(124), y: Int = 53, z: Int = 777): Int {
|
||||
return x + t.classArgument
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_add_class_arg(): Int {
|
||||
return function_default_arguments_1_add_class(190)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_mixed(): Int {
|
||||
return function_default_arguments_1_add(23, t = function_default_arguments_1_argClass(29), z = 8)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_last_missed_fun(z: Int, u: Int = 954): Int {
|
||||
return z + u
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_last_missed(x: Int): Int {
|
||||
return function_default_arguments_1_last_missed_fun(x)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_last_present(x: Int): Int {
|
||||
return function_default_arguments_1_last_missed_fun(x, 29)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_position_fun(first: Int, second: Int = 324
|
||||
, third: Int = 2531): Int {
|
||||
return first + 2 * second + 3 * third
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_position_third_only(x: Int): Int {
|
||||
return function_default_arguments_1_position_fun(11, third = x)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_position_all_reverse(x: Int): Int {
|
||||
return function_default_arguments_1_position_fun(11, third = x, second = 32)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_position_all_right_order(x: Int): Int {
|
||||
return function_default_arguments_1_position_fun(11, second = 32, third = x)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_position_all_default(x: Int): Int {
|
||||
return function_default_arguments_1_position_fun(x)
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_all_position_fun(first: Int = 31, second: Int = 32
|
||||
, third: Int = 33): Int {
|
||||
return first + 2 * second + 3 * third
|
||||
}
|
||||
|
||||
fun function_default_arguments_1_all_position(): Int {
|
||||
return function_default_arguments_1_all_position_fun()
|
||||
}
|
||||
Reference in New Issue
Block a user