translator: add sceleton for companion fields, fix nested classes

This commit is contained in:
Alexey Stepanov
2016-07-21 09:42:27 +03:00
parent 33836aeafb
commit e9a1d80f97
4 changed files with 33 additions and 14 deletions
@@ -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)
@@ -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)
}
}
@@ -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)
}
@@ -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<LLVMVariable>()
val fieldsIndex = HashMap<String, LLVMClassVariable>()
val nestedClasses = HashMap<String, ClassCodegen>()
val companionMethods = HashMap<String, FunctionCodegen>()
val companionFields = ArrayList<LLVMVariable>()
val companionFieldsIndex = HashMap<String, LLVMClassVariable>()
val companionFieldsSource = HashMap<String, ObjectCodegen>()
val constructorFields = ArrayList<LLVMVariable>()