diff --git a/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt b/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt index a189c22d738..733b7da19e6 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt @@ -37,7 +37,21 @@ class ConstructorConverter(private val converter: Converter) { } else { val params = converter.convertParameterList(constructor.getParameterList()) - var body = postProcessBody(converter.convertBlock(constructor.getBody())) + val bodyConverter = converter.withExpressionVisitor { object : ExpressionVisitor(it, mapOf()/*TODO: see KT-5327*/) { + override fun visitReferenceExpression(expression: PsiReferenceExpression) { + if (isQualifierEmptyOrThis(expression)) { + val field = expression.getReference()?.resolve() as? PsiField + if (field != null && field.getContainingClass() == constructor.getContainingClass()) { + val isNullable = typeConverter.variableNullability(field).isNullable(converter.settings) + result = QualifiedExpression(tempValIdentifier(), Identifier(expression.getReferenceName()!!, isNullable).assignNoPrototype()) + return + } + } + + super.visitReferenceExpression(expression) + } + }} + var body = postProcessBody(bodyConverter.convertBlock(constructor.getBody())) val containingClass = constructor.getContainingClass() val typeParameterList = converter.convertTypeParameterList(containingClass?.getTypeParameterList()) val factoryFunctionType = ClassType(containingClass?.declarationIdentifier() ?: Identifier.Empty, @@ -84,8 +98,8 @@ class ConstructorConverter(private val converter: Converter) { } } - val correctedConverter = converter.withExpressionVisitor { ExpressionVisitor(it, usageReplacementMap) } - postProcessBody(correctedConverter.convertBlock(body, false, { !statementsToRemove.contains(it) })) + val bodyConverter = converter.withExpressionVisitor { ExpressionVisitor(it, usageReplacementMap) } + postProcessBody(bodyConverter.convertBlock(body, false, { !statementsToRemove.contains(it) })) } else { Block.Empty @@ -163,7 +177,7 @@ class ConstructorConverter(private val converter: Converter) { var keepStatement = true if (statement is AssignmentExpression) { val assignee = statement.left - if (assignee is QualifiedExpression && (assignee.qualifier as? Identifier)?.name == FactoryFunction.tempValName) { + if (assignee is QualifiedExpression && (assignee.qualifier as? Identifier)?.name == tempValName) { val name = (assignee.identifier as Identifier).name for (field in finalOrWithEmptyInitializerFields) { if (name == field.identifier.name) { @@ -185,14 +199,14 @@ class ConstructorConverter(private val converter: Converter) { className.name, finalOrWithEmptyInitializerFields.map { initializers[it]!! }).assignNoPrototype() if (statements.isNotEmpty()) { - val localVar = LocalVariable(FactoryFunction.tempValIdentifier(), + val localVar = LocalVariable(tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, initializer, true).assignNoPrototype() statements.add(0, DeclarationStatement(listOf(localVar)).assignNoPrototype()) - statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype()) + statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype()) } else { statements.add(ReturnStatement(initializer).assignNoPrototype()) @@ -235,16 +249,19 @@ class ConstructorConverter(private val converter: Converter) { statements[i] = ReturnStatement(constructorCall).assignNoPrototype() return statements } - val localVar = LocalVariable(FactoryFunction.tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype() + val localVar = LocalVariable(tempValIdentifier(), Annotations.Empty, Modifiers.Empty, null, constructorCall, true).assignNoPrototype() statements[i] = DeclarationStatement(listOf(localVar)).assignNoPrototype() break } } } - statements.add(ReturnStatement(FactoryFunction.tempValIdentifier()).assignNoPrototype()) + statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype()) return statements } private fun ClassBody.factoryFunctions() = classObjectMembers.filterIsInstance(javaClass()) + + private val tempValName: String = "__" + private fun tempValIdentifier(): Identifier = Identifier(tempValName, false).assignNoPrototype() } \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt index 37a6dd55b7e..dbccac34977 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt @@ -58,28 +58,4 @@ class FactoryFunction(annotations: Annotations, parameterList: ParameterList, typeParameterList: TypeParameterList, block: Block) -: Function(Identifier("create").assignNoPrototype(), annotations, modifiers, returnType, typeParameterList, parameterList, block, false) { - - /* - public fun toFactoryFunction(containingClass: Class?): Function { - val statements = ArrayList(block?.statements ?: listOf()) - statements.add(ReturnStatement(tempValIdentifier()).assignNoPrototype()) - val newBlock = Block(statements, block?.lBrace ?: LBrace().assignNoPrototype(), block?.rBrace ?: RBrace().assignNoPrototype()) - if (block != null) { - newBlock.assignPrototypesFrom(block!!) - } - - val typeParameters = if (containingClass != null) containingClass.typeParameterList.parameters else listOf() - val typeParameterList = TypeParameterList(typeParameters).assignNoPrototype() - - val returnType = ClassType(containingClass?.name ?: Identifier.Empty, typeParameters, Nullability.NotNull, converter.settings).assignNoPrototype() - return Function(converter, Identifier("create").assignNoPrototype(), annotations, modifiers, - returnType, typeParameterList, parameterList, newBlock, false).assignPrototypesFrom(this) - } - */ - - class object { - public val tempValName: String = "__" - public fun tempValIdentifier(): Identifier = Identifier(tempValName, false).assignNoPrototype() - } -} +: Function(Identifier("create").assignNoPrototype(), annotations, modifiers, returnType, typeParameterList, parameterList, block, false) \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt index 4a165da519d..a5232849994 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt @@ -36,7 +36,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi import org.jetbrains.jet.lang.psi.JetParameter import org.jetbrains.jet.lang.psi.JetNamedDeclaration -class ExpressionVisitor(private val converter: Converter, +open class ExpressionVisitor(private val converter: Converter, private val usageReplacementMap: Map = mapOf()) : JavaElementVisitor() { private val typeConverter = converter.typeConverter @@ -308,27 +308,17 @@ class ExpressionVisitor(private val converter: Converter, } override fun visitReferenceExpression(expression: PsiReferenceExpression) { - val referencedName = expression.getReferenceName()!! + val referenceName = expression.getReferenceName()!! val target = expression.getReference()?.resolve() val isNullable = if (target is PsiVariable) typeConverter.variableNullability(target).isNullable(converter.settings) else false - - val containingConstructor = expression.getContainingConstructor() - val insideSecondaryConstructor = containingConstructor != null && !containingConstructor.isPrimaryConstructor() - if (insideSecondaryConstructor && - isQualifierEmptyOrThis(expression) && - (expression.getReference()?.resolve() as? PsiField)?.getContainingClass() == containingConstructor!!.getContainingClass()) { - result = QualifiedExpression(FactoryFunction.tempValIdentifier(), Identifier(referencedName, isNullable).assignNoPrototype()) - return - } - - var identifier = Identifier(referencedName, isNullable).assignNoPrototype() val qualifier = expression.getQualifierExpression() - if (qualifier != null && qualifier.getType() is PsiArrayType && referencedName == "length") { + var identifier = Identifier(referenceName, isNullable).assignNoPrototype() + if (qualifier != null && qualifier.getType() is PsiArrayType && referenceName == "length") { identifier = Identifier("size", isNullable).assignNoPrototype() } else if (qualifier != null) { - if (referencedName == JvmAbi.CLASS_OBJECT_FIELD || referencedName == JvmAbi.INSTANCE_FIELD) { + if (referenceName == JvmAbi.CLASS_OBJECT_FIELD || referenceName == JvmAbi.INSTANCE_FIELD) { if (target is LightField) { //TODO: should be KotlinLightField with check of origin here, see KT-5188 result = converter.convertExpression(qualifier) return @@ -349,7 +339,7 @@ class ExpressionVisitor(private val converter: Converter, && !PsiTreeUtil.isAncestor(target.getContainingClass(), expression, true) && !isStaticallyImported(target, expression)) { var member: PsiMember = target - var code = Identifier.toKotlin(referencedName) + var code = Identifier.toKotlin(referenceName) while (member.getContainingClass() != null) { code = Identifier.toKotlin(member.getContainingClass()!!.getName()!!) + "." + code member = member.getContainingClass()!!