translator: fix enum naming and location resolve

This commit is contained in:
e5l
2016-08-11 09:52:11 +03:00
parent cea504b095
commit 71ad20ddab
4 changed files with 36 additions and 14 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getFunctionResolvedCallWithAssert import org.jetbrains.kotlin.resolve.calls.callUtil.getFunctionResolvedCallWithAssert
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
@@ -172,7 +173,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
private fun evaluateDotBody(receiverExpr: KtExpression, selectorExpr: KtExpression, scopeDepth: Int): LLVMSingleValue? { private fun evaluateDotBody(receiverExpr: KtExpression, selectorExpr: KtExpression, scopeDepth: Int): LLVMSingleValue? {
val receiverName = receiverExpr.text val receiverName = receiverExpr.text
var receiver = when (receiverExpr) { var receiver = when (receiverExpr) {
is KtCallExpression, is KtCallExpression,
is KtBinaryExpression, is KtBinaryExpression,
@@ -206,10 +206,15 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
} }
} }
val location = receiverExpr.getType(state.bindingContext)?.getSubtypesPredicate()?.toString()?.split(".") val type = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiverExpr)?.type
val classReference = LLVMReferenceType(location?.last() ?: receiverName, "class") ?: receiverExpr.getType(state.bindingContext)
if (location != null) { ?: receiverExpr.getQualifiedExpressionForReceiver()?.getType(state.bindingContext)
classReference.location.addAll(location.dropLast(1))
val path = type?.getSubtypesPredicate()?.toString()?.split(".")
val classReference = LLVMReferenceType(path?.last() ?: receiverName, "class")
if (path != null) {
classReference.location.addAll(path.dropLast(1))
} }
val clazz = resolveClassOrObjectLocation(classReference) ?: return evaluateExtensionExpression(receiverExpr, selectorExpr as KtCallExpression, scopeDepth) val clazz = resolveClassOrObjectLocation(classReference) ?: return evaluateExtensionExpression(receiverExpr, selectorExpr as KtCallExpression, scopeDepth)
@@ -219,6 +224,10 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
private fun evaluateExtensionExpression(receiver: KtExpression, selector: KtCallExpression, scopeDepth: Int): LLVMSingleValue? { private fun evaluateExtensionExpression(receiver: KtExpression, selector: KtCallExpression, scopeDepth: Int): LLVMSingleValue? {
val receiverType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver) val receiverType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, receiver)
val standardType = LLVMMapStandardType(receiverType!!.type!!) val standardType = LLVMMapStandardType(receiverType!!.type!!)
// if (standardType is LLVMReferenceType) {
// standardType.location.addAll(receiverType.type!!.getSubtypesPredicate().toString().split(".").dropLast(1))
// }
val function = selector.firstChild.firstChild.text val function = selector.firstChild.firstChild.text
val names = parseArgList(selector, scopeDepth) val names = parseArgList(selector, scopeDepth)
val type = if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.type!!.mangle() })}" else "" val type = if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.type!!.mangle() })}" else ""
@@ -241,9 +250,9 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
else -> throw UnsupportedOperationException() else -> throw UnsupportedOperationException()
} }
private fun evaluateNameReferenceExpression(expr: KtNameReferenceExpression, classScope: StructCodegen? = null): LLVMSingleValue? { private fun evaluateNameReferenceExpression(expr: KtNameReferenceExpression, classScope: StructCodegen): LLVMSingleValue? {
val fieldName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)!!.name.toString() val fieldName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)!!.name.toString()
val field = classScope!!.companionFieldsIndex[fieldName] val field = classScope.companionFieldsIndex[fieldName]
val companionObject = classScope.companionFieldsSource[fieldName] val companionObject = classScope.companionFieldsSource[fieldName]
val receiver = variableManager[companionObject!!.fullName]!! val receiver = variableManager[companionObject!!.fullName]!!
val result = codeBuilder.getNewVariable(field!!.type, pointer = 1) val result = codeBuilder.getNewVariable(field!!.type, pointer = 1)
@@ -345,21 +354,30 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? = when { private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? = when {
expr is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1) expr is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
isEnumClassField(expr) -> resolveEnumClassField(expr) isEnumClassField(expr) -> resolveEnumClassField(expr)
(expr is KtNameReferenceExpression) && (classScope != null) -> evaluateNameReferenceExpression(expr, classScope.parentCodegen) (expr is KtNameReferenceExpression) && (classScope != null) -> evaluateNameReferenceExpression(expr, classScope.parentCodegen!!)
resolveContainingClass(expr) != null -> evaluateMemberMethodOrField(variableManager["this"]!!, expr.firstChild.text, topLevel) resolveContainingClass(expr) != null -> evaluateMemberMethodOrField(variableManager["this"]!!, expr.firstChild.text, topLevel)
else -> variableManager[expr.firstChild.text] else -> variableManager[expr.firstChild.text]
} }
private fun resolveEnumClassField(expr: KtReferenceExpression): LLVMSingleValue { private fun resolveEnumClassField(expr: KtReferenceExpression): LLVMSingleValue {
return state.classes[expr.getType(state.bindingContext).toString()]!!.enumFields[expr.text]!! return resolveCodegen(expr)!!.enumFields[expr.text]!!
} }
private fun isEnumClassField(expr: KtReferenceExpression): Boolean { private fun isEnumClassField(expr: KtReferenceExpression): Boolean {
val name = expr.getType(state.bindingContext)?.toString() ?: return false val clazz = resolveCodegen(expr) ?: return false
val clazz = state.classes[name] ?: return false
return clazz.enumFields.containsKey(expr.text) return clazz.enumFields.containsKey(expr.text)
} }
private fun resolveCodegen(expr: KtReferenceExpression): StructCodegen? {
val location = expr.getType(state.bindingContext)?.getSubtypesPredicate()?.toString()?.split(".") ?: return null
val name = location.last()
val classType = LLVMReferenceType(name, prefix = "class")
classType.location.addAll(location.dropLast(1))
return resolveClassOrObjectLocation(classType)
}
private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? { private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? {
val names = parseArgList(expr, scopeDepth) val names = parseArgList(expr, scopeDepth)
val name = expr.firstChild.firstChild.text val name = expr.firstChild.firstChild.text
@@ -34,8 +34,8 @@ class ObjectCodegen(state: TranslationState,
override fun generate() { override fun generate() {
super.generate() super.generate()
val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1) val classInstance = LLVMVariable("object.instance.$fullName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1)
codeBuilder.addGlobalIntialize(classInstance, type) codeBuilder.addGlobalInitialize(classInstance, type)
variableManager.addGlobalVariable(fullName, classInstance) variableManager.addGlobalVariable(fullName, classInstance)
} }
} }
@@ -1,6 +1,7 @@
package org.kotlinnative.translator package org.kotlinnative.translator
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.cfg.pseudocode.getSubtypesPredicate
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
@@ -201,6 +202,9 @@ abstract class StructCodegen(val state: TranslationState,
val type = result.type as LLVMReferenceType val type = result.type as LLVMReferenceType
type.prefix = "class" type.prefix = "class"
type.byRef = true type.byRef = true
val location = ktType.getSubtypesPredicate().toString().split(".").dropLast(1)
type.location.addAll(location)
} }
if (annotations.contains("Plain")) { if (annotations.contains("Plain")) {
@@ -81,7 +81,7 @@ class LLVMBuilder(val arm: Boolean = false) {
globalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1") globalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1")
} }
fun addGlobalIntialize(target: LLVMVariable, classType: LLVMType) { fun addGlobalInitialize(target: LLVMVariable, classType: LLVMType) {
val code = "$target = internal global $classType zeroinitializer, align ${classType.align}" val code = "$target = internal global $classType zeroinitializer, align ${classType.align}"
globalCode.appendln(code) globalCode.appendln(code)
} }