diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt index 15d3529c9df..7240fbeba7f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt @@ -2,22 +2,24 @@ package org.kotlinnative.translator import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.resolve.BindingContext import org.kotlinnative.translator.exceptions.TranslationException import org.kotlinnative.translator.llvm.LLVMBuilder import org.kotlinnative.translator.llvm.types.LLVMReferenceType -class ClassCodegen(override val state: TranslationState, - override val variableManager: VariableManager, +class ClassCodegen(state: TranslationState, + variableManager: VariableManager, val clazz: KtClass, - override val codeBuilder: LLVMBuilder, + codeBuilder: LLVMBuilder, parentCodegen: StructCodegen? = null) : StructCodegen(state, variableManager, clazz, state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException(), codeBuilder, parentCodegen) { val annotation: Boolean val enum: Boolean + var companionObjectCodegen: ObjectCodegen? = null override var size: Int = 0 override val structName: String = clazz.name!! @@ -58,31 +60,44 @@ class ClassCodegen(override val state: TranslationState, } } - fun generate() { + override fun prepareForGenerate() { if (annotation) { return } - - generate(clazz.declarations) - nestedClasses.forEach { x, classCodegen -> classCodegen.generate() } + super.prepareForGenerate() + nestedClasses.forEach { x, classCodegen -> classCodegen.prepareForGenerate() } val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException() val companionObjectDescriptor = descriptor.companionObjectDescriptor if (companionObjectDescriptor != null) { val companionObject = clazz.getCompanionObjects().first() - val property = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this) - val companionObjectName = structName + "." + companionObject.name - property.generate() + companionObjectCodegen = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this) + companionObjectCodegen!!.prepareForGenerate() + } + } - for ((key, value) in property.methods) { + override fun generate() { + if (annotation) { + return + } + + super.generate() + nestedClasses.forEach { x, classCodegen -> classCodegen.generate() } + + if (companionObjectCodegen != null) { + val companionObject = clazz.getCompanionObjects().first() + val companionObjectName = structName + "." + companionObject.name + companionObjectCodegen!!.generate() + + for ((key, value) in companionObjectCodegen!!.methods) { val methodName = key.removePrefix(companionObjectName + ".") companionMethods.put(structName + "." + methodName, value) } - companionFields.addAll(property.fields) - for (field in property.fields) { - companionFieldsSource.put(field.label, property) + companionFields.addAll(companionObjectCodegen!!.fields) + for (field in companionObjectCodegen!!.fields) { + companionFieldsSource.put(field.label, companionObjectCodegen!!) } - companionFieldsIndex.putAll(property.fieldsIndex) + companionFieldsIndex.putAll(companionObjectCodegen!!.fieldsIndex) } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 1ab93208db5..52597d113b5 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -12,10 +12,10 @@ import org.kotlinnative.translator.llvm.types.LLVMVoidType import java.util.* -class FunctionCodegen(override val state: TranslationState, - override val variableManager: VariableManager, +class FunctionCodegen(state: TranslationState, + variableManager: VariableManager, val function: KtNamedFunction, - override val codeBuilder: LLVMBuilder, + codeBuilder: LLVMBuilder, val parentCodegen: StructCodegen? = null) : BlockCodegen(state, variableManager, codeBuilder) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt index 8124d33b724..3edb7fc5043 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt @@ -8,10 +8,10 @@ import org.kotlinnative.translator.llvm.LLVMVariable import org.kotlinnative.translator.llvm.LLVMVariableScope import org.kotlinnative.translator.llvm.types.LLVMReferenceType -class ObjectCodegen(override val state: TranslationState, - override val variableManager: VariableManager, +class ObjectCodegen(state: TranslationState, + variableManager: VariableManager, val objectDeclaration: KtObjectDeclaration, - override val codeBuilder: LLVMBuilder, + codeBuilder: LLVMBuilder, parentCodegen: StructCodegen? = null) : StructCodegen(state, variableManager, objectDeclaration, state.bindingContext.get(BindingContext.CLASS, objectDeclaration) ?: throw TranslationException(), codeBuilder, parentCodegen = parentCodegen) { @@ -28,8 +28,12 @@ class ObjectCodegen(override val state: TranslationState, generateInnerFields(objectDeclaration.declarations) } - fun generate() { - generate(objectDeclaration.declarations) + override fun prepareForGenerate() { + super.prepareForGenerate() + } + + override fun generate() { + super.generate() val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1) codeBuilder.addGlobalIntialize(classInstance, type) variableManager.addGlobalVariable(fullName, classInstance) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt index ba1bd530065..e4f66fbaa8a 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ProjectTranslator.kt @@ -42,6 +42,8 @@ class ProjectTranslator(val files: List, val state: TranslationState) { private fun generateProjectBody() { with(state) { properties.values.map { it.generate() } + objects.values.map { it.prepareForGenerate() } + classes.values.map { it.prepareForGenerate() } objects.values.map { it.generate() } classes.values.map { it.generate() } externalFunctions.values.map { it.generate() } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt index d3877fbcbd3..8d0b4eff288 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt @@ -13,11 +13,11 @@ import org.kotlinnative.translator.llvm.types.LLVMReferenceType import org.kotlinnative.translator.llvm.types.LLVMVoidType import java.util.* -abstract class StructCodegen(open val state: TranslationState, - open val variableManager: VariableManager, - open val classOrObject: KtClassOrObject, +abstract class StructCodegen(val state: TranslationState, + val variableManager: VariableManager, + val classOrObject: KtClassOrObject, val classDescriptor: ClassDescriptor, - open val codeBuilder: LLVMBuilder, + val codeBuilder: LLVMBuilder, val parentCodegen: StructCodegen? = null) { val fields = ArrayList() @@ -39,12 +39,8 @@ abstract class StructCodegen(open val state: TranslationState, val fullName: String get() = "${if (type.location.size > 0) "${type.location.joinToString(".")}." else ""}$structName" - fun generate(declarations: List) { - generateStruct() - generateEnumFields() - generatePrimaryConstructor() - - for (declaration in declarations) { + open fun prepareForGenerate() { + for (declaration in classOrObject.declarations) { when (declaration) { is KtNamedFunction -> { val function = FunctionCodegen(state, variableManager, declaration, codeBuilder, this) @@ -52,6 +48,12 @@ abstract class StructCodegen(open val state: TranslationState, } } } + } + + open fun generate() { + generateStruct() + generateEnumFields() + generatePrimaryConstructor() val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive()) 0 else 1) variableManager.addVariable("this", classVal, 0) @@ -73,7 +75,7 @@ abstract class StructCodegen(open val state: TranslationState, field.offset = offset offset++ - if ((declaration.initializer != null) && !(this is ObjectCodegen)){ + if ((declaration.initializer != null) && !(this is ObjectCodegen)) { initializedFields.put(field, declaration.initializer!!) } fields.add(field) diff --git a/translator/src/test/kotlin/tests/input/class_method_access_1.txt b/translator/src/test/kotlin/tests/input/class_method_access_1.txt new file mode 100644 index 00000000000..a0bfb5a12c1 --- /dev/null +++ b/translator/src/test/kotlin/tests/input/class_method_access_1.txt @@ -0,0 +1 @@ +class_method_access_1_test_Int(110) == 122 diff --git a/translator/src/test/kotlin/tests/kotlin/class_method_access_1.kt b/translator/src/test/kotlin/tests/kotlin/class_method_access_1.kt new file mode 100644 index 00000000000..2ec083afedd --- /dev/null +++ b/translator/src/test/kotlin/tests/kotlin/class_method_access_1.kt @@ -0,0 +1,20 @@ +class class_method_access_1_donor(var size: Int) { + fun getSizeVal(): Int { + return size + 4 + } +} + +class class_method_access_1_owner(val arg: class_method_access_1_donor) { + val tKIopsD = 56 + fun getSize(): Int { + return arg.getSizeVal() + 8 + } +} + + +fun class_method_access_1_test(x: Int): Int { + val instance_donor = class_method_access_1_donor(x) + val instance_owner = class_method_access_1_owner(instance_donor) + + return instance_owner.getSize() +}