translator: fix resolve fields without this, fix global vars access
This commit is contained in:
@@ -240,7 +240,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement?): LLVMSingleValue? {
|
fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement? = null): LLVMSingleValue? {
|
||||||
val type = receiver.type as LLVMReferenceType
|
val type = receiver.type as LLVMReferenceType
|
||||||
val clazz = resolveClassOrObjectLocation(type)
|
val clazz = resolveClassOrObjectLocation(type)
|
||||||
val field = clazz.fieldsIndex[selectorName]
|
val field = clazz.fieldsIndex[selectorName]
|
||||||
@@ -324,23 +324,14 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
indexVariable
|
indexVariable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? = when {
|
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = 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)
|
(expr is KtNameReferenceExpression) && (classScope != null) -> evaluateNameReferenceExpression(expr, classScope)
|
||||||
else -> {
|
resolveContainingClass(expr) != null -> evaluateMemberMethodOrField(variableManager["this"]!!, expr.firstChild.text, topLevel)
|
||||||
val referenceContext = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)
|
else -> variableManager[expr.firstChild.text]
|
||||||
when (referenceContext) {
|
|
||||||
is PropertyDescriptorImpl -> {
|
|
||||||
val receiverThis = variableManager["this"]!!
|
|
||||||
evaluateMemberMethodOrField(receiverThis, expr.firstChild.text, topLevel, call = null)!!
|
|
||||||
}
|
|
||||||
else -> variableManager[expr.firstChild.text]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveEnumClassField(expr: KtReferenceExpression): LLVMSingleValue {
|
private fun resolveEnumClassField(expr: KtReferenceExpression): LLVMSingleValue {
|
||||||
@@ -417,7 +408,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveContainingClass(expr: KtCallExpression): StructCodegen? {
|
private fun resolveContainingClass(expr: KtElement): StructCodegen? {
|
||||||
val name = expr.getResolvedCallWithAssert(state.bindingContext).dispatchReceiver?.type?.toString() ?: return null
|
val name = expr.getResolvedCallWithAssert(state.bindingContext).dispatchReceiver?.type?.toString() ?: return null
|
||||||
return state.classes[name] ?: state.objects[name]
|
return state.classes[name] ?: state.objects[name]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
test1() == 5
|
||||||
|
test2() == 0
|
||||||
|
test3() == 5
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
global_test1() == 3000
|
||||||
|
global_test2() == 4001
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
class Main {
|
||||||
|
var i = 0
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
i = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
fun changeI(): Int {
|
||||||
|
main()
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test1(): Int {
|
||||||
|
val main = Main()
|
||||||
|
return main.changeI()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test2(): Int {
|
||||||
|
val main = Main()
|
||||||
|
return main.i
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test3(): Int {
|
||||||
|
return Main().changeI()
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
val MY_FIRST_CONSTANT: Int = 3000
|
||||||
|
val MY_SECOND_CONSTANT: Int = 4000
|
||||||
|
|
||||||
|
fun global_test1(): Int {
|
||||||
|
return MY_FIRST_CONSTANT
|
||||||
|
}
|
||||||
|
|
||||||
|
fun global_test2(): Int {
|
||||||
|
return MY_SECOND_CONSTANT + 1
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user