translator: escape calculating reference type location
This commit is contained in:
@@ -4,7 +4,6 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.cfg.pseudocode.getSubtypesPredicate
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -195,7 +194,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
is KtPostfixExpression,
|
||||
is KtBinaryExpression -> evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable
|
||||
is KtDotQualifiedExpression -> {
|
||||
val codegen = resolveCodegenByName(receiverName, receiverName.split("."))
|
||||
val codegen = resolveCodegenByName(receiverName)
|
||||
if (codegen != null) null else evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable
|
||||
}
|
||||
is KtNameReferenceExpression -> {
|
||||
@@ -307,22 +306,32 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
}
|
||||
|
||||
private fun resolveClassOrObjectLocation(type: LLVMReferenceType): StructCodegen? {
|
||||
if (type.location.size == 0) {
|
||||
return state.classes[type.type] ?: state.objects[type.type]
|
||||
}
|
||||
val typeLocations = type.type.split('.')
|
||||
val currentLocation = StringBuilder()
|
||||
var codegen: ClassCodegen? = null
|
||||
var currentIndex = 0
|
||||
|
||||
var codegen = state.classes[type.location[0]]
|
||||
var i = 1
|
||||
while (i < type.location.size) {
|
||||
codegen = codegen?.nestedClasses?.get(type.location[i])
|
||||
i++
|
||||
do {
|
||||
currentLocation.append((if (currentIndex > 0) "." else "") + typeLocations[currentIndex])
|
||||
if (state.classes.containsKey(currentLocation.toString())) {
|
||||
codegen = state.classes[currentLocation.toString()]
|
||||
} else if (state.objects.containsKey(currentLocation.toString())) {
|
||||
return state.objects[currentLocation.toString()]
|
||||
}
|
||||
currentIndex++
|
||||
} while ((currentIndex < typeLocations.size) && (codegen == null))
|
||||
|
||||
while (currentIndex < typeLocations.size - 1) {
|
||||
currentLocation.append('.' + typeLocations[currentIndex])
|
||||
currentIndex++
|
||||
codegen = codegen?.nestedClasses?.get(currentLocation.toString())
|
||||
}
|
||||
|
||||
if (codegen?.companionObjectCodegen != null && type.type == codegen?.companionObjectCodegen?.structName) {
|
||||
return codegen?.companionObjectCodegen!!
|
||||
}
|
||||
|
||||
return codegen?.nestedClasses?.get(type.type)
|
||||
return if (codegen?.structName == type.type) codegen else codegen?.nestedClasses?.get(type.type)
|
||||
}
|
||||
|
||||
fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? {
|
||||
@@ -407,26 +416,14 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
||||
?: expr.getType(state.bindingContext)
|
||||
?: expr.getQualifiedExpressionForReceiver()?.getType(state.bindingContext)
|
||||
|
||||
val location = type?.getSubtypesPredicate()?.toString()?.split(".")
|
||||
?: state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr as KtReferenceExpression)?.fqNameSafe?.toString()?.split(".")
|
||||
?: return null
|
||||
|
||||
val name = type?.constructor?.declarationDescriptor?.fqNameSafe?.asString() ?: throw UnexpectedException(expr.text)
|
||||
|
||||
return resolveCodegenByName(name, location)
|
||||
|
||||
return resolveCodegenByName(name)
|
||||
}
|
||||
|
||||
private fun resolveCodegenByName(name: String, location: List<String>): StructCodegen? {
|
||||
val classType = LLVMReferenceType(name, prefix = "class")
|
||||
var locationPrefix = ""
|
||||
for (currentLocation in location.dropLast(1)) {
|
||||
locationPrefix += (if (locationPrefix.length > 0) "." else "") + currentLocation
|
||||
classType.location.add(locationPrefix)
|
||||
}
|
||||
private fun resolveCodegenByName(name: String): StructCodegen? =
|
||||
resolveClassOrObjectLocation(LLVMReferenceType(name, prefix = "class"))
|
||||
|
||||
return resolveClassOrObjectLocation(classType)
|
||||
}
|
||||
|
||||
private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: StructCodegen? = null, caller: LLVMVariable? = null): LLVMSingleValue? {
|
||||
var names = parseArgList(expr, scopeDepth)
|
||||
|
||||
@@ -30,10 +30,6 @@ class ClassCodegen(state: TranslationState,
|
||||
|
||||
init {
|
||||
type = LLVMReferenceType(structName, "class", align = TranslationState.pointerAlign, size = TranslationState.pointerSize, byRef = true)
|
||||
if (parentCodegen != null) {
|
||||
type.location.addAll(parentCodegen.type.location)
|
||||
type.location.add(parentCodegen.structName)
|
||||
}
|
||||
|
||||
descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException("Can't receive descriptor of class " + clazz.name)
|
||||
|
||||
|
||||
@@ -20,11 +20,7 @@ class ObjectCodegen(state: TranslationState,
|
||||
|
||||
init {
|
||||
type = LLVMReferenceType(structName, "class", align = TranslationState.pointerAlign, size = TranslationState.pointerSize, byRef = true)
|
||||
if (parentCodegen != null) {
|
||||
type.location.addAll(parentCodegen.type.location)
|
||||
type.location.add(parentCodegen.structName)
|
||||
}
|
||||
primaryConstructorIndex = LLVMType.mangleFunctionArguments(emptyList())
|
||||
primaryConstructorIndex = LLVMType.mangleFunctionArguments(emptyList())
|
||||
constructorFields.put(primaryConstructorIndex!!, arrayListOf())
|
||||
}
|
||||
|
||||
|
||||
@@ -39,27 +39,25 @@ fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope
|
||||
val refName = declarationDescriptor.fqNameSafe.asString()
|
||||
val refType = state.classes[type.toString()]?.type ?: LLVMReferenceType(refName, align = TranslationState.pointerAlign, prefix = "class")
|
||||
|
||||
val result = LLVMVariable(name, refType, name, scope, pointer = 1)
|
||||
var currentPrefix = ""
|
||||
for (currentLocation in type.getSubtypesPredicate().toString().split(".").dropLast(1)) {
|
||||
currentPrefix += (if (currentPrefix.length > 0) "." else "") + currentLocation
|
||||
refType.location.add(currentPrefix)
|
||||
}
|
||||
result
|
||||
LLVMVariable(name, refType, name, scope, pointer = 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun LLVMMapStandardType(type: KotlinType, state: TranslationState): LLVMType =
|
||||
fun LLVMMapStandardType(type: KotlinType, state: TranslationState) =
|
||||
LLVMInstanceOfStandardType("type", type, LLVMRegisterScope(), state).type
|
||||
|
||||
fun String.addBeforeIfNotEmpty(add: String): String =
|
||||
if (this.length > 0) add + this else this
|
||||
|
||||
|
||||
fun String.addAfterIfNotEmpty(add: String): String =
|
||||
if (this.length > 0) this + add else this
|
||||
|
||||
fun String.indexOfOrLast(str: Char, startIndex: Int = 0): Int {
|
||||
val pos = this.indexOf(str, startIndex)
|
||||
return if (pos < 0) this.length else pos
|
||||
}
|
||||
|
||||
|
||||
fun FqName.convertToNativeName(): String =
|
||||
this.asString().replace(".<init>", "")
|
||||
@@ -18,8 +18,6 @@ class LLVMReferenceType(val type: String,
|
||||
|
||||
override fun toString() = "%$typename"
|
||||
|
||||
val location = ArrayList<String>()
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq ${firstOp.getType()} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user