translator: nested classes fields access, tests

This commit is contained in:
e5l
2016-07-20 17:44:07 +03:00
parent abdd9dd9eb
commit b473dfc5e2
7 changed files with 57 additions and 16 deletions
+6 -6
View File
@@ -14,12 +14,12 @@ fun main(args: Array<String>) {
val analyzedFiles = ArrayList<String>()
// val kotlib = ClassLoader.getSystemClassLoader().getResources("kotlib/kotlin")
// for (resourse in kotlib) {
// for (app in File(resourse.toURI()).listFiles()) {
// analyzedFiles.add(app.absoluteFile.toString())
// }
// }
val kotlib = ClassLoader.getSystemClassLoader().getResources("kotlib/kotlin")
for (resourse in kotlib) {
for (app in File(resourse.toURI()).listFiles()) {
analyzedFiles.add(app.absoluteFile.toString())
}
}
analyzedFiles.addAll(args.toList())
@@ -106,7 +106,11 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
}
private fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement): LLVMSingleValue? {
val clazz = state.classes[(receiver.type as LLVMReferenceType).type] ?: state.objects[(receiver.type as LLVMReferenceType).type]!!
val type = receiver.type as LLVMReferenceType
val clazz = resolveClassOrObjectLocation(type)
val field = clazz.fieldsIndex[selectorName]
if (field != null) {
val result = codeBuilder.getNewVariable(field.type, pointer = 1)
@@ -126,6 +130,21 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
return evaluateFunctionCallExpression(LLVMVariable(methodName, returnType, scope = LLVMVariableScope()), callArgs)
}
private fun resolveClassOrObjectLocation(type: LLVMReferenceType): StructCodegen {
if (type.location.size == 0) {
return state.classes[type.type] ?: state.objects[type.type]!!
}
var codegen = state.classes[type.location[0]]!!
var i = 1
while (i < type.location.size) {
codegen = codegen.nestedClasses[type.location[i]]!!
}
return codegen.nestedClasses[type.type]!!
}
fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? {
val arrayNameVariable = evaluateReferenceExpression(expr.arrayExpression as KtReferenceExpression, scope) as LLVMVariable
val arrayIndex = evaluateConstantExpression(expr.indexExpressions.first() as KtConstantExpression)
@@ -166,6 +185,8 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
val nestedConstructor = classScope?.nestedClasses?.get(expr.calleeExpression!!.text)
if (nestedConstructor != null) {
val args = loadArgsIfRequired(names, nestedConstructor.constructorFields)
return evaluateConstructorCallExpression(LLVMVariable(nestedConstructor.fullName, nestedConstructor.type, scope = LLVMVariableScope()), args)
}
return null
@@ -15,9 +15,9 @@ class ClassCodegen(override val state: TranslationState,
override val variableManager: VariableManager,
val clazz: KtClass,
override val codeBuilder: LLVMBuilder,
prefix: String = "") :
owner: StructCodegen? = null) :
StructCodegen(state, variableManager, clazz, state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException(), codeBuilder, prefix) {
StructCodegen(state, variableManager, clazz, state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException(), codeBuilder, owner) {
val annotation: Boolean
@@ -34,9 +34,11 @@ class ClassCodegen(override val state: TranslationState,
indexFields(descriptor, parameterList)
generateInnerFields(clazz.declarations)
if (prefix.length > 0) {
type.prefix = "${type.prefix}_$prefix"
if (owner != null) {
type.location.addAll(owner.type.location)
type.location.add(owner.structName)
}
type.size = size
}
@@ -63,6 +65,7 @@ class ClassCodegen(override val state: TranslationState,
fieldsIndex["enum_item"] = item
size += type.size
}
else -> {}
}
}
@@ -16,7 +16,7 @@ abstract class StructCodegen(open val state: TranslationState,
open val classOrObject: KtClassOrObject,
val classDescriptor: ClassDescriptor,
open val codeBuilder: LLVMBuilder,
val prefix: String = "") {
val owner: StructCodegen? = null) {
val fields = ArrayList<LLVMVariable>()
val fieldsIndex = HashMap<String, LLVMClassVariable>()
@@ -29,8 +29,7 @@ abstract class StructCodegen(open val state: TranslationState,
var methods = HashMap<String, FunctionCodegen>()
abstract val structName: String
val fullName: String
get() = "${if (prefix.length > 0) "${prefix}_" else ""}$structName"
get() = "${if (type.location.size > 0) "${type.location.joinToString(".")}." else ""}$structName"
fun generate(declarations: List<KtDeclaration>) {
generateStruct()
@@ -71,7 +70,7 @@ abstract class StructCodegen(open val state: TranslationState,
ClassCodegen(state,
VariableManager(state.globalVariableCollection),
declaration, codeBuilder,
fullName))
this))
}
}
}
@@ -7,10 +7,14 @@ class LLVMReferenceType(val type: String, var prefix: String = "", override val
override val defaultValue: String = ""
override var size: Int = 4
override fun toString() = "%$prefix${if (prefix.length > 0) "." else ""}$type"
override fun toString() = "%$prefix${if (prefix.length > 0) "." else ""}${
if (location.size > 0) "${location.joinToString(".")}." else ""
}$type"
private val params = ArrayList<String>()
val location = ArrayList<String>()
fun addParam(param: String) {
params.add(param)
}
@@ -0,0 +1 @@
nested_test_1(1) == 1
@@ -0,0 +1,13 @@
class Outer() {
class Nested(var i: Int) {
}
}
fun nested_test_1(k: Int): Int {
val j = Outer.Nested(k - 1)
j.i = k
return j.i
}