translator: fix calls methods of class fields which are classes, add preindex of methods, add tests
This commit is contained in:
@@ -2,22 +2,24 @@ package org.kotlinnative.translator
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
import org.jetbrains.kotlin.psi.KtParameter
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.kotlinnative.translator.exceptions.TranslationException
|
import org.kotlinnative.translator.exceptions.TranslationException
|
||||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||||
|
|
||||||
class ClassCodegen(override val state: TranslationState,
|
class ClassCodegen(state: TranslationState,
|
||||||
override val variableManager: VariableManager,
|
variableManager: VariableManager,
|
||||||
val clazz: KtClass,
|
val clazz: KtClass,
|
||||||
override val codeBuilder: LLVMBuilder,
|
codeBuilder: LLVMBuilder,
|
||||||
parentCodegen: StructCodegen? = null) :
|
parentCodegen: StructCodegen? = null) :
|
||||||
|
|
||||||
StructCodegen(state, variableManager, clazz, state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException(), codeBuilder, parentCodegen) {
|
StructCodegen(state, variableManager, clazz, state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException(), codeBuilder, parentCodegen) {
|
||||||
|
|
||||||
val annotation: Boolean
|
val annotation: Boolean
|
||||||
val enum: Boolean
|
val enum: Boolean
|
||||||
|
var companionObjectCodegen: ObjectCodegen? = null
|
||||||
|
|
||||||
override var size: Int = 0
|
override var size: Int = 0
|
||||||
override val structName: String = clazz.name!!
|
override val structName: String = clazz.name!!
|
||||||
@@ -58,31 +60,44 @@ class ClassCodegen(override val state: TranslationState,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generate() {
|
override fun prepareForGenerate() {
|
||||||
if (annotation) {
|
if (annotation) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
super.prepareForGenerate()
|
||||||
generate(clazz.declarations)
|
nestedClasses.forEach { x, classCodegen -> classCodegen.prepareForGenerate() }
|
||||||
nestedClasses.forEach { x, classCodegen -> classCodegen.generate() }
|
|
||||||
|
|
||||||
val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException()
|
val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException()
|
||||||
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
val companionObjectDescriptor = descriptor.companionObjectDescriptor
|
||||||
if (companionObjectDescriptor != null) {
|
if (companionObjectDescriptor != null) {
|
||||||
val companionObject = clazz.getCompanionObjects().first()
|
val companionObject = clazz.getCompanionObjects().first()
|
||||||
val property = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this)
|
companionObjectCodegen = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this)
|
||||||
val companionObjectName = structName + "." + companionObject.name
|
companionObjectCodegen!!.prepareForGenerate()
|
||||||
property.generate()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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 + ".")
|
val methodName = key.removePrefix(companionObjectName + ".")
|
||||||
companionMethods.put(structName + "." + methodName, value)
|
companionMethods.put(structName + "." + methodName, value)
|
||||||
}
|
}
|
||||||
companionFields.addAll(property.fields)
|
companionFields.addAll(companionObjectCodegen!!.fields)
|
||||||
for (field in property.fields) {
|
for (field in companionObjectCodegen!!.fields) {
|
||||||
companionFieldsSource.put(field.label, property)
|
companionFieldsSource.put(field.label, companionObjectCodegen!!)
|
||||||
}
|
}
|
||||||
companionFieldsIndex.putAll(property.fieldsIndex)
|
companionFieldsIndex.putAll(companionObjectCodegen!!.fieldsIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import org.kotlinnative.translator.llvm.types.LLVMVoidType
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
class FunctionCodegen(override val state: TranslationState,
|
class FunctionCodegen(state: TranslationState,
|
||||||
override val variableManager: VariableManager,
|
variableManager: VariableManager,
|
||||||
val function: KtNamedFunction,
|
val function: KtNamedFunction,
|
||||||
override val codeBuilder: LLVMBuilder,
|
codeBuilder: LLVMBuilder,
|
||||||
val parentCodegen: StructCodegen? = null) :
|
val parentCodegen: StructCodegen? = null) :
|
||||||
BlockCodegen(state, variableManager, codeBuilder) {
|
BlockCodegen(state, variableManager, codeBuilder) {
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import org.kotlinnative.translator.llvm.LLVMVariable
|
|||||||
import org.kotlinnative.translator.llvm.LLVMVariableScope
|
import org.kotlinnative.translator.llvm.LLVMVariableScope
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||||
|
|
||||||
class ObjectCodegen(override val state: TranslationState,
|
class ObjectCodegen(state: TranslationState,
|
||||||
override val variableManager: VariableManager,
|
variableManager: VariableManager,
|
||||||
val objectDeclaration: KtObjectDeclaration,
|
val objectDeclaration: KtObjectDeclaration,
|
||||||
override val codeBuilder: LLVMBuilder,
|
codeBuilder: LLVMBuilder,
|
||||||
parentCodegen: StructCodegen? = null) :
|
parentCodegen: StructCodegen? = null) :
|
||||||
StructCodegen(state, variableManager, objectDeclaration, state.bindingContext.get(BindingContext.CLASS, objectDeclaration) ?: throw TranslationException(),
|
StructCodegen(state, variableManager, objectDeclaration, state.bindingContext.get(BindingContext.CLASS, objectDeclaration) ?: throw TranslationException(),
|
||||||
codeBuilder, parentCodegen = parentCodegen) {
|
codeBuilder, parentCodegen = parentCodegen) {
|
||||||
@@ -28,8 +28,12 @@ class ObjectCodegen(override val state: TranslationState,
|
|||||||
generateInnerFields(objectDeclaration.declarations)
|
generateInnerFields(objectDeclaration.declarations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generate() {
|
override fun prepareForGenerate() {
|
||||||
generate(objectDeclaration.declarations)
|
super.prepareForGenerate()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generate() {
|
||||||
|
super.generate()
|
||||||
val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1)
|
val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1)
|
||||||
codeBuilder.addGlobalIntialize(classInstance, type)
|
codeBuilder.addGlobalIntialize(classInstance, type)
|
||||||
variableManager.addGlobalVariable(fullName, classInstance)
|
variableManager.addGlobalVariable(fullName, classInstance)
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ class ProjectTranslator(val files: List<KtFile>, val state: TranslationState) {
|
|||||||
private fun generateProjectBody() {
|
private fun generateProjectBody() {
|
||||||
with(state) {
|
with(state) {
|
||||||
properties.values.map { it.generate() }
|
properties.values.map { it.generate() }
|
||||||
|
objects.values.map { it.prepareForGenerate() }
|
||||||
|
classes.values.map { it.prepareForGenerate() }
|
||||||
objects.values.map { it.generate() }
|
objects.values.map { it.generate() }
|
||||||
classes.values.map { it.generate() }
|
classes.values.map { it.generate() }
|
||||||
externalFunctions.values.map { it.generate() }
|
externalFunctions.values.map { it.generate() }
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
|||||||
import org.kotlinnative.translator.llvm.types.LLVMVoidType
|
import org.kotlinnative.translator.llvm.types.LLVMVoidType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
abstract class StructCodegen(open val state: TranslationState,
|
abstract class StructCodegen(val state: TranslationState,
|
||||||
open val variableManager: VariableManager,
|
val variableManager: VariableManager,
|
||||||
open val classOrObject: KtClassOrObject,
|
val classOrObject: KtClassOrObject,
|
||||||
val classDescriptor: ClassDescriptor,
|
val classDescriptor: ClassDescriptor,
|
||||||
open val codeBuilder: LLVMBuilder,
|
val codeBuilder: LLVMBuilder,
|
||||||
val parentCodegen: StructCodegen? = null) {
|
val parentCodegen: StructCodegen? = null) {
|
||||||
|
|
||||||
val fields = ArrayList<LLVMVariable>()
|
val fields = ArrayList<LLVMVariable>()
|
||||||
@@ -39,12 +39,8 @@ abstract class StructCodegen(open val state: TranslationState,
|
|||||||
val fullName: 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<KtDeclaration>) {
|
open fun prepareForGenerate() {
|
||||||
generateStruct()
|
for (declaration in classOrObject.declarations) {
|
||||||
generateEnumFields()
|
|
||||||
generatePrimaryConstructor()
|
|
||||||
|
|
||||||
for (declaration in declarations) {
|
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is KtNamedFunction -> {
|
is KtNamedFunction -> {
|
||||||
val function = FunctionCodegen(state, variableManager, declaration, codeBuilder, this)
|
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)
|
val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive()) 0 else 1)
|
||||||
variableManager.addVariable("this", classVal, 0)
|
variableManager.addVariable("this", classVal, 0)
|
||||||
@@ -73,7 +75,7 @@ abstract class StructCodegen(open val state: TranslationState,
|
|||||||
field.offset = offset
|
field.offset = offset
|
||||||
offset++
|
offset++
|
||||||
|
|
||||||
if ((declaration.initializer != null) && !(this is ObjectCodegen)){
|
if ((declaration.initializer != null) && !(this is ObjectCodegen)) {
|
||||||
initializedFields.put(field, declaration.initializer!!)
|
initializedFields.put(field, declaration.initializer!!)
|
||||||
}
|
}
|
||||||
fields.add(field)
|
fields.add(field)
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
class_method_access_1_test_Int(110) == 122
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user