From e9a1d80f97434f8aadb796480ff3a0c5709c80e0 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Thu, 21 Jul 2016 09:42:27 +0300 Subject: [PATCH] translator: add sceleton for companion fields, fix nested classes --- .../kotlinnative/translator/BlockCodegen.kt | 14 ++++++++++++-- .../kotlinnative/translator/ClassCodegen.kt | 19 +++++++++++-------- .../kotlinnative/translator/ObjectCodegen.kt | 9 ++++++--- .../kotlinnative/translator/StructCodegen.kt | 5 ++++- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index ea8c7ef7e99..4a3e7170a75 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -103,9 +103,19 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM private fun evaluateClassScopedDotExpression(clazz: ClassCodegen, selector: KtExpression, scopeDepth: Int): LLVMSingleValue? = when (selector) { is KtCallExpression -> evaluateCallExpression(selector, scopeDepth, clazz) + is KtReferenceExpression -> evaluateReferenceExpression(selector, scopeDepth, clazz) else -> throw UnsupportedOperationException() } + private fun evaluatenameReferenceExpression(expr: KtNameReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? { + val fieldName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)!!.name.toString() + val field = classScope!!.companionFieldsIndex[fieldName] + + val result = codeBuilder.getNewVariable(field!!.type, pointer = 1) + codeBuilder.loadClassField(result, field, field.offset) + return result + } + private fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement): LLVMSingleValue? { val type = receiver.type as LLVMReferenceType val clazz = resolveClassOrObjectLocation(type) @@ -155,11 +165,11 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM return indexVariable } - private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int): LLVMSingleValue? = when (expr) { + private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? = when (expr) { is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1) + is KtNameReferenceExpression -> evaluatenameReferenceExpression(expr, scopeDepth + 1, classScope) else -> variableManager.getLLVMvalue(expr.firstChild.text) } - private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? { val function = expr.firstChild.firstChild.text val names = parseArgList(expr, scopeDepth) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt index 8556c1567fb..723dcad0bc2 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ClassCodegen.kt @@ -15,18 +15,17 @@ class ClassCodegen(override val state: TranslationState, override val variableManager: VariableManager, val clazz: KtClass, override val codeBuilder: LLVMBuilder, - owner: StructCodegen? = null) : + parentCodegen: StructCodegen? = null) : - StructCodegen(state, variableManager, clazz, state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException(), codeBuilder, owner) { + StructCodegen(state, variableManager, clazz, state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException(), codeBuilder, parentCodegen) { val annotation: Boolean override var size: Int = 0 - override val structName: String + override val structName: String = clazz.name!! override val type: LLVMReferenceType init { - structName = (if (parentCodegen != null) parentCodegen.structName + "." else "") + clazz.name!! type = LLVMReferenceType(structName, "class", byRef = true) val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException() val parameterList = clazz.getPrimaryConstructorParameterList()?.parameters ?: listOf() @@ -35,9 +34,9 @@ class ClassCodegen(override val state: TranslationState, indexFields(descriptor, parameterList) generateInnerFields(clazz.declarations) - if (owner != null) { - type.location.addAll(owner.type.location) - type.location.add(owner.structName) + if (parentCodegen != null) { + type.location.addAll(parentCodegen.type.location) + type.location.add(parentCodegen.structName) } type.size = size @@ -66,7 +65,8 @@ class ClassCodegen(override val state: TranslationState, fieldsIndex["enum_item"] = item size += type.size } - else -> {} + else -> { + } } } @@ -89,7 +89,10 @@ class ClassCodegen(override val state: TranslationState, for (method in property.methods) { val methodName = method.key.removePrefix(companionObjectName + ".") companionMethods.put(structName + "." + methodName, method.value) + companionFieldsSource.put(structName + "." + methodName, property) } + companionFields.addAll(property.fields) + companionFieldsIndex.putAll(property.fieldsIndex) } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt index 6787e85bce9..f637a75467c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/ObjectCodegen.kt @@ -12,16 +12,19 @@ class ObjectCodegen(override val state: TranslationState, override val variableManager: VariableManager, val objectDeclaration: KtObjectDeclaration, override val codeBuilder: LLVMBuilder, - override val parentCodegen: StructCodegen? = null) : + parentCodegen: StructCodegen? = null) : StructCodegen(state, variableManager, objectDeclaration, state.bindingContext.get(BindingContext.CLASS, objectDeclaration) ?: throw TranslationException(), codeBuilder, parentCodegen = parentCodegen) { override var size: Int = 0 - override val structName: String + override val structName: String = objectDeclaration.name!! override val type: LLVMReferenceType init { - structName = (if (parentCodegen != null) parentCodegen.structName + "." else "") + objectDeclaration.name!! type = LLVMReferenceType(structName, "class", byRef = true) + if (parentCodegen != null) { + type.location.addAll(parentCodegen.type.location) + type.location.add(parentCodegen.structName) + } generateInnerFields(objectDeclaration.declarations) } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt index 51293005bdd..8d615f8e0e1 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/StructCodegen.kt @@ -16,12 +16,15 @@ abstract class StructCodegen(open val state: TranslationState, open val classOrObject: KtClassOrObject, val classDescriptor: ClassDescriptor, open val codeBuilder: LLVMBuilder, - open val parentCodegen: StructCodegen? = null) { + val parentCodegen: StructCodegen? = null) { val fields = ArrayList() val fieldsIndex = HashMap() val nestedClasses = HashMap() val companionMethods = HashMap() + val companionFields = ArrayList() + val companionFieldsIndex = HashMap() + val companionFieldsSource = HashMap() val constructorFields = ArrayList()