diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt index 17a24848131..d89c290da8d 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ConstructorConverter.kt @@ -204,7 +204,7 @@ class ConstructorConverter( val parameterModifiers = converter.convertModifiers(propertyInfo, classKind) FunctionParameter(propertyInfo.identifier, type, - if (propertyInfo.isVal) FunctionParameter.VarValModifier.Val else FunctionParameter.VarValModifier.Var, + if (propertyInfo.isVar) FunctionParameter.VarValModifier.Var else FunctionParameter.VarValModifier.Val, converter.convertAnnotations(parameter) + converter.convertAnnotations(field), parameterModifiers, default) diff --git a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt index 2adb642be4a..94910f6b59f 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/Converter.kt @@ -109,7 +109,7 @@ class Converter private constructor( is PsiJavaFile -> convertFile(element) is PsiClass -> convertClass(element) is PsiMethod -> convertMethod(element, null, null, null, ClassKind.FINAL_CLASS) - is PsiField -> convertProperty(PropertyInfo.fromFieldWithNoAccessors(element, element.isVal(referenceSearcher)), ClassKind.FINAL_CLASS) + is PsiField -> convertProperty(PropertyInfo.fromFieldWithNoAccessors(element, element.isVar(referenceSearcher)), ClassKind.FINAL_CLASS) is PsiStatement -> createDefaultCodeConverter().convertStatement(element) is PsiExpression -> createDefaultCodeConverter().convertExpression(element) is PsiImportList -> convertImportList(element) @@ -331,7 +331,7 @@ class Converter private constructor( val shouldDeclareType = settings.specifyFieldTypeByDefault || field == null - || shouldDeclareVariableType(field, propertyType, propertyInfo.isVal && modifiers.isPrivate) + || shouldDeclareVariableType(field, propertyType, !propertyInfo.isVar && modifiers.isPrivate) //TODO: usage processings for converting method's to property if (field != null) { @@ -364,7 +364,7 @@ class Converter private constructor( val property = Property(name, annotations, modifiers, - propertyInfo.isVal, + propertyInfo.isVar, propertyType, shouldDeclareType, deferredElement { codeConverter -> field?.let { codeConverter.convertExpression(it.initializer, it.type) } ?: Expression.Empty }, diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ReferenceSearcher.kt b/j2k/src/org/jetbrains/kotlin/j2k/ReferenceSearcher.kt index 4806973c8e6..2edd31804a9 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ReferenceSearcher.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ReferenceSearcher.kt @@ -42,25 +42,26 @@ public fun ReferenceSearcher.findMethodCalls(method: PsiMethod, scope: PsiElemen }.filterNotNull() } -public fun PsiField.isVal(searcher: ReferenceSearcher): Boolean { - if (hasModifierProperty(PsiModifier.FINAL)) return true - if (!hasModifierProperty(PsiModifier.PRIVATE)) return false - val containingClass = getContainingClass() ?: return false +public fun PsiField.isVar(searcher: ReferenceSearcher): Boolean { + if (hasModifierProperty(PsiModifier.FINAL)) return false + if (!hasModifierProperty(PsiModifier.PRIVATE)) return true + val containingClass = getContainingClass() ?: return true val writes = searcher.findVariableUsages(this, containingClass).filter { PsiUtil.isAccessedForWriting(it) } - if (writes.size() == 0) return true - if (writes.size() > 1) return false + if (writes.size() == 0) return false + if (writes.size() > 1) return true val write = writes.single() val parent = write.getParent() - if (parent is PsiAssignmentExpression && - parent.getOperationSign().getTokenType() == JavaTokenType.EQ && - write.isQualifierEmptyOrThis()) { + if (parent is PsiAssignmentExpression + && parent.getOperationSign().getTokenType() == JavaTokenType.EQ + && write.isQualifierEmptyOrThis() + ) { val constructor = write.getContainingConstructor() - return constructor != null && - constructor.getContainingClass() == containingClass && - parent.getParent() is PsiExpressionStatement && - parent.getParent()?.getParent() == constructor.getBody() + return constructor == null + || constructor.containingClass != containingClass + || !(parent.parent is PsiExpressionStatement) + || parent.parent?.parent != constructor.body } - return false + return true } public fun PsiVariable.hasWriteAccesses(searcher: ReferenceSearcher, scope: PsiElement?): Boolean diff --git a/j2k/src/org/jetbrains/kotlin/j2k/Utils.kt b/j2k/src/org/jetbrains/kotlin/j2k/Utils.kt index e322c01b3c5..d3e97f13c3f 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/Utils.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/Utils.kt @@ -16,11 +16,10 @@ package org.jetbrains.kotlin.j2k -import org.jetbrains.kotlin.types.expressions.OperatorConventions import com.intellij.psi.* -import com.intellij.psi.util.PsiUtil -import org.jetbrains.kotlin.j2k.ast.* import com.intellij.psi.util.PsiMethodUtil +import org.jetbrains.kotlin.j2k.ast.* +import org.jetbrains.kotlin.types.expressions.OperatorConventions fun quoteKeywords(packageName: String): String = packageName.split('.').map { Identifier.toKotlin(it) }.joinToString(".") @@ -45,7 +44,7 @@ fun getDefaultInitializer(property: Property): Expression? { } fun shouldGenerateDefaultInitializer(searcher: ReferenceSearcher, field: PsiField) - = field.getInitializer() == null && !(field.isVal(searcher) && field.hasWriteAccesses(searcher, field.getContainingClass())) + = field.initializer == null && (field.isVar(searcher) || !field.hasWriteAccesses(searcher, field.containingClass)) fun PsiReferenceExpression.isQualifierEmptyOrThis(): Boolean { val qualifier = getQualifierExpression() diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Property.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Property.kt index 61364513fc6..71261260e8d 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Property.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Property.kt @@ -24,7 +24,7 @@ class Property( val identifier: Identifier, annotations: Annotations, modifiers: Modifiers, - val isVal: Boolean, + val isVar: Boolean, val type: Type, val explicitType: Boolean, private val initializer: DeferredElement, @@ -50,7 +50,7 @@ class Property( override fun generateCode(builder: CodeBuilder) { builder.append(annotations) .appendWithSpaceAfter(presentationModifiers()) - .append(if (isVal) "val " else "var ") + .append(if (isVar) "var " else "val ") .append(identifier) if (explicitType) { diff --git a/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt b/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt index 8a3fca9233a..7a2a4a9c622 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/propertyDetection.kt @@ -30,7 +30,7 @@ import java.util.* class PropertyInfo( val name: String, - val isVal: Boolean, + val isVar: Boolean, val psiType: PsiType, val field: PsiField?, val getMethod: PsiMethod?, @@ -57,8 +57,8 @@ class PropertyInfo( val needExplicitSetter: Boolean get() = needSetterBody || specialSetterAccess != null companion object { - fun fromFieldWithNoAccessors(field: PsiField, isVal: Boolean) - = PropertyInfo(field.name ?: "", isVal, field.type, field, null, null, false, false, null, false) + fun fromFieldWithNoAccessors(field: PsiField, isVar: Boolean) + = PropertyInfo(field.name ?: "", isVar, field.type, field, null, null, false, false, null, false) } } @@ -128,7 +128,7 @@ private class PropertyDetector( val getterAccess = if (getterInfo != null) converter.convertModifiers(getterInfo.method, false).accessModifier() else Modifier.PUBLIC //TODO val setterAccess = if (setterInfo != null) converter.convertModifiers(setterInfo.method, false).accessModifier() - else if (field != null && !field.isVal(converter.referenceSearcher)) + else if (field != null && field.isVar(converter.referenceSearcher)) converter.convertModifiers(field, false).accessModifier() else getterAccess @@ -138,17 +138,17 @@ private class PropertyDetector( //TODO: no body for getter OR setter - val isVal = if (setterInfo != null) - false - else if (getterInfo!!.superProperty != null && !getterInfo.superProperty!!.isVal) - false + val isVar = if (setterInfo != null) + true + else if (getterInfo!!.superProperty != null && getterInfo.superProperty!!.isVar) + true else - field == null || field.isVal(converter.referenceSearcher) + field != null && field.isVar(converter.referenceSearcher) val type = field?.type ?: getterInfo?.method?.returnType ?: setterInfo!!.method.parameterList.parameters.single()?.type!! val propertyInfo = PropertyInfo(propertyName, - isVal, + isVar, type, field, getterInfo?.method, @@ -179,7 +179,7 @@ private class PropertyDetector( // map all other fields for (field in psiClass.fields) { if (field !in mappedFields) { - val propertyInfo = PropertyInfo.fromFieldWithNoAccessors(field, field.isVal(converter.referenceSearcher)) + val propertyInfo = PropertyInfo.fromFieldWithNoAccessors(field, field.isVar(converter.referenceSearcher)) memberToPropertyInfo[field] = propertyInfo } } @@ -215,7 +215,7 @@ private class PropertyDetector( continue } - if (!propertyInfo.isVal) { + if (propertyInfo.isVar) { val setterName = JvmAbi.setterName(propertyInfo.name) val setterSignature = MethodSignatureUtil.createMethodSignature(setterName, arrayOf(propertyInfo.psiType), emptyArray(), PsiSubstitutor.EMPTY) if (setterSignature in prohibitedSignatures) { @@ -235,7 +235,7 @@ private class PropertyDetector( ) private class SuperPropertyInfo( - val isVal: Boolean + val isVar: Boolean //TODO: add visibility ) @@ -261,11 +261,11 @@ private class PropertyDetector( val containingClass = method.containingClass!! val superPropertyInfo: SuperPropertyInfo? = if (converter.inConversionScope(containingClass)) { val propertyInfo = converter.propertyDetectionCache[containingClass][method] - if (propertyInfo != null) SuperPropertyInfo(propertyInfo.isVal) else null + if (propertyInfo != null) SuperPropertyInfo(propertyInfo.isVar) else null } else if (method is KotlinLightMethod) { val origin = method.getOrigin() - if (origin is JetProperty) SuperPropertyInfo(!origin.isVar) else null + if (origin is JetProperty) SuperPropertyInfo(origin.isVar) else null } else { null