translator: fix resolve fields without this, fix global vars access

This commit is contained in:
e5l
2016-08-10 11:35:07 +03:00
parent 986b95dc88
commit 6fc0ed5f61
5 changed files with 47 additions and 13 deletions
@@ -240,7 +240,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
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 clazz = resolveClassOrObjectLocation(type)
val field = clazz.fieldsIndex[selectorName]
@@ -324,23 +324,14 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
indexVariable
}
}
}
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? = when {
expr is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
isEnumClassField(expr) -> resolveEnumClassField(expr)
(expr is KtNameReferenceExpression) && (classScope != null) -> evaluateNameReferenceExpression(expr, classScope)
else -> {
val referenceContext = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)
when (referenceContext) {
is PropertyDescriptorImpl -> {
val receiverThis = variableManager["this"]!!
evaluateMemberMethodOrField(receiverThis, expr.firstChild.text, topLevel, call = null)!!
}
else -> variableManager[expr.firstChild.text]
}
}
resolveContainingClass(expr) != null -> evaluateMemberMethodOrField(variableManager["this"]!!, expr.firstChild.text, topLevel)
else -> variableManager[expr.firstChild.text]
}
private fun resolveEnumClassField(expr: KtReferenceExpression): LLVMSingleValue {
@@ -417,7 +408,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
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
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
}