From a84b32af98d49af30a5a0e572b9ca29f4ed1ce12 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 14 Oct 2014 17:33:20 +0400 Subject: [PATCH] KT-5492 J2K: convert field with getter/setter to property #KT-5492 Fixed --- .../openapi/util/text/annotations.xml | 5 + .../jetbrains/jet/j2k/ClassBodyConverter.kt | 161 +++++++++++++++++- .../jetbrains/jet/j2k/ConstructorConverter.kt | 88 ++++++---- j2k/src/org/jetbrains/jet/j2k/Converter.kt | 63 +++---- j2k/src/org/jetbrains/jet/j2k/Utils.kt | 7 +- .../org/jetbrains/jet/j2k/ast/ClassBody.kt | 2 +- j2k/src/org/jetbrains/jet/j2k/ast/Field.kt | 11 +- j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt | 3 +- .../jet/j2k/visitors/ExpressionVisitor.kt | 21 ++- .../JavaToKotlinConverterTestGenerated.java | 89 +++++++++- .../testData/ast/class/abstractClassShape.kt | 8 - .../ast/constructors/customerBuilder.kt | 10 +- .../ast/constructors/genericIdentifier.kt | 6 +- .../testData/ast/constructors/identifier.kt | 6 +- .../dropAccessors/AccessInGetterWithThis.java | 7 + .../dropAccessors/AccessInGetterWithThis.kt | 3 + .../dropAccessors/CannotDropOnlySetter.java | 7 + .../ast/dropAccessors/CannotDropOnlySetter.kt | 7 + .../testData/ast/dropAccessors/DataClass.java | 28 +++ .../testData/ast/dropAccessors/DataClass.kt | 6 + .../DataClassWithMutableField.java | 15 ++ .../DataClassWithMutableField.kt | 12 ++ .../ast/dropAccessors/DifferentFieldName.java | 13 ++ .../ast/dropAccessors/DifferentFieldName.kt | 10 ++ .../ast/dropAccessors/DropGetter.java | 7 + .../testData/ast/dropAccessors/DropGetter.kt | 3 + .../dropAccessors/DropGetterAndSetter.java | 11 ++ .../ast/dropAccessors/DropGetterAndSetter.kt | 3 + .../dropAccessors/DropGetterForMutable.java | 11 ++ .../ast/dropAccessors/DropGetterForMutable.kt | 8 + .../ast/dropAccessors/FalseGetter.java | 8 + .../testData/ast/dropAccessors/FalseGetter.kt | 8 + .../ast/dropAccessors/FalseSetter.java | 11 ++ .../testData/ast/dropAccessors/FalseSetter.kt | 8 + .../FieldUsagesInFactoryMethods.java | 35 ++++ .../FieldUsagesInFactoryMethods.kt | 23 +++ .../GetterAndSetterNamesDifferent.java | 11 ++ .../GetterAndSetterNamesDifferent.kt | 8 + .../GetterSetterUsages.java.todo | 19 +++ .../ast/dropAccessors/GetterSetterUsages.kt | 11 ++ .../QualifyFieldUsagesOnRename.java.todo | 32 ++++ j2k/tests/testData/ast/enum/colorEnum.kt | 6 +- .../fieldsWithPrimaryPrivateConstructor.kt | 6 +- .../ast/enum/primaryPrivateConstructor.kt | 7 +- j2k/tests/testData/ast/issues/kt-638.kt | 6 +- 45 files changed, 691 insertions(+), 139 deletions(-) create mode 100644 annotations/com/intellij/openapi/util/text/annotations.xml create mode 100644 j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.java create mode 100644 j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.java create mode 100644 j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/DataClass.java create mode 100644 j2k/tests/testData/ast/dropAccessors/DataClass.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.java create mode 100644 j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/DifferentFieldName.java create mode 100644 j2k/tests/testData/ast/dropAccessors/DifferentFieldName.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/DropGetter.java create mode 100644 j2k/tests/testData/ast/dropAccessors/DropGetter.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.java create mode 100644 j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.java create mode 100644 j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/FalseGetter.java create mode 100644 j2k/tests/testData/ast/dropAccessors/FalseGetter.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/FalseSetter.java create mode 100644 j2k/tests/testData/ast/dropAccessors/FalseSetter.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.java create mode 100644 j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.java create mode 100644 j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.java.todo create mode 100644 j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.kt create mode 100644 j2k/tests/testData/ast/dropAccessors/QualifyFieldUsagesOnRename.java.todo diff --git a/annotations/com/intellij/openapi/util/text/annotations.xml b/annotations/com/intellij/openapi/util/text/annotations.xml new file mode 100644 index 00000000000..92e32317eee --- /dev/null +++ b/annotations/com/intellij/openapi/util/text/annotations.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/j2k/src/org/jetbrains/jet/j2k/ClassBodyConverter.kt b/j2k/src/org/jetbrains/jet/j2k/ClassBodyConverter.kt index efc27184492..8f9741175e2 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ClassBodyConverter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ClassBodyConverter.kt @@ -24,21 +24,43 @@ import com.intellij.psi.PsiAnnotationMethod import java.util.ArrayList import com.intellij.psi.PsiModifier import com.intellij.psi.PsiMethod -import com.intellij.psi.PsiField -import com.intellij.psi.PsiClassInitializer import org.jetbrains.jet.j2k.ast.* +import com.intellij.psi.PsiField +import com.intellij.psi.PsiReturnStatement +import com.intellij.psi.PsiReferenceExpression +import com.intellij.openapi.util.text.StringUtil +import java.util.HashMap +import com.intellij.psi.PsiClassInitializer +import com.intellij.psi.PsiExpressionStatement +import com.intellij.psi.PsiAssignmentExpression +import com.intellij.psi.PsiExpression +import com.intellij.psi.JavaTokenType +import org.jetbrains.jet.j2k.visitors.ExpressionConverter +import com.intellij.psi.PsiElementFactory + +class FieldCorrectionInfo(val name: Identifier, val access: Modifier?, val setterAccess: Modifier?) class ClassBodyConverter(private val psiClass: PsiClass, - private val converter: Converter, - private val constructorConverter: ConstructorConverter?) { + private val converter: Converter) { + private val membersToRemove = HashSet() + private val fieldCorrections = HashMap() + public fun convertBody(): ClassBody { - val membersToRemove = HashSet() + processAccessorsToDrop() + + val correctedConverter = buildConverterWithCorrectedFieldNames() + + val constructorConverter = if (psiClass.getName() != null) + ConstructorConverter(psiClass, correctedConverter, fieldCorrections) + else + null + val convertedMembers = LinkedHashMap() for (element in psiClass.getChildren()) { if (element is PsiMember) { if (element is PsiAnnotationMethod) continue // converted in convertAnnotationType() - val converted = converter.convertMember(element, membersToRemove, constructorConverter) + val converted = correctedConverter.convertMember(element, membersToRemove, constructorConverter) if (converted != null && !converted.isEmpty) { convertedMembers.put(element, converted) } @@ -78,7 +100,21 @@ class ClassBodyConverter(private val psiClass: PsiClass, val lBrace = LBrace().assignPrototype(psiClass.getLBrace()) val rBrace = RBrace().assignPrototype(psiClass.getRBrace()) - return ClassBody(primaryConstructorSignature, members, classObjectMembers, factoryFunctions, lBrace, rBrace) + val classBody = ClassBody(primaryConstructorSignature, constructorConverter?.baseClassParams ?: listOf(), members, classObjectMembers, factoryFunctions, lBrace, rBrace) + + return if (constructorConverter != null) constructorConverter.postProcessConstructors(classBody) else classBody + } + + private fun Converter.convertMember(member: PsiMember, + membersToRemove: MutableSet, + constructorConverter: ConstructorConverter?): Member? { + return when (member) { + is PsiMethod -> convertMethod(member, membersToRemove, constructorConverter) + is PsiField -> convertField(member, fieldCorrections[member]) + is PsiClass -> convertClass(member) + is PsiClassInitializer -> convertInitializer(member) + else -> throw IllegalArgumentException("Unknown member: $member") + } } // do not convert private static methods into class object if possible @@ -101,4 +137,115 @@ class ClassBodyConverter(private val psiClass: PsiClass, // we generate nested classes with factory functions into class object as a workaround until secondary constructors supported by Kotlin private fun shouldGenerateIntoClassObject(nestedClass: Class) = !nestedClass.modifiers.contains(Modifier.INNER) && nestedClass.body.factoryFunctions.isNotEmpty() + + private fun processAccessorsToDrop() { + val fieldToGetterInfo = HashMap() + val fieldToSetterInfo = HashMap() + val fieldsWithConflict = HashSet() + for (method in psiClass.getMethods()) { + val info = getAccessorInfo(method) ?: continue + val map = if (info.kind == AccessorKind.GETTER) fieldToGetterInfo else fieldToSetterInfo + + val prevInfo = map[info.field] + if (prevInfo != null) { + fieldsWithConflict.add(info.field) + continue + } + + map[info.field] = info + } + + for ((field, getterInfo) in fieldToGetterInfo) { + val setterInfo = run { + val info = fieldToSetterInfo[field] + if (info?.propertyName == getterInfo.propertyName) info else null + } + + membersToRemove.add(getterInfo.method) + if (setterInfo != null) { + membersToRemove.add(setterInfo.method) + } + + val getterAccess = converter.convertModifiers(getterInfo.method).accessModifier() + val setterAccess = if (setterInfo != null) + converter.convertModifiers(setterInfo.method).accessModifier() + else + converter.convertModifiers(field).accessModifier() + //TODO: check that setter access is not bigger + fieldCorrections[field] = FieldCorrectionInfo(Identifier(getterInfo.propertyName).assignNoPrototype(), + getterAccess, + setterAccess) + } + } + + private enum class AccessorKind { + GETTER + SETTER + } + + private class AccessorInfo(val method: PsiMethod, val field: PsiField, val kind: AccessorKind, val propertyName: String) + + private fun getAccessorInfo(method: PsiMethod): AccessorInfo? { + val name = method.getName() + if (name.startsWith("get") && method.getParameterList().getParametersCount() == 0) { + val body = method.getBody() ?: return null + val returnStatement = (body.getStatements().singleOrNull() as? PsiReturnStatement) ?: return null + val field = fieldByExpression(returnStatement.getReturnValue()) ?: return null + val propertyName = StringUtil.decapitalize(name.substring("get".length)) + return AccessorInfo(method, field, AccessorKind.GETTER, propertyName) + } + else if (name.startsWith("set") && method.getParameterList().getParametersCount() == 1) { + val body = method.getBody() ?: return null + val statement = (body.getStatements().singleOrNull() as? PsiExpressionStatement) ?: return null + val assignment = statement.getExpression() as? PsiAssignmentExpression ?: return null + if (assignment.getOperationTokenType() != JavaTokenType.EQ) return null + val field = fieldByExpression(assignment.getLExpression()) ?: return null + if ((assignment.getRExpression() as? PsiReferenceExpression)?.resolve() != method.getParameterList().getParameters().single()) return null + val propertyName = StringUtil.decapitalize(name.substring("set".length)) + return AccessorInfo(method, field, AccessorKind.SETTER, propertyName) + } + else { + return null + } + } + + private fun fieldByExpression(expression: PsiExpression?): PsiField? { + val refExpr = expression as? PsiReferenceExpression ?: return null + if (!refExpr.isQualifierEmptyOrThis()) return null + val field = refExpr.resolve() as? PsiField ?: return null + if (field.getContainingClass() != psiClass || field.hasModifierProperty(PsiModifier.STATIC)) return null + return field + } + + //TODO: correct usages to accessors (and field too) across all code being converted + all other Kotlin code in the project + private fun buildConverterWithCorrectedFieldNames(): Converter { + if (fieldCorrections.isEmpty()) return converter + return converter.withExpressionConverter { prevExpressionConverter -> + object : ExpressionConverter { + override fun convertExpression(expression: PsiExpression, converter: Converter): Expression { + val result = prevExpressionConverter.convertExpression(expression, converter) + if (expression !is PsiReferenceExpression) return result + + val field = expression.resolve() as? PsiField ?: return result + val correction = fieldCorrections[field] ?: return result + if (correction.name.name == field.getName()) return result + + val qualifier = expression.getQualifierExpression() + return if (qualifier != null) { + QualifiedExpression(converter.convertExpression(qualifier), correction.name) + } + else { + // check if field name is shadowed + val elementFactory = PsiElementFactory.SERVICE.getInstance(expression.getProject()) + val refExpr = elementFactory.createExpressionFromText(correction.name.name, expression) as PsiReferenceExpression + if (refExpr.resolve() == null) + correction.name + else + QualifiedExpression(ThisExpression(Identifier.Empty).assignNoPrototype(), correction.name) //TODO: this is not correct in case of nested/anonymous classes + } + + } + } + } + } } \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt b/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt index f6309743320..89ee5e25154 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ConstructorConverter.kt @@ -18,13 +18,15 @@ package org.jetbrains.jet.j2k import com.intellij.psi.* import org.jetbrains.jet.j2k.ast.* -import org.jetbrains.jet.j2k.visitors.ExpressionVisitor import com.intellij.psi.util.PsiUtil import java.util.HashMap import java.util.ArrayList import java.util.HashSet +import org.jetbrains.jet.j2k.visitors.ExpressionConverter -class ConstructorConverter(private val psiClass: PsiClass, private val converter: Converter) { +class ConstructorConverter(private val psiClass: PsiClass, + private val converter: Converter, + private val fieldCorrections: Map) { private val typeConverter = converter.typeConverter private val tempValName: String = "__" @@ -163,23 +165,25 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter if (constructor in constructorsToDrop) return null val params = converter.convertParameterList(constructor.getParameterList()) - val bodyConverter = converter.withExpressionVisitor { object : ExpressionVisitor(it) { - override fun visitReferenceExpression(expression: PsiReferenceExpression) { - if (isQualifierEmptyOrThis(expression)) { - val member = expression.getReference()?.resolve() as? PsiMember - if (member != null && + val bodyConverter = converter.withExpressionConverter { prevExpressionConverter -> + object : ExpressionConverter { + override fun convertExpression(expression: PsiExpression, converter: Converter): Expression { + if (expression is PsiReferenceExpression && expression.isQualifierEmptyOrThis()) { + val member = expression.getReference()?.resolve() as? PsiMember + if (member != null && !member.isConstructor() && member.getContainingClass() == constructor.getContainingClass()) { - val isNullable = member is PsiField && typeConverter.variableNullability(member).isNullable(converter.settings) - val qualifier = if (member.hasModifierProperty(PsiModifier.STATIC)) constructor.declarationIdentifier() else tempValIdentifier() - result = QualifiedExpression(qualifier, Identifier(expression.getReferenceName()!!, isNullable).assignNoPrototype()) - return + val isNullable = member is PsiField && typeConverter.variableNullability(member).isNullable(converter.settings) + val qualifier = if (member.hasModifierProperty(PsiModifier.STATIC)) constructor.declarationIdentifier() else tempValIdentifier() + val name = fieldCorrections[member]?.name ?: Identifier(expression.getReferenceName()!!, isNullable).assignNoPrototype() + return QualifiedExpression(qualifier, name) + } } - } - super.visitReferenceExpression(expression) + return prevExpressionConverter.convertExpression(expression, converter) + } } - }} + } var body = postProcessBody(bodyConverter.convertBlock(constructor.getBody())) val containingClass = constructor.getContainingClass() val typeParameterList = converter.convertTypeParameterList(containingClass?.getTypeParameterList()) @@ -219,20 +223,27 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter continue } + val fieldCorrection = fieldCorrections[field] + // we cannot specify different setter access for constructor parameter + if (fieldCorrection != null && !isVal(converter.referenceSearcher, field) && fieldCorrection.access != fieldCorrection.setterAccess) continue + parameterToField.put(parameter, field to type) statementsToRemove.add(initializationStatement) membersToRemove.add(field) - if (field.getName() != parameter.getName()) { - parameterUsageReplacementMap.put(parameter.getName()!!, field.getName()!!) + val fieldName = fieldCorrection?.name?.name ?: field.getName()!! + if (fieldName != parameter.getName()) { + parameterUsageReplacementMap.put(parameter.getName()!!, fieldName) } } - val bodyConverter = converter.withExpressionVisitor { - object : ReplacingExpressionVisitor(this, parameterUsageReplacementMap, it) { - override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { - if (expression.isSuperConstructorCall()) return // skip it - super.visitMethodCallExpression(expression) + val bodyConverter = converter.withExpressionConverter { prevExpressionConverter -> + object : ReplacingExpressionConverter(this, parameterUsageReplacementMap, prevExpressionConverter) { + override fun convertExpression(expression: PsiExpression, converter: Converter): Expression { + if (expression is PsiMethodCallExpression && expression.isSuperConstructorCall()) { + return Expression.Empty // skip it + } + return super.convertExpression(expression, converter) } } } @@ -243,7 +254,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter } // we need to replace renamed parameter usages in base class constructor arguments and in default values - val correctedConverter = converter.withExpressionVisitor { ReplacingExpressionVisitor(this, parameterUsageReplacementMap, it) } + val correctedConverter = converter.withExpressionConverter { prevExpressionConverter -> ReplacingExpressionConverter(this, parameterUsageReplacementMap, prevExpressionConverter) } .withSpecialContext(psiClass) /* to correct nested class references */ val statement = primaryConstructor.getBody()?.getStatements()?.firstOrNull() @@ -264,11 +275,17 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter } else { val (field, type) = parameterToField[parameter]!! - Parameter(field.declarationIdentifier(), + val fieldCorrection = fieldCorrections[field] + val name = fieldCorrection?.name ?: field.declarationIdentifier() + val accessModifiers = if (fieldCorrection != null) + Modifiers(listOf()).with(fieldCorrection.access).assignNoPrototype() + else + converter.convertModifiers(field).filter { it in ACCESS_MODIFIERS } + Parameter(name, type, if (isVal(converter.referenceSearcher, field)) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var, converter.convertAnnotations(parameter) + converter.convertAnnotations(field), - converter.convertModifiers(field).filter { it in ACCESS_MODIFIERS }, + accessModifiers, defaultValue).assignPrototypes(listOf(parameter, field), CommentsAndSpacesInheritance(blankLinesBefore = false)) } }).assignPrototype(primaryConstructor.getParameterList()) @@ -286,7 +303,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter val assignment = ref.getParent() as? PsiAssignmentExpression ?: continue if (assignment.getOperationSign().getTokenType() != JavaTokenType.EQ) continue val assignee = assignment.getLExpression() as? PsiReferenceExpression ?: continue - if (!isQualifierEmptyOrThis(assignee)) continue + if (!assignee.isQualifierEmptyOrThis()) continue val field = assignee.resolve() as? PsiField ?: continue if (field.getContainingClass() != constructor.getContainingClass()) continue if (field.hasModifierProperty(PsiModifier.STATIC)) continue @@ -297,7 +314,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter if (statement.getParent() != body) continue // and no other assignments to field should exist in the constructor - if (converter.referenceSearcher.findVariableUsages(field, body).any { it != assignee && PsiUtil.isAccessedForWriting(it) && isQualifierEmptyOrThis(it) }) continue + if (converter.referenceSearcher.findVariableUsages(field, body).any { it != assignee && PsiUtil.isAccessedForWriting(it) && it.isQualifierEmptyOrThis() }) continue //TODO: check access to field before assignment return field to statement @@ -312,7 +329,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter } else { val updatedFunctions = processFactoryFunctionsWithConstructorCall(classBody.factoryFunctions) - return ClassBody(classBody.primaryConstructorSignature, classBody.members, classBody.classObjectMembers, updatedFunctions, classBody.lBrace, classBody.rBrace) + return ClassBody(classBody.primaryConstructorSignature, classBody.baseClassParams, classBody.members, classBody.classObjectMembers, updatedFunctions, classBody.lBrace, classBody.rBrace) } } @@ -341,7 +358,7 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter val parameterList = ParameterList(parameters).assignNoPrototype() val constructorSignature = PrimaryConstructorSignature(Annotations.Empty, modifiers, parameterList).assignNoPrototype() val updatedMembers = classBody.members.filter { !fieldsToInitialize.contains(it) } - return ClassBody(constructorSignature, updatedMembers, classBody.classObjectMembers, updatedFactoryFunctions, classBody.lBrace, classBody.rBrace) + return ClassBody(constructorSignature, classBody.baseClassParams, updatedMembers, classBody.classObjectMembers, updatedFactoryFunctions, classBody.lBrace, classBody.rBrace) } private fun processFactoryFunctionsWithConstructorCall(functions: List): List { @@ -443,11 +460,11 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter return ref.getCanonicalText() == "super" && ref.resolve()?.isConstructor() ?: false } - private /*inner*//*TODO:KT-5343*/ open class ReplacingExpressionVisitor( - val owner: ConstructorConverter, - val parameterUsageReplacementMap: Map, converter: Converter) : ExpressionVisitor(converter) { - override fun visitReferenceExpression(expression: PsiReferenceExpression) { - if (expression.getQualifier() == null) { + private /*inner*//*TODO: see KT-5343*/ open class ReplacingExpressionConverter(val owner: ConstructorConverter, + val parameterUsageReplacementMap: Map, + val prevExpressionConverter: ExpressionConverter) : ExpressionConverter { + override fun convertExpression(expression: PsiExpression, converter: Converter): Expression { + if (expression is PsiReferenceExpression && expression.getQualifier() == null) { val replacement = parameterUsageReplacementMap[expression.getReferenceName()] if (replacement != null) { val target = expression.getReference()?.resolve() @@ -455,14 +472,13 @@ class ConstructorConverter(private val psiClass: PsiClass, private val converter val scope = target.getDeclarationScope() // we do not check for exactly this constructor because default values reference parameters in other constructors if (scope.isConstructor() && scope.getParent() == owner.psiClass) { - result = Identifier(replacement, owner.typeConverter.variableNullability(target).isNullable(owner.converter.settings)) - return + return Identifier(replacement, converter.typeConverter.variableNullability(target).isNullable(converter.settings)) } } } } - super.visitReferenceExpression(expression) + return prevExpressionConverter.convertExpression(expression, converter) } } } \ No newline at end of file diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt index 5ee0915d671..09ff3452a70 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt @@ -51,7 +51,7 @@ public class Converter private(val project: Project, private val postProcessor: PostProcessor?, private val state: Converter.State) { private class State(val methodReturnType: PsiType?, - val expressionVisitorFactory: (Converter) -> ExpressionVisitor, + val expressionConverter: ExpressionConverter, val statementVisitorFactory: (Converter) -> StatementVisitor, val specialContext: PsiElement?, val importList: ImportList?, @@ -64,7 +64,6 @@ public class Converter private(val project: Project, val importNames: Set = state.importList?.imports?.mapTo(HashSet()) { it.name } ?: setOf() val importsToAdd: MutableCollection? = state.importsToAdd - private val expressionVisitor = state.expressionVisitorFactory(this) private val statementVisitor = state.statementVisitorFactory(this) val annotationConverter = AnnotationConverter(this) @@ -74,34 +73,34 @@ public class Converter private(val project: Project, public fun create(project: Project, settings: ConverterSettings, conversionScope: ConversionScope, referenceSearcher: ReferenceSearcher, postProcessor: PostProcessor?): Converter { - val state = State(null, { ExpressionVisitor(it) }, { StatementVisitor(it) }, null, null, null) + val state = State(null, ExpressionVisitor(), { StatementVisitor(it) }, null, null, null) return Converter(project, settings, conversionScope, referenceSearcher, postProcessor, state) } } fun withMethodReturnType(methodReturnType: PsiType?): Converter = Converter(project, settings, conversionScope, referenceSearcher, postProcessor, - State(methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, state.specialContext, state.importList, state.importsToAdd)) + State(methodReturnType, state.expressionConverter, state.statementVisitorFactory, state.specialContext, state.importList, state.importsToAdd)) - fun withExpressionVisitor(factory: (Converter) -> ExpressionVisitor): Converter + fun withExpressionConverter(factory: (prevConverter: ExpressionConverter) -> ExpressionConverter): Converter = Converter(project, settings, conversionScope, referenceSearcher, postProcessor, - State(state.methodReturnType, factory, state.statementVisitorFactory, state.specialContext, state.importList, state.importsToAdd)) + State(state.methodReturnType, factory(state.expressionConverter), state.statementVisitorFactory, state.specialContext, state.importList, state.importsToAdd)) fun withStatementVisitor(factory: (Converter) -> StatementVisitor): Converter = Converter(project, settings, conversionScope, referenceSearcher, postProcessor, - State(state.methodReturnType, state.expressionVisitorFactory, factory, state.specialContext, state.importList, state.importsToAdd)) + State(state.methodReturnType, state.expressionConverter, factory, state.specialContext, state.importList, state.importsToAdd)) fun withSpecialContext(context: PsiElement): Converter = Converter(project, settings, conversionScope, referenceSearcher, postProcessor, - State(state.methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, context, state.importList, state.importsToAdd)) + State(state.methodReturnType, state.expressionConverter, state.statementVisitorFactory, context, state.importList, state.importsToAdd)) private fun withImportList(importList: ImportList): Converter = Converter(project, settings, conversionScope, referenceSearcher, postProcessor, - State(state.methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, state.specialContext, importList, state.importsToAdd)) + State(state.methodReturnType, state.expressionConverter, state.statementVisitorFactory, state.specialContext, importList, state.importsToAdd)) private fun withImportsToAdd(importsToAdd: MutableCollection): Converter = Converter(project, settings, conversionScope, referenceSearcher, postProcessor, - State(state.methodReturnType, state.expressionVisitorFactory, state.statementVisitorFactory, state.specialContext, state.importList, importsToAdd)) + State(state.methodReturnType, state.expressionConverter, state.statementVisitorFactory, state.specialContext, state.importList, importsToAdd)) public fun elementToKotlin(element: PsiElement): String { try { @@ -141,7 +140,7 @@ public class Converter private(val project: Project, is PsiJavaFile -> convertFile(element) is PsiClass -> convertClass(element) is PsiMethod -> convertMethod(element, null, null) - is PsiField -> convertField(element) + is PsiField -> convertField(element, null) is PsiStatement -> convertStatement(element) is PsiExpression -> convertExpression(element) is PsiImportList -> convertImportList(element) @@ -185,18 +184,10 @@ public class Converter private(val project: Project, } fun convertAnonymousClassBody(anonymousClass: PsiAnonymousClass): AnonymousClassBody { - return AnonymousClassBody(ClassBodyConverter(anonymousClass, this, null).convertBody(), + return AnonymousClassBody(ClassBodyConverter(anonymousClass, this).convertBody(), anonymousClass.getBaseClassType().resolve()?.isInterface() ?: false).assignPrototype(anonymousClass) } - fun convertMember(member: PsiMember, membersToRemove: MutableSet, constructorConverter: ConstructorConverter?): Member? = when (member) { - is PsiMethod -> convertMethod(member, membersToRemove, constructorConverter) - is PsiField -> convertField(member) - is PsiClass -> convertClass(member) - is PsiClassInitializer -> convertInitializer(member) - else -> throw IllegalArgumentException("Unknown member: $member") - } - fun convertAnnotations(owner: PsiModifierListOwner): Annotations = annotationConverter.convertAnnotations(owner) @@ -212,9 +203,7 @@ public class Converter private(val project: Project, val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes()) val name = psiClass.declarationIdentifier() - val constructorConverter = ConstructorConverter(psiClass, this) - var classBody = ClassBodyConverter(psiClass, this, constructorConverter).convertBody() - classBody = constructorConverter.postProcessConstructors(classBody) + var classBody = ClassBodyConverter(psiClass, this).convertBody() return when { psiClass.isInterface() -> Trait(name, annotations, modifiers, typeParameters, extendsTypes, listOf(), implementsTypes, classBody) @@ -230,7 +219,7 @@ public class Converter private(val project: Project, modifiers = modifiers.with(Modifier.INNER) } - Class(name, annotations, modifiers, typeParameters, extendsTypes, constructorConverter.baseClassParams, implementsTypes, classBody) + Class(name, annotations, modifiers, typeParameters, extendsTypes, classBody.baseClassParams, implementsTypes, classBody) } }.assignPrototype(psiClass) } @@ -259,8 +248,8 @@ public class Converter private(val project: Project, val constructorSignature = PrimaryConstructorSignature(Annotations.Empty, Modifiers.Empty, parameterList).assignNoPrototype() // to convert fields and nested types - they are not allowed in Kotlin but we convert them and let user refactor code - var classBody = ClassBodyConverter(psiClass, this, null).convertBody() - classBody = ClassBody(constructorSignature, classBody.members, classBody.classObjectMembers, listOf(), classBody.lBrace, classBody.rBrace) + var classBody = ClassBodyConverter(psiClass, this).convertBody() + classBody = ClassBody(constructorSignature, classBody.baseClassParams, classBody.members, classBody.classObjectMembers, listOf(), classBody.lBrace, classBody.rBrace) val annotationAnnotation = Annotation(Identifier("annotation").assignNoPrototype(), listOf(), false, false).assignNoPrototype() return Class(psiClass.declarationIdentifier(), @@ -273,14 +262,19 @@ public class Converter private(val project: Project, classBody).assignPrototype(psiClass) } - private fun convertInitializer(initializer: PsiClassInitializer): Initializer { + fun convertInitializer(initializer: PsiClassInitializer): Initializer { return Initializer(convertBlock(initializer.getBody()), convertModifiers(initializer)).assignPrototype(initializer) } - private fun convertField(field: PsiField): Member { + fun convertField(field: PsiField, correction: FieldCorrectionInfo?): Member { val annotations = annotationConverter.convertAnnotations(field) - val modifiers = convertModifiers(field) - val name = field.declarationIdentifier() + + var modifiers = convertModifiers(field) + if (correction != null) { + modifiers = modifiers.without(modifiers.accessModifier()).with(correction.access) + } + + val name = correction?.name ?: field.declarationIdentifier() val converted = if (field is PsiEnumConstant) { val argumentList = field.getArgumentList() EnumConstant(name, @@ -302,7 +296,8 @@ public class Converter private(val project: Project, initializer, isVal, typeToDeclare != null, - initializer.isEmpty && shouldGenerateDefaultInitializer(referenceSearcher, field)) + initializer.isEmpty && shouldGenerateDefaultInitializer(referenceSearcher, field), + if (correction != null) correction.setterAccess else modifiers.accessModifier()) } return converted.assignPrototype(field) } @@ -324,7 +319,7 @@ public class Converter private(val project: Project, return if (convertedType == initializerType) null else convertedType } - private fun convertMethod(method: PsiMethod, membersToRemove: MutableSet?, constructorConverter: ConstructorConverter?): Member? { + fun convertMethod(method: PsiMethod, membersToRemove: MutableSet?, constructorConverter: ConstructorConverter?): Member? { return withMethodReturnType(method.getReturnType()).doConvertMethod(method, membersToRemove, constructorConverter)?.assignPrototype(method) } @@ -438,9 +433,7 @@ public class Converter private(val project: Project, fun convertExpression(expression: PsiExpression?): Expression { if (expression == null) return Expression.Empty - expressionVisitor.reset() - expression.accept(expressionVisitor) - return expressionVisitor.result.assignPrototype(expression) + return state.expressionConverter.convertExpression(expression, this).assignPrototype(expression) } fun convertLocalVariable(variable: PsiLocalVariable): LocalVariable { diff --git a/j2k/src/org/jetbrains/jet/j2k/Utils.kt b/j2k/src/org/jetbrains/jet/j2k/Utils.kt index a1c93facc19..9ccee917190 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Utils.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Utils.kt @@ -61,7 +61,7 @@ fun isVal(searcher: ReferenceSearcher, field: PsiField): Boolean { val parent = write.getParent() if (parent is PsiAssignmentExpression && parent.getOperationSign().getTokenType() == JavaTokenType.EQ && - isQualifierEmptyOrThis(write)) { + write.isQualifierEmptyOrThis()) { val constructor = write.getContainingConstructor() return constructor != null && constructor.getContainingClass() == containingClass && @@ -74,8 +74,8 @@ fun isVal(searcher: ReferenceSearcher, field: PsiField): Boolean { fun shouldGenerateDefaultInitializer(searcher: ReferenceSearcher, field: PsiField) = field.getInitializer() == null && !(isVal(searcher, field) && field.hasWriteAccesses(searcher, field.getContainingClass())) -fun isQualifierEmptyOrThis(ref: PsiReferenceExpression): Boolean { - val qualifier = ref.getQualifierExpression() +fun PsiReferenceExpression.isQualifierEmptyOrThis(): Boolean { + val qualifier = getQualifierExpression() return qualifier == null || (qualifier is PsiThisExpression && qualifier.getQualifier() == null) } @@ -93,6 +93,7 @@ fun PsiElement.isInSingleLine(): Boolean { return true } +//TODO: check for variables that are definitely assigned in constructors fun PsiElement.getContainingMethod(): PsiMethod? { var context = getContext() while (context != null) { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ClassBody.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ClassBody.kt index d91763afbf5..d2ce78f18fa 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ClassBody.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ClassBody.kt @@ -20,9 +20,9 @@ import org.jetbrains.jet.j2k.* abstract class Member(val annotations: Annotations, val modifiers: Modifiers) : Element() -//TODO: should be Element? class ClassBody ( val primaryConstructorSignature: PrimaryConstructorSignature?, + val baseClassParams: List, val members: List, val classObjectMembers: List, val factoryFunctions: List, diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt index 901ae295fff..7ea324efc6e 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt @@ -26,7 +26,8 @@ class Field( val initializer: Element, val isVal: Boolean, val explicitType: Boolean, - private val defaultInitializer: Boolean + private val defaultInitializer: Boolean, + val setterAccess: Modifier? ) : Member(annotations, modifiers) { override fun generateCode(builder: CodeBuilder) { @@ -46,5 +47,13 @@ class Field( if (!initializerToUse.isEmpty) { builder append " = " append initializerToUse } + + if (!isVal && setterAccess != modifiers.accessModifier()) { + builder.append("\n") + if (setterAccess != null) { + builder.appendWithSpaceAfter(Modifiers(listOf(setterAccess)).assignNoPrototype()) + } + builder.append("set") + } } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt index ff3244e7e39..27f6d277ddf 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt @@ -43,7 +43,8 @@ class Modifiers(val modifiers: Collection) : Element() { fun with(modifier: Modifier?): Modifiers = if (modifier != null) Modifiers(modifiers + listOf(modifier)).assignPrototypesFrom(this) else this - fun without(modifier: Modifier): Modifiers { + fun without(modifier: Modifier?): Modifiers { + if (modifier == null) return this val set = HashSet(modifiers) set.remove(modifier) return Modifiers(set).assignPrototypesFrom(this) diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt index 2d45ab76de6..b8ef5e83522 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt @@ -38,14 +38,25 @@ import org.jetbrains.jet.lang.resolve.name.FqName import org.jetbrains.jet.asJava.KotlinLightField import org.jetbrains.jet.lang.psi.JetObjectDeclaration -open class ExpressionVisitor(private val converter: Converter) : JavaElementVisitor() { - private val typeConverter = converter.typeConverter +trait ExpressionConverter { + fun convertExpression(expression: PsiExpression, converter: Converter): Expression +} - public var result: Expression = Expression.Empty - protected set +class ExpressionVisitor : JavaElementVisitor(), ExpressionConverter { + private var _converter: Converter? = null + private var result: Expression = Expression.Empty - public fun reset() { + private val converter: Converter get() { + return _converter!! + } + private val typeConverter: TypeConverter get() = converter.typeConverter + + override fun convertExpression(expression: PsiExpression, converter: Converter): Expression { + this._converter = converter result = Expression.Empty + + expression.accept(this) + return result } override fun visitArrayAccessExpression(expression: PsiArrayAccessExpression) { diff --git a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java index 03e0805b05d..f8ea3d63b20 100644 --- a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java +++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java @@ -17,10 +17,13 @@ package org.jetbrains.jet.j2k.test; import com.intellij.testFramework.TestDataPath; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.junit.runner.RunWith; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import org.junit.runner.RunWith; +import org.jetbrains.jet.JUnit3RunnerWithInners; import java.io.File; import java.util.regex.Pattern; @@ -29,7 +32,7 @@ import java.util.regex.Pattern; @SuppressWarnings("all") @TestMetadata("j2k/tests/testData/ast") @TestDataPath("$PROJECT_ROOT") -@InnerTestClasses({JavaToKotlinConverterTestGenerated.Annotations.class, JavaToKotlinConverterTestGenerated.AnonymousBlock.class, JavaToKotlinConverterTestGenerated.ArrayAccessExpression.class, JavaToKotlinConverterTestGenerated.ArrayInitializerExpression.class, JavaToKotlinConverterTestGenerated.ArrayType.class, JavaToKotlinConverterTestGenerated.AssertStatement.class, JavaToKotlinConverterTestGenerated.AssignmentExpression.class, JavaToKotlinConverterTestGenerated.BinaryExpression.class, JavaToKotlinConverterTestGenerated.Blocks.class, JavaToKotlinConverterTestGenerated.BoxedType.class, JavaToKotlinConverterTestGenerated.BreakStatement.class, JavaToKotlinConverterTestGenerated.CallChainExpression.class, JavaToKotlinConverterTestGenerated.Class.class, JavaToKotlinConverterTestGenerated.ClassExpression.class, JavaToKotlinConverterTestGenerated.Comments.class, JavaToKotlinConverterTestGenerated.ConditionalExpression.class, JavaToKotlinConverterTestGenerated.Constructors.class, JavaToKotlinConverterTestGenerated.ContinueStatement.class, JavaToKotlinConverterTestGenerated.DeclarationStatement.class, JavaToKotlinConverterTestGenerated.DoWhileStatement.class, JavaToKotlinConverterTestGenerated.Enum.class, JavaToKotlinConverterTestGenerated.Equals.class, JavaToKotlinConverterTestGenerated.Field.class, JavaToKotlinConverterTestGenerated.For.class, JavaToKotlinConverterTestGenerated.ForeachStatement.class, JavaToKotlinConverterTestGenerated.Formatting.class, JavaToKotlinConverterTestGenerated.Function.class, JavaToKotlinConverterTestGenerated.Identifier.class, JavaToKotlinConverterTestGenerated.IfStatement.class, JavaToKotlinConverterTestGenerated.ImportStatement.class, JavaToKotlinConverterTestGenerated.InProjectionType.class, JavaToKotlinConverterTestGenerated.Inheritance.class, JavaToKotlinConverterTestGenerated.IsOperator.class, JavaToKotlinConverterTestGenerated.Issues.class, JavaToKotlinConverterTestGenerated.KotlinApiAccess.class, JavaToKotlinConverterTestGenerated.LabelStatement.class, JavaToKotlinConverterTestGenerated.List.class, JavaToKotlinConverterTestGenerated.LiteralExpression.class, JavaToKotlinConverterTestGenerated.LocalVariable.class, JavaToKotlinConverterTestGenerated.MethodCallExpression.class, JavaToKotlinConverterTestGenerated.Misc.class, JavaToKotlinConverterTestGenerated.NewClassExpression.class, JavaToKotlinConverterTestGenerated.Nullability.class, JavaToKotlinConverterTestGenerated.ObjectLiteral.class, JavaToKotlinConverterTestGenerated.OutProjectionType.class, JavaToKotlinConverterTestGenerated.PackageStatement.class, JavaToKotlinConverterTestGenerated.ParenthesizedExpression.class, JavaToKotlinConverterTestGenerated.PolyadicExpression.class, JavaToKotlinConverterTestGenerated.PostfixOperator.class, JavaToKotlinConverterTestGenerated.PrefixOperator.class, JavaToKotlinConverterTestGenerated.RawGenerics.class, JavaToKotlinConverterTestGenerated.ReturnStatement.class, JavaToKotlinConverterTestGenerated.Settings.class, JavaToKotlinConverterTestGenerated.StarProjectionType.class, JavaToKotlinConverterTestGenerated.StaticMembers.class, JavaToKotlinConverterTestGenerated.SuperExpression.class, JavaToKotlinConverterTestGenerated.Switch.class, JavaToKotlinConverterTestGenerated.SynchronizedStatement.class, JavaToKotlinConverterTestGenerated.ThisExpression.class, JavaToKotlinConverterTestGenerated.ThrowStatement.class, JavaToKotlinConverterTestGenerated.ToKotlinClasses.class, JavaToKotlinConverterTestGenerated.Trait.class, JavaToKotlinConverterTestGenerated.TryStatement.class, JavaToKotlinConverterTestGenerated.TryWithResource.class, JavaToKotlinConverterTestGenerated.TypeCastExpression.class, JavaToKotlinConverterTestGenerated.TypeParameters.class, JavaToKotlinConverterTestGenerated.VarArg.class, JavaToKotlinConverterTestGenerated.WhileStatement.class}) +@InnerTestClasses({JavaToKotlinConverterTestGenerated.Annotations.class, JavaToKotlinConverterTestGenerated.AnonymousBlock.class, JavaToKotlinConverterTestGenerated.ArrayAccessExpression.class, JavaToKotlinConverterTestGenerated.ArrayInitializerExpression.class, JavaToKotlinConverterTestGenerated.ArrayType.class, JavaToKotlinConverterTestGenerated.AssertStatement.class, JavaToKotlinConverterTestGenerated.AssignmentExpression.class, JavaToKotlinConverterTestGenerated.BinaryExpression.class, JavaToKotlinConverterTestGenerated.Blocks.class, JavaToKotlinConverterTestGenerated.BoxedType.class, JavaToKotlinConverterTestGenerated.BreakStatement.class, JavaToKotlinConverterTestGenerated.CallChainExpression.class, JavaToKotlinConverterTestGenerated.Class.class, JavaToKotlinConverterTestGenerated.ClassExpression.class, JavaToKotlinConverterTestGenerated.Comments.class, JavaToKotlinConverterTestGenerated.ConditionalExpression.class, JavaToKotlinConverterTestGenerated.Constructors.class, JavaToKotlinConverterTestGenerated.ContinueStatement.class, JavaToKotlinConverterTestGenerated.DeclarationStatement.class, JavaToKotlinConverterTestGenerated.DoWhileStatement.class, JavaToKotlinConverterTestGenerated.DropAccessors.class, JavaToKotlinConverterTestGenerated.Enum.class, JavaToKotlinConverterTestGenerated.Equals.class, JavaToKotlinConverterTestGenerated.Field.class, JavaToKotlinConverterTestGenerated.For.class, JavaToKotlinConverterTestGenerated.ForeachStatement.class, JavaToKotlinConverterTestGenerated.Formatting.class, JavaToKotlinConverterTestGenerated.Function.class, JavaToKotlinConverterTestGenerated.Identifier.class, JavaToKotlinConverterTestGenerated.IfStatement.class, JavaToKotlinConverterTestGenerated.ImportStatement.class, JavaToKotlinConverterTestGenerated.InProjectionType.class, JavaToKotlinConverterTestGenerated.Inheritance.class, JavaToKotlinConverterTestGenerated.IsOperator.class, JavaToKotlinConverterTestGenerated.Issues.class, JavaToKotlinConverterTestGenerated.KotlinApiAccess.class, JavaToKotlinConverterTestGenerated.LabelStatement.class, JavaToKotlinConverterTestGenerated.List.class, JavaToKotlinConverterTestGenerated.LiteralExpression.class, JavaToKotlinConverterTestGenerated.LocalVariable.class, JavaToKotlinConverterTestGenerated.MethodCallExpression.class, JavaToKotlinConverterTestGenerated.Misc.class, JavaToKotlinConverterTestGenerated.NewClassExpression.class, JavaToKotlinConverterTestGenerated.Nullability.class, JavaToKotlinConverterTestGenerated.ObjectLiteral.class, JavaToKotlinConverterTestGenerated.OutProjectionType.class, JavaToKotlinConverterTestGenerated.PackageStatement.class, JavaToKotlinConverterTestGenerated.ParenthesizedExpression.class, JavaToKotlinConverterTestGenerated.PolyadicExpression.class, JavaToKotlinConverterTestGenerated.PostfixOperator.class, JavaToKotlinConverterTestGenerated.PrefixOperator.class, JavaToKotlinConverterTestGenerated.RawGenerics.class, JavaToKotlinConverterTestGenerated.ReturnStatement.class, JavaToKotlinConverterTestGenerated.Settings.class, JavaToKotlinConverterTestGenerated.StarProjectionType.class, JavaToKotlinConverterTestGenerated.StaticMembers.class, JavaToKotlinConverterTestGenerated.SuperExpression.class, JavaToKotlinConverterTestGenerated.Switch.class, JavaToKotlinConverterTestGenerated.SynchronizedStatement.class, JavaToKotlinConverterTestGenerated.ThisExpression.class, JavaToKotlinConverterTestGenerated.ThrowStatement.class, JavaToKotlinConverterTestGenerated.ToKotlinClasses.class, JavaToKotlinConverterTestGenerated.Trait.class, JavaToKotlinConverterTestGenerated.TryStatement.class, JavaToKotlinConverterTestGenerated.TryWithResource.class, JavaToKotlinConverterTestGenerated.TypeCastExpression.class, JavaToKotlinConverterTestGenerated.TypeParameters.class, JavaToKotlinConverterTestGenerated.VarArg.class, JavaToKotlinConverterTestGenerated.WhileStatement.class}) @RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConverterTest { public void testAllFilesPresentInAst() throws Exception { @@ -1310,6 +1313,88 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv } + @TestMetadata("j2k/tests/testData/ast/dropAccessors") + @TestDataPath("$PROJECT_ROOT") + @RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) + public static class DropAccessors extends AbstractJavaToKotlinConverterTest { + @TestMetadata("AccessInGetterWithThis.java") + public void testAccessInGetterWithThis() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.java"); + doTest(fileName); + } + + public void testAllFilesPresentInDropAccessors() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("j2k/tests/testData/ast/dropAccessors"), Pattern.compile("^(.+)\\.java$"), true); + } + + @TestMetadata("CannotDropOnlySetter.java") + public void testCannotDropOnlySetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.java"); + doTest(fileName); + } + + @TestMetadata("DataClass.java") + public void testDataClass() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/DataClass.java"); + doTest(fileName); + } + + @TestMetadata("DataClassWithMutableField.java") + public void testDataClassWithMutableField() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.java"); + doTest(fileName); + } + + @TestMetadata("DifferentFieldName.java") + public void testDifferentFieldName() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/DifferentFieldName.java"); + doTest(fileName); + } + + @TestMetadata("DropGetter.java") + public void testDropGetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/DropGetter.java"); + doTest(fileName); + } + + @TestMetadata("DropGetterAndSetter.java") + public void testDropGetterAndSetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.java"); + doTest(fileName); + } + + @TestMetadata("DropGetterForMutable.java") + public void testDropGetterForMutable() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.java"); + doTest(fileName); + } + + @TestMetadata("FalseGetter.java") + public void testFalseGetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/FalseGetter.java"); + doTest(fileName); + } + + @TestMetadata("FalseSetter.java") + public void testFalseSetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/FalseSetter.java"); + doTest(fileName); + } + + @TestMetadata("FieldUsagesInFactoryMethods.java") + public void testFieldUsagesInFactoryMethods() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.java"); + doTest(fileName); + } + + @TestMetadata("GetterAndSetterNamesDifferent.java") + public void testGetterAndSetterNamesDifferent() throws Exception { + String fileName = JetTestUtils.navigationMetadata("j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.java"); + doTest(fileName); + } + + } + @TestMetadata("j2k/tests/testData/ast/enum") @TestDataPath("$PROJECT_ROOT") @RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class) diff --git a/j2k/tests/testData/ast/class/abstractClassShape.kt b/j2k/tests/testData/ast/class/abstractClassShape.kt index 2b5e09efc31..d262fa91d72 100644 --- a/j2k/tests/testData/ast/class/abstractClassShape.kt +++ b/j2k/tests/testData/ast/class/abstractClassShape.kt @@ -1,12 +1,4 @@ abstract class Shape { public var color: String - public fun setColor(c: String) { - color = c - } - - public fun getColor(): String { - return color - } - public abstract fun area(): Double } \ No newline at end of file diff --git a/j2k/tests/testData/ast/constructors/customerBuilder.kt b/j2k/tests/testData/ast/constructors/customerBuilder.kt index df6785bdfbb..397a0871404 100644 --- a/j2k/tests/testData/ast/constructors/customerBuilder.kt +++ b/j2k/tests/testData/ast/constructors/customerBuilder.kt @@ -1,20 +1,12 @@ package org.test.customer -class Customer(public val _firstName: String, public val _lastName: String) { +class Customer(public val firstName: String, public val lastName: String) { { doSmthBefore() doSmthAfter() } - public fun getFirstName(): String { - return _firstName - } - - public fun getLastName(): String { - return _lastName - } - private fun doSmthBefore() { } diff --git a/j2k/tests/testData/ast/constructors/genericIdentifier.kt b/j2k/tests/testData/ast/constructors/genericIdentifier.kt index 6213f71e780..7b0132372d9 100644 --- a/j2k/tests/testData/ast/constructors/genericIdentifier.kt +++ b/j2k/tests/testData/ast/constructors/genericIdentifier.kt @@ -14,12 +14,8 @@ public fun Identifier(name: T, hasDollar: Boolean, isNullable: Boolean): Ide return __ } -public class Identifier(private val myName: T, private val myHasDollar: Boolean) { +public class Identifier(public val name: T, private val myHasDollar: Boolean) { private var myNullable = true - - public fun getName(): T { - return myName - } } public class User { diff --git a/j2k/tests/testData/ast/constructors/identifier.kt b/j2k/tests/testData/ast/constructors/identifier.kt index ec47a181791..7751d231896 100644 --- a/j2k/tests/testData/ast/constructors/identifier.kt +++ b/j2k/tests/testData/ast/constructors/identifier.kt @@ -14,12 +14,8 @@ public fun Identifier(name: String, hasDollar: Boolean, isNullable: Boolean): Id return __ } -public class Identifier(private val myName: String, private val myHasDollar: Boolean) { +public class Identifier(public val name: String, private val myHasDollar: Boolean) { private var myNullable = true - - public fun getName(): String { - return myName - } } public class User { diff --git a/j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.java b/j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.java new file mode 100644 index 00000000000..aab1d24e649 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.java @@ -0,0 +1,7 @@ +public class AAA { + private final int x = 42; + + public int getX() { + return this.x; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.kt b/j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.kt new file mode 100644 index 00000000000..aa2614ee957 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/AccessInGetterWithThis.kt @@ -0,0 +1,3 @@ +public class AAA { + public val x: Int = 42 +} diff --git a/j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.java b/j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.java new file mode 100644 index 00000000000..4229549b735 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.java @@ -0,0 +1,7 @@ +public class AAA { + private int x = 42; + + public void setX(int x) { + this.x = x; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.kt b/j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.kt new file mode 100644 index 00000000000..99073d68531 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/CannotDropOnlySetter.kt @@ -0,0 +1,7 @@ +public class AAA { + private var x = 42 + + public fun setX(x: Int) { + this.x = x + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DataClass.java b/j2k/tests/testData/ast/dropAccessors/DataClass.java new file mode 100644 index 00000000000..fe49677a6cf --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DataClass.java @@ -0,0 +1,28 @@ +public class Test { + private String id; + private String name; + private int myAge; + + public Test(String id, String name, int anAge) { + this.id = id; + this.name = name; + myAge = anAge; + System.out.println(anAge); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public int getAge() { + return myAge; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DataClass.kt b/j2k/tests/testData/ast/dropAccessors/DataClass.kt new file mode 100644 index 00000000000..e0065bd2328 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DataClass.kt @@ -0,0 +1,6 @@ +public class Test(public var id: String?, public val name: String, public val age: Int) { + + { + System.out.println(age) + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.java b/j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.java new file mode 100644 index 00000000000..e215e8e735f --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.java @@ -0,0 +1,15 @@ +public class Test { + private int myCount; + + public Test(int count) { + myCount = count; + } + + public int getCount() { + return myCount; + } + + public void inc() { + myCount++; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.kt b/j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.kt new file mode 100644 index 00000000000..de84f032ed6 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DataClassWithMutableField.kt @@ -0,0 +1,12 @@ +public class Test(count: Int) { + public var count: Int = 0 + private set + + { + this.count = count + } + + public fun inc() { + count++ + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DifferentFieldName.java b/j2k/tests/testData/ast/dropAccessors/DifferentFieldName.java new file mode 100644 index 00000000000..f986c1f5e83 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DifferentFieldName.java @@ -0,0 +1,13 @@ +public class AAA { + private int myX = 42; + + public int getX() { + return myX; + } + + public void foo(AAA other) { + System.out.println(myX); + System.out.println(other.myX); + myX = 10; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DifferentFieldName.kt b/j2k/tests/testData/ast/dropAccessors/DifferentFieldName.kt new file mode 100644 index 00000000000..1dd682bc711 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DifferentFieldName.kt @@ -0,0 +1,10 @@ +public class AAA { + public var x: Int = 42 + private set + + public fun foo(other: AAA) { + System.out.println(x) + System.out.println(other.x) + x = 10 + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DropGetter.java b/j2k/tests/testData/ast/dropAccessors/DropGetter.java new file mode 100644 index 00000000000..a8d09e23780 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DropGetter.java @@ -0,0 +1,7 @@ +public class AAA { + private final int x = 42; + + public int getX() { + return x; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DropGetter.kt b/j2k/tests/testData/ast/dropAccessors/DropGetter.kt new file mode 100644 index 00000000000..aa2614ee957 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DropGetter.kt @@ -0,0 +1,3 @@ +public class AAA { + public val x: Int = 42 +} diff --git a/j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.java b/j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.java new file mode 100644 index 00000000000..3b68f2b9d56 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.java @@ -0,0 +1,11 @@ +public class AAA { + private int x = 42; + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.kt b/j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.kt new file mode 100644 index 00000000000..0074fc2d309 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DropGetterAndSetter.kt @@ -0,0 +1,3 @@ +public class AAA { + public var x: Int = 42 +} diff --git a/j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.java b/j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.java new file mode 100644 index 00000000000..6657f708da9 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.java @@ -0,0 +1,11 @@ +public class AAA { + private int x = 42; + + public int getX() { + return x; + } + + public void foo() { + x = 10; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.kt b/j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.kt new file mode 100644 index 00000000000..4c1a7d6a7eb --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/DropGetterForMutable.kt @@ -0,0 +1,8 @@ +public class AAA { + public var x: Int = 42 + private set + + public fun foo() { + x = 10 + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/FalseGetter.java b/j2k/tests/testData/ast/dropAccessors/FalseGetter.java new file mode 100644 index 00000000000..5b6024908b9 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/FalseGetter.java @@ -0,0 +1,8 @@ +public class AAA { + private int x = 42; + private AAA other = new AAA(); + + public int getX() { + return other.x; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/FalseGetter.kt b/j2k/tests/testData/ast/dropAccessors/FalseGetter.kt new file mode 100644 index 00000000000..ffab977787b --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/FalseGetter.kt @@ -0,0 +1,8 @@ +public class AAA { + private val x = 42 + private val other = AAA() + + public fun getX(): Int { + return other.x + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/FalseSetter.java b/j2k/tests/testData/ast/dropAccessors/FalseSetter.java new file mode 100644 index 00000000000..7c10fdb38f1 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/FalseSetter.java @@ -0,0 +1,11 @@ +public class AAA { + private int x = 42; + + public int getX() { + return x; + } + + public void setX(int x) { + this.x += x; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/FalseSetter.kt b/j2k/tests/testData/ast/dropAccessors/FalseSetter.kt new file mode 100644 index 00000000000..55c8bd57c68 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/FalseSetter.kt @@ -0,0 +1,8 @@ +public class AAA { + public var x: Int = 42 + private set + + public fun setX(x: Int) { + this.x += x + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.java b/j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.java new file mode 100644 index 00000000000..d06d660e129 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.java @@ -0,0 +1,35 @@ +class C { + final int myArg1; + int myArg2; + int myArg3; + + C(int arg1, int arg2, int arg3) { + this(arg1); + myArg2 = arg2; + myArg3 = arg3; + } + + C(int arg1, int arg2) { + this(arg1); + myArg2 = arg2; + myArg3 = 0; + } + + C(int arg1) { + myArg1 = arg1; + myArg2 = 0; + myArg3 = 0; + } + + int getArg1() { + return myArg1; + } + + int getArg2() { + return myArg2; + } + + int getArg3() { + return myArg3; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.kt b/j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.kt new file mode 100644 index 00000000000..01b45fb9412 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/FieldUsagesInFactoryMethods.kt @@ -0,0 +1,23 @@ +fun C(arg1: Int, arg2: Int, arg3: Int): C { + val __ = C(arg1) + __.arg2 = arg2 + __.arg3 = arg3 + return __ +} + +fun C(arg1: Int, arg2: Int): C { + val __ = C(arg1) + __.arg2 = arg2 + __.arg3 = 0 + return __ +} + +class C(val arg1: Int) { + var arg2: Int = 0 + var arg3: Int = 0 + + { + arg2 = 0 + arg3 = 0 + } +} \ No newline at end of file diff --git a/j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.java b/j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.java new file mode 100644 index 00000000000..e896854cbe6 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.java @@ -0,0 +1,11 @@ +public class AAA { + private int x = 42; + + public int getX() { + return x; + } + + public void setY(int x) { + this.x = x; + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.kt b/j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.kt new file mode 100644 index 00000000000..27688bd3314 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/GetterAndSetterNamesDifferent.kt @@ -0,0 +1,8 @@ +public class AAA { + public var x: Int = 42 + private set + + public fun setY(x: Int) { + this.x = x + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.java.todo b/j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.java.todo new file mode 100644 index 00000000000..d196f6614c5 --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.java.todo @@ -0,0 +1,19 @@ +public class AAA { + private int x = 42; + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public void foo() { + setX(getX() + 1); + } + + public void bar(AAA other) { + other.setX(other.getX() + 1); + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.kt b/j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.kt new file mode 100644 index 00000000000..87cd25fd2ca --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/GetterSetterUsages.kt @@ -0,0 +1,11 @@ +public class AAA { + public var x: Int = 42 + + public fun foo() { + x = x + 1 + } + + public fun bar(other: AAA) { + other.x = other.x + 1 + } +} diff --git a/j2k/tests/testData/ast/dropAccessors/QualifyFieldUsagesOnRename.java.todo b/j2k/tests/testData/ast/dropAccessors/QualifyFieldUsagesOnRename.java.todo new file mode 100644 index 00000000000..7dd2f85fa3f --- /dev/null +++ b/j2k/tests/testData/ast/dropAccessors/QualifyFieldUsagesOnRename.java.todo @@ -0,0 +1,32 @@ +public class AAA { + private int myX = 42; + + public int getX() { + return myX; + } + + public void foo(final int x) { + System.out.println(x); + System.out.println(getX()); + System.out.println(myX); + + Runnable runnable = new Runnable() { + @Override + public void run() { + System.out.println(x); + System.out.println(getX()); + System.out.println(myX); + } + }; + } + + class Nested { + int x = myX; + + void foo() { + System.out.println(x); + System.out.println(getX()); + System.out.println(myX); + } + } +} diff --git a/j2k/tests/testData/ast/enum/colorEnum.kt b/j2k/tests/testData/ast/enum/colorEnum.kt index a96ba5955a8..00dfc632fc1 100644 --- a/j2k/tests/testData/ast/enum/colorEnum.kt +++ b/j2k/tests/testData/ast/enum/colorEnum.kt @@ -1,10 +1,6 @@ package demo -enum class MyEnum private(private val color: Int) { +enum class MyEnum private(public val color: Int) { RED : MyEnum(10) BLUE : MyEnum(20) - - public fun getColor(): Int { - return color - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.kt b/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.kt index 83a774702ba..d57aa80dad1 100644 --- a/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.kt +++ b/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.kt @@ -1,11 +1,7 @@ -enum class Color private(private val code: Int) { +enum class Color private(public val code: Int) { WHITE : Color(21) BLACK : Color(22) RED : Color(23) YELLOW : Color(24) BLUE : Color(25) - - public fun getCode(): Int { - return code - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/enum/primaryPrivateConstructor.kt b/j2k/tests/testData/ast/enum/primaryPrivateConstructor.kt index 838467a0bff..59d0da30bdb 100644 --- a/j2k/tests/testData/ast/enum/primaryPrivateConstructor.kt +++ b/j2k/tests/testData/ast/enum/primaryPrivateConstructor.kt @@ -1,8 +1,3 @@ package demo -enum class Color private(private val code: Int) { - - public fun getCode(): Int { - return code - } -} \ No newline at end of file +enum class Color private(public val code: Int) \ No newline at end of file diff --git a/j2k/tests/testData/ast/issues/kt-638.kt b/j2k/tests/testData/ast/issues/kt-638.kt index 7d46a242a2f..611179a6135 100644 --- a/j2k/tests/testData/ast/issues/kt-638.kt +++ b/j2k/tests/testData/ast/issues/kt-638.kt @@ -14,12 +14,8 @@ public fun Identifier(name: T, hasDollar: Boolean, isNullable: Boolean): Ide return __ } -public class Identifier(private val myName: T, private val myHasDollar: Boolean) { +public class Identifier(public val name: T, private val myHasDollar: Boolean) { private var myNullable = true - - public fun getName(): T { - return myName - } } public class User {