KT-5492 J2K: convert field with getter/setter to property

#KT-5492 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-10-14 17:33:20 +04:00
parent 129c592581
commit a84b32af98
45 changed files with 691 additions and 139 deletions
@@ -0,0 +1,5 @@
<root>
<item name='com.intellij.openapi.util.text.StringUtil java.lang.String decapitalize(java.lang.String)'>
<annotation name='org.jetbrains.annotations.NotNull'/>
</item>
</root>
@@ -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<PsiMember>()
private val fieldCorrections = HashMap<PsiField, FieldCorrectionInfo>()
public fun convertBody(): ClassBody {
val membersToRemove = HashSet<PsiMember>()
processAccessorsToDrop()
val correctedConverter = buildConverterWithCorrectedFieldNames()
val constructorConverter = if (psiClass.getName() != null)
ConstructorConverter(psiClass, correctedConverter, fieldCorrections)
else
null
val convertedMembers = LinkedHashMap<PsiMember, Member>()
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<PsiMember>,
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<PsiField, AccessorInfo>()
val fieldToSetterInfo = HashMap<PsiField, AccessorInfo>()
val fieldsWithConflict = HashSet<PsiField>()
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
}
}
}
}
}
}
@@ -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<PsiField, FieldCorrectionInfo>) {
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 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 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<FactoryFunction>): List<FactoryFunction> {
@@ -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<String, String>, 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<String, String>,
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)
}
}
}
+28 -35
View File
@@ -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<String> = state.importList?.imports?.mapTo(HashSet<String>()) { it.name } ?: setOf()
val importsToAdd: MutableCollection<String>? = 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<String>): 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<PsiMember>, 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<PsiMember>?, constructorConverter: ConstructorConverter?): Member? {
fun convertMethod(method: PsiMethod, membersToRemove: MutableSet<PsiMember>?, 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 {
+4 -3
View File
@@ -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) {
@@ -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<Expression>,
val members: List<Member>,
val classObjectMembers: List<Member>,
val factoryFunctions: List<FactoryFunction>,
+10 -1
View File
@@ -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")
}
}
}
@@ -43,7 +43,8 @@ class Modifiers(val modifiers: Collection<Modifier>) : 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)
@@ -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) {
@@ -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)
@@ -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
}
@@ -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() {
}
@@ -14,12 +14,8 @@ public fun <T> Identifier(name: T, hasDollar: Boolean, isNullable: Boolean): Ide
return __
}
public class Identifier<T>(private val myName: T, private val myHasDollar: Boolean) {
public class Identifier<T>(public val name: T, private val myHasDollar: Boolean) {
private var myNullable = true
public fun getName(): T {
return myName
}
}
public class User {
@@ -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 {
@@ -0,0 +1,7 @@
public class AAA {
private final int x = 42;
public int getX() {
return this.x;
}
}
@@ -0,0 +1,3 @@
public class AAA {
public val x: Int = 42
}
@@ -0,0 +1,7 @@
public class AAA {
private int x = 42;
public void setX(int x) {
this.x = x;
}
}
@@ -0,0 +1,7 @@
public class AAA {
private var x = 42
public fun setX(x: Int) {
this.x = x
}
}
@@ -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;
}
}
@@ -0,0 +1,6 @@
public class Test(public var id: String?, public val name: String, public val age: Int) {
{
System.out.println(age)
}
}
@@ -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++;
}
}
@@ -0,0 +1,12 @@
public class Test(count: Int) {
public var count: Int = 0
private set
{
this.count = count
}
public fun inc() {
count++
}
}
@@ -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;
}
}
@@ -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
}
}
@@ -0,0 +1,7 @@
public class AAA {
private final int x = 42;
public int getX() {
return x;
}
}
@@ -0,0 +1,3 @@
public class AAA {
public val x: Int = 42
}
@@ -0,0 +1,11 @@
public class AAA {
private int x = 42;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
@@ -0,0 +1,3 @@
public class AAA {
public var x: Int = 42
}
@@ -0,0 +1,11 @@
public class AAA {
private int x = 42;
public int getX() {
return x;
}
public void foo() {
x = 10;
}
}
@@ -0,0 +1,8 @@
public class AAA {
public var x: Int = 42
private set
public fun foo() {
x = 10
}
}
@@ -0,0 +1,8 @@
public class AAA {
private int x = 42;
private AAA other = new AAA();
public int getX() {
return other.x;
}
}
@@ -0,0 +1,8 @@
public class AAA {
private val x = 42
private val other = AAA()
public fun getX(): Int {
return other.x
}
}
@@ -0,0 +1,11 @@
public class AAA {
private int x = 42;
public int getX() {
return x;
}
public void setX(int x) {
this.x += x;
}
}
@@ -0,0 +1,8 @@
public class AAA {
public var x: Int = 42
private set
public fun setX(x: Int) {
this.x += x
}
}
@@ -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;
}
}
@@ -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
}
}
@@ -0,0 +1,11 @@
public class AAA {
private int x = 42;
public int getX() {
return x;
}
public void setY(int x) {
this.x = x;
}
}
@@ -0,0 +1,8 @@
public class AAA {
public var x: Int = 42
private set
public fun setY(x: Int) {
this.x = x
}
}
@@ -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);
}
}
@@ -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
}
}
@@ -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);
}
}
}
+1 -5
View File
@@ -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
}
}
@@ -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
}
}
@@ -1,8 +1,3 @@
package demo
enum class Color private(private val code: Int) {
public fun getCode(): Int {
return code
}
}
enum class Color private(public val code: Int)
+1 -5
View File
@@ -14,12 +14,8 @@ public fun <T> Identifier(name: T, hasDollar: Boolean, isNullable: Boolean): Ide
return __
}
public class Identifier<T>(private val myName: T, private val myHasDollar: Boolean) {
public class Identifier<T>(public val name: T, private val myHasDollar: Boolean) {
private var myNullable = true
public fun getName(): T {
return myName
}
}
public class User {