diff --git a/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt b/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt index c5750a0c9b2..b73edbd1d80 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ConstructorUtils.kt @@ -23,6 +23,14 @@ import com.intellij.psi.JavaRecursiveElementVisitor import java.util.LinkedHashSet import com.intellij.psi.PsiElement import com.intellij.psi.PsiMethodCallExpression +import com.intellij.psi.PsiParameter +import com.intellij.psi.PsiField +import com.intellij.psi.PsiAssignmentExpression +import com.intellij.psi.PsiThisExpression +import com.intellij.psi.PsiStatement +import com.intellij.psi.PsiExpressionStatement +import com.intellij.psi.PsiBlockStatement +import com.intellij.psi.util.PsiUtil fun PsiMethod.isPrimaryConstructor(): Boolean { if (!isConstructor()) return false @@ -63,11 +71,11 @@ fun PsiClass.getPrimaryConstructor(): PsiMethod? { } } -fun isInsidePrimaryConstructor(element: PsiElement): Boolean - = getContainingConstructor(element)?.isPrimaryConstructor() ?: false +fun PsiElement.isInsidePrimaryConstructor(): Boolean + = getContainingConstructor()?.isPrimaryConstructor() ?: false -fun getContainingConstructor(element: PsiElement): PsiMethod? { - var context = element.getContext() +fun PsiElement.getContainingConstructor(): PsiMethod? { + var context = getContext() while (context != null) { val _context = context!! if (_context is PsiMethod) { @@ -90,3 +98,4 @@ fun PsiMethodCallExpression.isSuperConstructorCall(): Boolean { fun PsiReferenceExpression.isThisConstructorCall(): Boolean = getReferences().filter { it.getCanonicalText() == "this" }.map { it.resolve() }.any { it is PsiMethod && it.isConstructor() } + diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt index 3b677afbf05..a6c2039c72f 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt @@ -18,14 +18,12 @@ package org.jetbrains.jet.j2k import com.intellij.psi.* import org.jetbrains.jet.j2k.ast.* -import org.jetbrains.jet.j2k.ast.types.ClassType -import org.jetbrains.jet.j2k.ast.types.EmptyType -import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.visitors.* import java.util.* import com.intellij.psi.CommonClassNames.* import org.jetbrains.jet.lang.types.expressions.OperatorConventions.* import com.intellij.openapi.project.Project +import com.intellij.psi.util.PsiUtil public class Converter(val project: Project, val settings: ConverterSettings) { @@ -54,7 +52,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { private fun convertTopElement(element: PsiElement?): Element? = when(element) { is PsiJavaFile -> convertFile(element) is PsiClass -> convertClass(element) - is PsiMethod -> convertMethod(element) + is PsiMethod -> convertMethod(element, HashSet()) is PsiField -> convertField(element) is PsiStatement -> convertStatement(element) is PsiExpression -> convertExpression(element) @@ -72,13 +70,29 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } public fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass { - return AnonymousClass(this, convertMembers(anonymousClass)) + return AnonymousClass(this, convertClassBody(anonymousClass)) } - private fun convertMembers(psiClass: PsiClass): List { - val allChildren = psiClass.getChildren().toList() - val lBraceIndex = allChildren.indexOf(psiClass.getLBrace()) - return allChildren.subList(lBraceIndex, allChildren.size).map { convertMember(it) }.filterNotNull() + private fun convertClassBody(psiClass: PsiClass): List { + val membersToRemove = HashSet() + val convertedMembers = LinkedHashMap() + var inBody = false + val lBrace = psiClass.getLBrace() + for (element in psiClass.getChildren()) { + if (element == lBrace) inBody = true + if (inBody) { + convertedMembers.put(element, convertMember(element, membersToRemove)) + } + } + return convertedMembers.keySet().filter { !membersToRemove.contains(it) }.map { convertedMembers[it]!! } + } + + private fun convertMember(element: PsiElement, membersToRemove: MutableSet): Element = when(element) { + is PsiMethod -> convertMethod(element, membersToRemove) + is PsiField -> convertField(element) + is PsiClass -> convertClass(element) + is PsiClassInitializer -> convertInitializer(element) + else -> convertElement(element) } private fun getComments(member: PsiMember): MemberComments { @@ -93,39 +107,31 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return MemberComments(whiteSpacesAndComments) } - private fun convertMember(e: PsiElement?): Element? = when(e) { - is PsiMethod -> convertMethod(e, true) - is PsiField -> convertField(e) - is PsiClass -> convertClass(e) - is PsiClassInitializer -> convertInitializer(e) - else -> convertElement(e) - } - private fun convertClass(psiClass: PsiClass): Class { val modifiers = convertModifierList(psiClass.getModifierList()) val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList()) val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes()) val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes()) val name = Identifier(psiClass.getName()!!) - val members = ArrayList(convertMembers(psiClass)) + val classBodyElements = ArrayList(convertClassBody(psiClass)) when { - psiClass.isInterface() -> return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, listOf(), implementsTypes, members) + psiClass.isInterface() -> return Trait(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, listOf(), implementsTypes, classBodyElements) - psiClass.isEnum() -> return Enum(this, name, getComments(psiClass), modifiers, typeParameters, listOf(), listOf(), implementsTypes, members) + psiClass.isEnum() -> return Enum(this, name, getComments(psiClass), modifiers, typeParameters, listOf(), listOf(), implementsTypes, classBodyElements) else -> { - if (psiClass.getConstructors().size > 1 && psiClass.getPrimaryConstructor() == null) { - val finalOrWithEmptyInitializerFields = members.filterIsInstance(javaClass()).filter { it.isVal() || it.initializer.toKotlin().isEmpty() } + if (psiClass.getPrimaryConstructor() == null && psiClass.getConstructors().size > 1) { + val finalOrWithEmptyInitializerFields = classBodyElements.filterIsInstance(javaClass()).filter { it.isVal() || it.initializer.toKotlin().isEmpty() } val initializers = HashMap() - for (member in members) { - if (member is Constructor && !member.isPrimary) { + for (element in classBodyElements) { + if (element is SecondaryConstructor) { for (field in finalOrWithEmptyInitializerFields) { initializers.put(field.identifier.toKotlin(), getDefaultInitializer(field)) } val newStatements = ArrayList() - for (statement in member.block!!.statements) { + for (statement in element.block!!.statements) { var keepStatement = true if (statement is AssignmentExpression) { val assignee = statement.left @@ -148,17 +154,15 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializerFields, initializers))) - member.block = Block(newStatements) + element.block = Block(newStatements) } } //TODO: comments? - members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet(), - ClassType(name, listOf(), false, this), - TypeParameterList.Empty, - ParameterList(createParametersFromFields(finalOrWithEmptyInitializerFields)), - Block(createInitStatementsFromFields(finalOrWithEmptyInitializerFields)), - true)) + val parameters = finalOrWithEmptyInitializerFields.map { Parameter(Identifier("_" + it.identifier.name), it.`type`, Parameter.VarValModifier.None, listOf()) } + classBodyElements.add(PrimaryConstructor(this, MemberComments.Empty, Collections.emptySet(), + ParameterList(parameters), + Block(createInitStatementsFromFields(finalOrWithEmptyInitializerFields)))) } val baseClassParams: List = run { @@ -173,13 +177,43 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } } - return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, members) + return Class(this, name, getComments(psiClass), modifiers, typeParameters, extendsTypes, baseClassParams, implementsTypes, classBodyElements) } } } + private fun findBackingFieldForConstructorParameter(parameter: PsiParameter, constructor: PsiMethod): Pair? { + val body = constructor.getBody() ?: return null + + val refs = findExpressionReferences(parameter, body) + + if (refs.any { PsiUtil.isAccessedForWriting(it) }) return null + + for(ref in refs) { + 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 + val field = assignee.resolve() as? PsiField ?: continue + if (field.getContainingClass() != constructor.getContainingClass()) continue + if (field.getInitializer() != null) continue + + // assignment should be a top-level statement + val statement = assignment.getParent() as? PsiExpressionStatement ?: continue + if (statement.getParent() != body) continue + + // and no other assignments to field should exist in the constructor + if (findExpressionReferences(field, body).any { it != assignee && PsiUtil.isAccessedForWriting(it) && isQualifierEmptyOrThis(it) }) continue + //TODO: check access to field before assignment + + return field to statement + } + + return null + } + private fun convertInitializer(initializer: PsiClassInitializer): Initializer { - return Initializer(convertBlock(initializer.getBody(), true), convertModifierList(initializer.getModifierList())) + return Initializer(convertBlock(initializer.getBody()), convertModifierList(initializer.getModifierList())) } private fun convertField(field: PsiField): Field { @@ -192,9 +226,9 @@ public class Converter(val project: Project, val settings: ConverterSettings) { convertElement(field.getArgumentList())) } - var kType = convertType(field.getType(), field.isAnnotatedAsNotNull()) + var kType = convertVariableType(field) if (field.hasModifierProperty(PsiModifier.FINAL) && field.getInitializer().isDefinitelyNotNull()) { - kType = kType.convertedToNotNull(); + kType = kType.toNotNullType(); } return Field(Identifier(field.getName()!!), @@ -205,60 +239,97 @@ public class Converter(val project: Project, val settings: ConverterSettings) { field.countWriteAccesses(field.getContainingClass())) } - private fun convertMethod(method: PsiMethod): Function { - return convertMethod(method, true) - } - - private fun convertMethod(method: PsiMethod, notEmpty: Boolean): Function { + private fun convertMethod(method: PsiMethod, membersToRemove: MutableSet): Function { if (directlyOverridesMethodFromObject(method)) { dispatcher.expressionVisitor = ExpressionVisitorForDirectObjectInheritors(this) } else { dispatcher.expressionVisitor = ExpressionVisitor(this) } - methodReturnType = method.getReturnType() - val identifier = Identifier(method.getName()) - val returnType = convertType(method.getReturnType(), method.isAnnotatedAsNotNull()) - val body = convertBlock(method.getBody(), notEmpty) - val params = createFunctionParameters(method) - val typeParameterList = convertTypeParameterList(method.getTypeParameterList()) - val modifiers = HashSet(convertModifierList(method.getModifierList())) - if (isOverride(method)) { - modifiers.add(Modifier.OVERRIDE) + try { + methodReturnType = method.getReturnType() + val returnType = convertType(method.getReturnType(), method.isAnnotatedAsNotNull()) + + val modifiers = HashSet(convertModifierList(method.getModifierList())) + if (isOverride(method)) { + modifiers.add(Modifier.OVERRIDE) + } + + val containingClass = method.getContainingClass() + if (containingClass != null && containingClass.isInterface()) { + modifiers.remove(Modifier.ABSTRACT) + } + + if (isNotOpenMethod(method)) { + modifiers.add(Modifier.NOT_OPEN) + } + + val comments = getComments(method) + + if (method.isConstructor()) { + if (method.isPrimaryConstructor()) { + val params = method.getParameterList().getParameters() + val parameterToField = HashMap() + val body = method.getBody() + val block = if (body != null) { + val statementsToRemove = HashSet() + val usageReplacementMap = HashMap() + for (parameter in params) { + val (field, initializationStatement) = findBackingFieldForConstructorParameter(parameter, method) ?: continue + if (membersToRemove.contains(field)) continue // already used as backing field + if (convertVariableType(field) != convertVariableType(parameter)) continue + + parameterToField.put(parameter, field) + statementsToRemove.add(initializationStatement) + + if (field.getName() != parameter.getName()) { + usageReplacementMap.put(parameter, field.getName()!!) + } + } + dispatcher.expressionVisitor = ExpressionVisitor(this, usageReplacementMap) + Block(convertStatements(body.getStatements().filter{ !statementsToRemove.contains(it) }), false) + } + else { + Block.Empty + } + + val parameterList = ParameterList(params.map { + val field = parameterToField[it] + if (field == null) { + convertParameter(it) + } + else { + membersToRemove.add(field) + Parameter(Identifier(field.getName()!!), + convertVariableType(it), + if (field.hasModifierProperty(PsiModifier.FINAL)) Parameter.VarValModifier.Val else Parameter.VarValModifier.Var, + convertModifierList(field.getModifierList()).filter { ACCESS_MODIFIERS.contains(it) }) + } + }) + return PrimaryConstructor(this, comments, modifiers, parameterList, block) + } + else { + val params = convertParameterList(method.getParameterList()) + return SecondaryConstructor(this, comments, modifiers, params, convertBlock(method.getBody())) + } + } + else { + val params = convertParameterList(method.getParameterList()) + val typeParameterList = convertTypeParameterList(method.getTypeParameterList()) + val block = convertBlock(method.getBody()) + return Function(this, Identifier(method.getName()), comments, modifiers, returnType, typeParameterList, params, block) + } } - - val containingClass = method.getContainingClass() - if (containingClass != null && containingClass.isInterface()) { - modifiers.remove(Modifier.ABSTRACT) + finally { + dispatcher.expressionVisitor = ExpressionVisitor(this) } - - if (isNotOpenMethod(method)) { - modifiers.add(Modifier.NOT_OPEN) - } - - if (method.isConstructor()) { - return Constructor(this, identifier, getComments(method), modifiers, returnType, typeParameterList, params, - Block(body.statements), method.isPrimaryConstructor()) - } - - return Function(this, identifier, getComments(method), modifiers, returnType, typeParameterList, params, body) } - private fun createFunctionParameters(method: PsiMethod): ParameterList { - val result = ArrayList() - for (parameter in method.getParameterList().getParameters()) { - result.add(Parameter(Identifier(parameter.getName()!!), - convertType(parameter.getType(), parameter.isAnnotatedAsNotNull()), - parameter.countWriteAccesses(method.getBody()) == 0)) - } - return ParameterList(result) - } - - public fun convertBlock(block: PsiCodeBlock?, notEmpty: Boolean = true): Block { + public fun convertBlock(block: PsiCodeBlock?): Block { if (block == null) return Block.Empty - return Block(convertStatements(block.getChildren().toList()), notEmpty) + return Block(convertStatements(block.getChildren().toList()), true) } public fun convertStatements(statements: List): StatementList { @@ -302,13 +373,13 @@ public class Converter(val project: Project, val settings: ConverterSettings) { public fun convertTypeElement(element: PsiTypeElement?): TypeElement { return TypeElement(if (element == null) - EmptyType() + Type.Empty else convertType(element.getType())) } public fun convertType(`type`: PsiType?): Type { - if (`type` == null) return EmptyType() + if (`type` == null) return Type.Empty return `type`.accept(TypeVisitor(this))!! } @@ -320,22 +391,30 @@ public class Converter(val project: Project, val settings: ConverterSettings) { public fun convertType(`type`: PsiType?, notNull: Boolean): Type { val result = convertType(`type`) if (notNull) { - return result.convertedToNotNull() + return result.toNotNullType() } return result } + public fun convertVariableType(variable: PsiVariable): Type + = convertType(variable.getType(), variable.isAnnotatedAsNotNull()) + private fun convertToNotNullableTypes(types: Array): List - = types.map { convertType(it).convertedToNotNull() } + = types.map { convertType(it).toNotNullType() } - public fun convertParameterList(parameters: Array): List - = parameters.map { convertParameter(it) } + public fun convertParameterList(parameters: PsiParameterList): ParameterList + = ParameterList(parameters.getParameters().map { convertParameter(it) }) - public fun convertParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter { - return Parameter(Identifier(parameter.getName()!!), - convertType(parameter.getType(), - forceNotNull || parameter.isAnnotatedAsNotNull()), true) + public fun convertParameter(parameter: PsiParameter, + forceNotNull: Boolean = false, + varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None, + modifiers: Collection = listOf()): Parameter { + var `type` = convertVariableType(parameter) + if (forceNotNull) { + `type` = `type`.toNotNullType() + } + return Parameter(Identifier(parameter.getName()!!), `type`, varValModifier, modifiers) } public fun convertArguments(expression: PsiCallExpression): List { @@ -380,10 +459,6 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return expression } - private fun createParametersFromFields(fields: List): List { - return fields.map { Parameter(Identifier("_" + it.identifier.name), it.`type`, true) } - } - private fun createInitStatementsFromFields(fields: List): List { val result = ArrayList() for (field in fields) { diff --git a/j2k/src/org/jetbrains/jet/j2k/Utils.kt b/j2k/src/org/jetbrains/jet/j2k/Utils.kt index 9aeb34fe2b3..2fee6c8113b 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Utils.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Utils.kt @@ -24,26 +24,34 @@ import com.intellij.psi.PsiLiteralExpression import com.intellij.psi.PsiNewExpression import org.jetbrains.jet.j2k.ast.Field import org.jetbrains.jet.lang.types.expressions.OperatorConventions -import com.intellij.psi.util.PsiUtil import com.intellij.psi.PsiModifierListOwner +import java.util.ArrayList +import com.intellij.psi.util.PsiUtil +import com.intellij.psi.PsiThisExpression +import java.util.HashMap fun quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier(it).toKotlin() }.makeString(".") -fun PsiElement.countWriteAccesses(scope: PsiElement?): Int { - if (scope == null) return 0 +fun findExpressionReferences(element: PsiElement, scope: PsiElement): Collection { + class Visitor : JavaRecursiveElementVisitor() { + val refs = ArrayList() - var writes = 0 - scope.accept(object: JavaRecursiveElementVisitor() { override fun visitReferenceExpression(expression: PsiReferenceExpression) { super.visitReferenceExpression(expression) - if (PsiUtil.isAccessedForWriting(expression) && expression.isReferenceTo(this@countWriteAccesses)) { - writes++ + if (expression.isReferenceTo(element)) { + refs.add(expression) } } - }) - return writes + } + + val visitor = Visitor() + scope.accept(visitor) + return visitor.refs } +fun PsiElement.countWriteAccesses(scope: PsiElement?): Int + = if (scope != null) findExpressionReferences(this, scope).count { PsiUtil.isAccessedForWriting(it) } else 0 + fun PsiModifierListOwner.isAnnotatedAsNotNull(): Boolean = getModifierList()?.getAnnotations()?.any { NOT_NULL_ANNOTATIONS.contains(it.getQualifiedName()) } ?: false @@ -66,4 +74,9 @@ fun getDefaultInitializer(field: Field): String { else -> "0" } } -} \ No newline at end of file +} + +fun isQualifierEmptyOrThis(ref: PsiReferenceExpression): Boolean { + val qualifier = ref.getQualifierExpression() + return qualifier == null || (qualifier is PsiThisExpression && qualifier.getQualifier() == null) +} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt index 61d99ecd2bb..ac6dc1a4c88 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/AnonymousClass.kt @@ -17,10 +17,9 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.Converter -import org.jetbrains.jet.j2k.ast.types.Type import java.util.Collections -class AnonymousClass(converter: Converter, members: List) +class AnonymousClass(converter: Converter, bodyElements: List) : Class(converter, Identifier("anonClass"), MemberComments.Empty, @@ -29,6 +28,6 @@ class AnonymousClass(converter: Converter, members: List) listOf(), listOf(), listOf(), - members) { + bodyElements) { override fun toKotlin() = bodyToKotlin() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ArrayInitializerExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ArrayInitializerExpression.kt index 5883b8647c4..934238c4aca 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ArrayInitializerExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ArrayInitializerExpression.kt @@ -17,8 +17,6 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.lang.types.expressions.OperatorConventions -import org.jetbrains.jet.j2k.ast.types.ArrayType -import org.jetbrains.jet.j2k.ast.types.isPrimitive open class ArrayInitializerExpression(val arrayType: ArrayType, val initializers: List) : Expression() { override fun toKotlin(): String { @@ -32,14 +30,14 @@ open class ArrayInitializerExpression(val arrayType: ArrayType, val initializers private fun createArrayFunction(): String { val elementType = arrayType.elementType if (elementType.isPrimitive()) { - return (elementType.convertedToNotNull().toKotlin() + "Array").decapitalize() + return (elementType.toNotNullType().toKotlin() + "Array").decapitalize() } - return arrayType.convertedToNotNull().toKotlin().decapitalize() + return arrayType.toNotNullType().toKotlin().decapitalize() } private fun innerTypeStr(): String { - return arrayType.convertedToNotNull().toKotlin().replace("Array", "").toLowerCase() + return arrayType.toNotNullType().toKotlin().replace("Array", "").toLowerCase() } private fun explicitConvertIfNeeded(i: Expression): String { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt index ddb6cd6724b..d1432a41e10 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ArrayWithoutInitializationExpression.kt @@ -16,10 +16,6 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.ArrayType -import org.jetbrains.jet.j2k.ast.types.Type -import org.jetbrains.jet.j2k.ast.types.PrimitiveType - open class ArrayWithoutInitializationExpression(val `type`: Type, val expressions: List) : Expression() { override fun toKotlin(): String { if (`type` is ArrayType) { @@ -55,17 +51,17 @@ open class ArrayWithoutInitializationExpression(val `type`: Type, val expression return if (`type` is ArrayType) when (`type`.elementType) { is PrimitiveType -> - `type`.convertedToNotNull().toKotlin() + `type`.toNotNullType().toKotlin() is ArrayType -> if (hasInit) - `type`.convertedToNotNull().toKotlin() + `type`.toNotNullType().toKotlin() else "arrayOfNulls<" + `type`.elementType.toKotlin() + ">" else -> "arrayOfNulls<" + `type`.elementType.toKotlin() + ">" } else - `type`.convertedToNotNull().toKotlin() + `type`.toNotNullType().toKotlin() } } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt index 661170885fe..c674d40f78f 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Class.kt @@ -17,8 +17,6 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.Converter -import org.jetbrains.jet.j2k.ast.types.ClassType -import org.jetbrains.jet.j2k.ast.types.Type import java.util.HashSet import java.util.ArrayList @@ -31,53 +29,50 @@ open class Class( val extendsTypes: List, val baseClassParams: List, val implementsTypes: List, - val members: List + val bodyElements: List ) : Member(comments, modifiers) { - open val TYPE: String + + override fun toKotlin(): String = + commentsToKotlin() + + modifiersToKotlin() + + keyword + " " + name.toKotlin() + + typeParameterList.toKotlin() + + primaryConstructorSignatureToKotlin() + + implementTypesToKotlin() + + typeParameterList.whereToKotlin().withPrefix(" ") + + bodyToKotlin() + + protected open val keyword: String get() = "class" - val classMembers = parseClassMembers(members) + protected val classMembers: ClassMembers = ClassMembers.fromBodyElements(bodyElements) - open fun primaryConstructorSignatureToKotlin(): String { + protected open fun primaryConstructorSignatureToKotlin(): String { val constructor = classMembers.primaryConstructor - return if (constructor != null) constructor.primarySignatureToKotlin() else "()" + return if (constructor != null) constructor.signatureToKotlin() else "()" } - fun primaryConstructorBodyToKotlin(): String? { - val maybeConstructor = classMembers.primaryConstructor - if (maybeConstructor != null && !(maybeConstructor.block?.isEmpty ?: true)) { - return "\n" + maybeConstructor.primaryBodyToKotlin() + "\n" + protected fun primaryConstructorBodyToKotlin(): String { + val constructor = classMembers.primaryConstructor + if (constructor != null && !(constructor.block?.isEmpty ?: true)) { + return "\n" + constructor.bodyToKotlin() + "\n" } return "" } - fun secondaryConstructorsAsStaticInitFunctions(): MemberList { - return MemberList(classMembers.secondaryConstructors.elements.map { if (it is Constructor) constructorToInit(it) else it }) + private fun secondaryConstructorsAsStaticInitFunctions(): MemberList { + return MemberList(classMembers.secondaryConstructors.elements.map { if (it is SecondaryConstructor) it.toInitFunction(this) else it }) } - private fun constructorToInit(f: Function): Function { - val modifiers = HashSet(f.modifiers) - modifiers.add(Modifier.STATIC) - val statements = ArrayList(f.block?.statements ?: ArrayList()) - statements.add(ReturnStatement(Identifier("__"))) - val block = Block(statements) - val constructorTypeParameters = ArrayList() - constructorTypeParameters.addAll(typeParameterList.parameters) - constructorTypeParameters.addAll(f.typeParameterList.parameters) - return Function(converter, Identifier("init"), MemberComments.Empty, modifiers, - ClassType(name, constructorTypeParameters, false, converter), - TypeParameterList(constructorTypeParameters), f.params, block) - } - - fun baseClassSignatureWithParams(): List { - if (TYPE.equals("class") && extendsTypes.size() == 1) { + private fun baseClassSignatureWithParams(): List { + if (keyword.equals("class") && extendsTypes.size() == 1) { val baseParams = baseClassParams.toKotlin(", ") return arrayListOf(extendsTypes[0].toKotlin() + "(" + baseParams + ")") } return extendsTypes.map { it.toKotlin() } } - fun implementTypesToKotlin(): String { + protected fun implementTypesToKotlin(): String { val allTypes = ArrayList() allTypes.addAll(baseClassSignatureWithParams()) allTypes.addAll(implementsTypes.map { it.toKotlin() }) @@ -87,9 +82,9 @@ open class Class( " : " + allTypes.makeString(", ") } - fun modifiersToKotlin(): String { + protected fun modifiersToKotlin(): String { val modifierList = ArrayList() - val modifier = accessModifier() + val modifier = modifiers.accessModifier() if (modifier != null) { modifierList.add(modifier) } @@ -102,15 +97,20 @@ open class Class( return modifierList.toKotlin() } - open fun isDefinitelyFinal() = modifiers.contains(Modifier.FINAL) + protected open fun isDefinitelyFinal(): Boolean + = modifiers.contains(Modifier.FINAL) - open fun needsOpenModifier() = !isDefinitelyFinal() && converter.settings.openByDefault + protected open fun needsOpenModifier(): Boolean + = !isDefinitelyFinal() && converter.settings.openByDefault fun bodyToKotlin(): String { return " {" + classMembers.nonStaticMembers.toKotlin() + primaryConstructorBodyToKotlin() + classObjectToKotlin() + "}" + //TODO: + //val insideBody = classMembers.nonStaticMembers.toKotlin() + primaryConstructorBodyToKotlin() + classObjectToKotlin() + //return if (insideBody.trim().isNotEmpty()) " {" + insideBody + "}" else "" } - fun classObjectToKotlin(): String { + private fun classObjectToKotlin(): String { val secondaryConstructorsAsStaticInitFunctions = secondaryConstructorsAsStaticInitFunctions() val staticMembers = classMembers.staticMembers if (secondaryConstructorsAsStaticInitFunctions.isEmpty() && staticMembers.isEmpty()) { @@ -118,14 +118,4 @@ open class Class( } return "\nclass object {${secondaryConstructorsAsStaticInitFunctions.toKotlin()}${staticMembers.toKotlin()}}" } - - override fun toKotlin(): String = - commentsToKotlin() + - modifiersToKotlin() + - TYPE + " " + name.toKotlin() + - typeParameterList.toKotlin() + - primaryConstructorSignatureToKotlin() + - implementTypesToKotlin() + - typeParameterList.whereToKotlin().withPrefix(" ") + - bodyToKotlin() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Constructor.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Constructor.kt deleted file mode 100644 index f9a3fd23db2..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Constructor.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast - -import org.jetbrains.jet.j2k.ast.types.Type -import org.jetbrains.jet.j2k.Converter - -class Constructor( - converter: Converter, - identifier: Identifier, - comments: MemberComments, - modifiers: Set, - `type`: Type, - typeParameters: TypeParameterList, - params: Element, - block: Block, - val isPrimary: Boolean -) : Function(converter, identifier, comments, modifiers, - `type`, typeParameters, params, block) { - - fun primarySignatureToKotlin(): String { - return "(" + params.toKotlin() + ")" - } - - fun primaryBodyToKotlin(): String { - return block!!.toKotlin() - } -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt new file mode 100644 index 00000000000..7fc1a020c54 --- /dev/null +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.j2k.ast + +import org.jetbrains.jet.j2k.Converter +import java.util.HashSet +import java.util.ArrayList + +abstract class Constructor( + converter: Converter, + comments: MemberComments, + modifiers: Set, + parameterList: ParameterList, + block: Block +) : Function(converter, Identifier.Empty, comments, modifiers, Type.Empty, TypeParameterList.Empty, parameterList, block) + +class PrimaryConstructor(converter: Converter, + comments: MemberComments, + modifiers: Set, + parameterList: ParameterList, + block: Block) + : Constructor(converter, comments, modifiers, parameterList, block) { + + public fun signatureToKotlin(): String = "(" + parameterList.toKotlin() + ")" + + public fun bodyToKotlin(): String = block!!.toKotlin() +} + +class SecondaryConstructor(converter: Converter, + comments: MemberComments, + modifiers: Set, + parameterList: ParameterList, + block: Block) + : Constructor(converter, comments, modifiers, parameterList, block) { + + public fun toInitFunction(containingClass: Class): Function { + val modifiers = HashSet(modifiers) + modifiers.add(Modifier.STATIC) + val statements = ArrayList(block?.statements ?: listOf()) + statements.add(ReturnStatement(Identifier("__"))) + val block = Block(statements) + val typeParameters = ArrayList() + typeParameters.addAll(containingClass.typeParameterList.parameters) + return Function(converter, Identifier("init"), MemberComments.Empty, modifiers, + ClassType(containingClass.name, typeParameters, false, converter), + TypeParameterList(typeParameters), parameterList, block) + } +} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt index 32051b5d9ee..1bf2124c4b0 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Enum.kt @@ -17,7 +17,6 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.Converter -import org.jetbrains.jet.j2k.ast.types.Type class Enum( converter: Converter, @@ -28,9 +27,9 @@ class Enum( extendsTypes: List, baseClassParams: List, implementsTypes: List, - members: List + bodyElements: List ) : Class(converter, name, comments, modifiers, typeParameterList, - extendsTypes, baseClassParams, implementsTypes, members) { + extendsTypes, baseClassParams, implementsTypes, bodyElements) { override fun primaryConstructorSignatureToKotlin(): String { val s: String = super.primaryConstructorSignatureToKotlin() diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt b/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt index 8821caabe44..fe208f355a7 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/EnumConstant.kt @@ -16,15 +16,13 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type - open class EnumConstant( identifier: Identifier, members: MemberComments, modifiers: Set, `type`: Type, params: Element -) : Field(identifier, members, modifiers, `type`.convertedToNotNull(), params, 0) { +) : Field(identifier, members, modifiers, `type`.toNotNullType(), params, 0) { override fun toKotlin(): String { if (initializer.toKotlin().isEmpty()) { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt index bfcbe495968..e2c995677c2 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Expressions.kt @@ -16,8 +16,6 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type - open class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() { override fun toKotlin() = expression.toKotlin() + (if (!lvalue && expression.isNullable) "!!" else "") + diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt index b1b14b6d409..600a8bddca8 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Field.kt @@ -16,7 +16,6 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.* import java.util.ArrayList @@ -35,7 +34,7 @@ open class Field( modifierList.add(Modifier.ABSTRACT) } - val modifier = accessModifier() + val modifier = modifiers.accessModifier() if (modifier != null) { modifierList.add(modifier) } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt index 9b5efdaa3a2..a00b35250d2 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Function.kt @@ -16,9 +16,7 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type import java.util.ArrayList -import org.jetbrains.jet.j2k.ast.types.isUnit import org.jetbrains.jet.j2k.Converter open class Function( @@ -28,7 +26,7 @@ open class Function( modifiers: Set, val `type`: Type, val typeParameterList: TypeParameterList, - val params: Element, + val parameterList: ParameterList, var block: Block? ) : Member(comments, modifiers) { @@ -39,7 +37,7 @@ open class Function( resultingModifiers.add(Modifier.OVERRIDE) } - val accessModifier = accessModifier() + val accessModifier = modifiers.accessModifier() if (accessModifier != null && !isOverride) { resultingModifiers.add(accessModifier) } @@ -49,10 +47,10 @@ open class Function( } if (converter.settings.openByDefault && - !modifiers.contains(Modifier.ABSTRACT) && - !isOverride && - !modifiers.contains(Modifier.FINAL) && - !modifiers.contains(Modifier.PRIVATE)) { + !modifiers.contains(Modifier.ABSTRACT) && + !isOverride && + !modifiers.contains(Modifier.FINAL) && + !modifiers.contains(Modifier.PRIVATE)) { resultingModifiers.add(Modifier.OPEN) } @@ -69,7 +67,7 @@ open class Function( return commentsToKotlin() + modifiersToKotlin() + "fun ${typeParameterList.toKotlin().withSuffix(" ")}${name.toKotlin()}" + - "(${params.toKotlin()})" + + "(${parameterList.toKotlin()})" + returnTypeToKotlin() + typeParameterList.whereToKotlin() + block?.toKotlin() diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt b/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt index dc8dfd8ce0d..616c67d5009 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/LocalVariable.kt @@ -16,7 +16,6 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type import org.jetbrains.jet.j2k.Converter class LocalVariable( diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt index 9497c019e8c..7982f2f6cb9 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Members.kt @@ -25,10 +25,6 @@ class MemberComments(elements: List) : WhiteSpaceSeparatedElementList(e } abstract class Member(val comments: MemberComments, val modifiers: Set) : Element { - fun accessModifier(): Modifier? { - return modifiers.find { m -> m == Modifier.PUBLIC || m == Modifier.PROTECTED || m == Modifier.PRIVATE } - } - fun isAbstract(): Boolean = modifiers.contains(Modifier.ABSTRACT) fun isStatic(): Boolean = modifiers.contains(Modifier.STATIC) fun commentsToKotlin(): String = comments.toKotlin() @@ -42,28 +38,28 @@ class MemberList(elements: List) : WhiteSpaceSeparatedElementList(eleme get() = elements.filter { it is Member }.map { it as Member } } -class ClassMembers( - val primaryConstructor: Constructor?, +class ClassMembers private( + val primaryConstructor: PrimaryConstructor?, val secondaryConstructors: MemberList, val allMembers: MemberList, val staticMembers: MemberList, - val nonStaticMembers: MemberList -) { -} - -fun parseClassMembers(elements: List): ClassMembers { - val groups = splitInGroups(elements) - val constructors = groups.filter { it.member is Constructor } - val primaryConstructor = constructors.map { it.member }.find { (it as Constructor).isPrimary } - val secondaryConstructors = constructors.filter { !(it.member as Constructor).isPrimary } - val nonConstructors = groups.filter { it.member !is Constructor } - val staticMembers = nonConstructors.filter { it.member.isStatic() } - val nonStaticMembers = nonConstructors.filter { !it.member.isStatic() } - return ClassMembers(primaryConstructor as Constructor?, - secondaryConstructors.toMemberList(), - nonConstructors.toMemberList(), - staticMembers.toMemberList(), - nonStaticMembers.toMemberList()) + val nonStaticMembers: MemberList) { + class object { + public fun fromBodyElements(elements: List): ClassMembers { + val groups = splitInGroups(elements) + val constructors = groups.filter { it.member is Constructor } + val primaryConstructor = constructors.map { it.member }.filterIsInstance(javaClass()).firstOrNull() + val secondaryConstructors = constructors.filter { it.member is SecondaryConstructor } + val nonConstructors = groups.filter { it.member !is Constructor } + val staticMembers = nonConstructors.filter { it.member.isStatic() } + val nonStaticMembers = nonConstructors.filter { !it.member.isStatic() } + return ClassMembers(primaryConstructor, + secondaryConstructors.toMemberList(), + nonConstructors.toMemberList(), + staticMembers.toMemberList(), + nonStaticMembers.toMemberList()) + } + } } private fun List.toMemberList() = MemberList(flatMap { it.elements }) @@ -74,8 +70,8 @@ private fun splitInGroups(elements: List): List { for (element in elements) { currentGroup.add(element) if (element is Member) { - result.add(Pair(element, currentGroup)) - currentGroup = ArrayList() + result.add(element to currentGroup) + currentGroup = ArrayList() } } if (result.isNotEmpty()) { diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt b/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt index 63264d8c38e..89c330f407f 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/MethodCallExpression.kt @@ -16,7 +16,6 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type import java.util.ArrayList open class MethodCallExpression( diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt index db2b0adfc2a..c2ef0d89d99 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Modifier.kt @@ -16,6 +16,11 @@ package org.jetbrains.jet.j2k.ast +import org.jetbrains.jet.j2k.ast.Modifier.PUBLIC +import org.jetbrains.jet.j2k.ast.Modifier.PROTECTED +import org.jetbrains.jet.j2k.ast.Modifier.PRIVATE +import org.jetbrains.jet.j2k.ast.Modifier.INTERNAL + enum class Modifier(val name: String) { PUBLIC: Modifier("public") PROTECTED: Modifier("protected") @@ -25,6 +30,25 @@ enum class Modifier(val name: String) { ABSTRACT: Modifier("abstract") FINAL: Modifier("final") OPEN: Modifier("open") - NOT_OPEN: Modifier("not open") + NOT_OPEN: Modifier("not open") //TODO: drop it OVERRIDE: Modifier("override") + + public fun toKotlin(): String? { + return when(this) { + INTERNAL -> null + NOT_OPEN -> throw IllegalArgumentException() + else -> name + } + } } + +val ACCESS_MODIFIERS = setOf(PUBLIC, PROTECTED, PRIVATE, INTERNAL) + +fun Collection.accessModifier(): Modifier? { + return firstOrNull { ACCESS_MODIFIERS.contains(it) } +} + +fun Collection.toKotlin(): String + = if (isNotEmpty()) map { it.toKotlin() }.filterNotNull().makeString(" ") + " " else "" + + diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt index 5aca7825035..d4b65ec78ff 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Parameter.kt @@ -16,19 +16,31 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type -import org.jetbrains.jet.j2k.ast.types.VarArg +class Parameter(val identifier: Identifier, val `type`: Type, val varVal: Parameter.VarValModifier, val modifiers: Collection) : Expression() { + //TODO: merge with modifiers? + //TODO: maybe vararg is modifier too? + public enum class VarValModifier { + None + Val + Var + } -open class Parameter(val identifier: Identifier, val `type`: Type, val readOnly: Boolean = true) : Expression() { override fun toKotlin(): String { - val vararg: String = (if (`type` is VarArg) - "vararg " - else - "") - val `var`: String? = (if (readOnly) - "" - else - "var ") - return vararg + `var` + identifier.toKotlin() + " : " + `type`.toKotlin() + val builder = StringBuilder() + + builder.append(modifiers.toKotlin()) + + if (`type` is VarArgType) { + assert(varVal == VarValModifier.None) + builder.append("vararg ") + } + + when (varVal) { + VarValModifier.Var -> builder.append("var ") + VarValModifier.Val -> builder.append("val ") + } + + builder.append(identifier.toKotlin()).append(": ").append(`type`.toKotlin()) + return builder.toString() } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt b/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt index 6af085bbc34..4c551aa1176 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/ReferenceElement.kt @@ -16,8 +16,6 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type - class ReferenceElement(val reference: Identifier, val types: List) : Element { override fun toKotlin() = reference.toKotlin() + types.toKotlin(", ", "<", ">") } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt index 8070fe89731..0799dc50d27 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Trait.kt @@ -17,7 +17,6 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.Converter -import org.jetbrains.jet.j2k.ast.types.Type class Trait( converter: Converter, @@ -28,11 +27,11 @@ class Trait( extendsTypes: List, baseClassParams: List, implementsTypes: List, - members: List + bodyElements: List ) : Class(converter, name, comments, modifiers, typeParameterList, - extendsTypes, baseClassParams, implementsTypes, members) { + extendsTypes, baseClassParams, implementsTypes, bodyElements) { - override val TYPE: String + override val keyword: String get() = "trait" override fun primaryConstructorSignatureToKotlin() = "" diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt b/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt index 79e989f2619..df7d86c5156 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/TypeElement.kt @@ -16,10 +16,8 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type - open class TypeElement(val `type`: Type) : Element { override fun toKotlin() = `type`.toKotlin() - fun toKotlinNotNull(): String = `type`.convertedToNotNull().toKotlin() + fun toKotlinNotNull(): String = `type`.toNotNullType().toKotlin() } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt b/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt index 803fe1714d8..a1d3b5bd199 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/TypeParameters.kt @@ -16,7 +16,6 @@ package org.jetbrains.jet.j2k.ast -import org.jetbrains.jet.j2k.ast.types.Type import com.intellij.psi.PsiTypeParameter import org.jetbrains.jet.j2k.Converter import com.intellij.psi.PsiTypeParameterList diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt new file mode 100644 index 00000000000..7fec002006b --- /dev/null +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt @@ -0,0 +1,113 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.j2k.ast + +import org.jetbrains.jet.j2k.Converter +import java.util.ArrayList + +fun Type.isPrimitive(): Boolean = this is PrimitiveType +fun Type.isUnit(): Boolean = this == Type.Unit + +abstract class MayBeNullableType(nullable: Boolean, val converter: Converter) : Type { + override val isNullable: Boolean = !converter.settings.forceNotNullTypes && nullable +} + +trait NotNullType : Type { + override val isNullable: Boolean + get() = false +} + +trait Type : Element { + val isNullable: Boolean + + open fun toNotNullType(): Type { + if (isNullable) throw UnsupportedOperationException("toNotNullType must be defined") + return this + } + + protected fun isNullableStr(): String? { + return if (isNullable) "?" else "" + } + + object Empty : NotNullType { + override fun toKotlin(): String = "UNRESOLVED_TYPE" + } + + object Unit: NotNullType { + override fun toKotlin() = "Unit" + } + + override fun equals(other: Any?): Boolean = other is Type && other.toKotlin() == this.toKotlin() + + override fun hashCode(): Int = toKotlin().hashCode() +} + +open class ClassType(val `type`: Identifier, val parameters: List, nullable: Boolean, + converter: Converter) : MayBeNullableType(nullable, converter) { + + override fun toKotlin(): String { + // TODO change to map() when KT-2051 is fixed + val parametersToKotlin = ArrayList() + for (param in parameters) { + parametersToKotlin.add(param.toKotlin()) + } + var params: String = if (parametersToKotlin.size() == 0) + "" + else + "<" + parametersToKotlin.makeString(", ") + ">" + return `type`.toKotlin() + params + isNullableStr() + } + + + override fun toNotNullType(): Type = ClassType(`type`, parameters, false, converter) +} + +class ArrayType( + val elementType: Type, + nullable: Boolean, + converter: Converter +) : MayBeNullableType(nullable, converter) { + override fun toKotlin(): String { + if (elementType is PrimitiveType) { + return elementType.toKotlin() + "Array" + isNullableStr() + } + + return "Array<" + elementType.toKotlin() + ">" + isNullableStr() + } + + override fun toNotNullType(): Type = ArrayType(elementType, false, converter) +} + +open class InProjectionType(val bound: Type) : NotNullType { + override fun toKotlin(): String = "in " + bound.toKotlin() +} + +open class OutProjectionType(val bound: Type) : NotNullType { + override fun toKotlin(): String = "out " + bound.toKotlin() +} + +open class StarProjectionType() : NotNullType { + override fun toKotlin(): String = "*" +} + +open class PrimitiveType(val `type`: Identifier) : NotNullType { + override fun toKotlin(): String = `type`.toKotlin() +} + +open class VarArgType(val `type`: Type) : NotNullType { + override fun toKotlin(): String = `type`.toKotlin() +} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt index 0ace8e6159a..2a45f1bf65b 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Util.kt @@ -21,9 +21,6 @@ import java.util.ArrayList fun List.toKotlin(separator: String, prefix: String = "", postfix: String = ""): String = if (isNotEmpty()) map { it.toKotlin() }.makeString(separator, prefix, postfix) else "" -fun Collection.toKotlin(separator: String = " "): String - = if (isNotEmpty()) map { it.name }.makeString(separator) + separator else "" - fun String.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this fun Expression.withPrefix(prefix: String): String = if (isEmpty) "" else prefix + toKotlin() diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/ArrayType.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/ArrayType.kt deleted file mode 100644 index f185689ab7f..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/ArrayType.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -import org.jetbrains.jet.j2k.Converter - -class ArrayType( - val elementType: Type, - nullable: Boolean, - converter: Converter -) : MayBeNullableType(nullable, converter) { - override fun toKotlin(): String { - if (elementType is PrimitiveType) { - return elementType.toKotlin() + "Array" + isNullableStr() - } - - return "Array<" + elementType.toKotlin() + ">" + isNullableStr() - } - - override fun convertedToNotNull(): Type = ArrayType(elementType, false, converter) -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/ClassType.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/ClassType.kt deleted file mode 100644 index b563cb6ca12..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/ClassType.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -import org.jetbrains.jet.j2k.ast.Element -import org.jetbrains.jet.j2k.ast.Identifier -import java.util.ArrayList -import org.jetbrains.jet.j2k.Converter - -open class ClassType(val `type`: Identifier, val parameters: List, nullable: Boolean, - converter: Converter) : MayBeNullableType(nullable, converter) { - - override fun toKotlin(): String { - // TODO change to map() when KT-2051 is fixed - val parametersToKotlin = ArrayList() - for (param in parameters) { - parametersToKotlin.add(param.toKotlin()) - } - var params: String = if (parametersToKotlin.size() == 0) - "" - else - "<" + parametersToKotlin.makeString(", ") + ">" - return `type`.toKotlin() + params + isNullableStr() - } - - - override fun convertedToNotNull(): Type = ClassType(`type`, parameters, false, converter) -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/EmptyType.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/EmptyType.kt deleted file mode 100644 index e4d0c3b5fc3..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/EmptyType.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -open class EmptyType() : NotNullType { - override fun toKotlin(): String = "UNRESOLVED_TYPE" -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/InProjectionType.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/InProjectionType.kt deleted file mode 100644 index 4ea99da170b..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/InProjectionType.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -open class InProjectionType(val bound: Type) : NotNullType { - override fun toKotlin(): String = "in " + bound.toKotlin() -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/OutProjectionType.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/OutProjectionType.kt deleted file mode 100644 index 2ee59704923..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/OutProjectionType.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -open class OutProjectionType(val bound: Type) : NotNullType { - override fun toKotlin(): String = "out " + bound.toKotlin() -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/PrimitiveType.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/PrimitiveType.kt deleted file mode 100644 index 990bc51e02c..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/PrimitiveType.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -import org.jetbrains.jet.j2k.ast.Identifier - -open class PrimitiveType(val `type`: Identifier) : NotNullType { - override fun toKotlin(): String = `type`.toKotlin() -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/StarProjectionType.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/StarProjectionType.kt deleted file mode 100644 index 4956cdcc4f8..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/StarProjectionType.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -open class StarProjectionType() : NotNullType { - override fun toKotlin(): String = "*" -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/Type.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/Type.kt deleted file mode 100644 index c02d85e56b5..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/Type.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -import org.jetbrains.jet.j2k.ast.Element -import org.jetbrains.jet.j2k.Converter - -fun Type.isPrimitive(): Boolean = this is PrimitiveType -fun Type.isUnit(): Boolean = this == UnitType - -abstract class MayBeNullableType(nullable: Boolean, val converter: Converter) : Type { - override val isNullable: Boolean = !converter.settings.forceNotNullTypes && nullable -} - -trait NotNullType : Type { - override val isNullable: Boolean - get() = false -} - -object UnitType: NotNullType { - override fun toKotlin() = "Unit" -} - -trait Type : Element { - val isNullable: Boolean - - open fun convertedToNotNull(): Type { - if (isNullable) throw UnsupportedOperationException("convertedToNotNull must be defined") - return this - } - - protected fun isNullableStr(): String? { - return if (isNullable) "?" else "" - } -} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/types/VarArg.kt b/j2k/src/org/jetbrains/jet/j2k/ast/types/VarArg.kt deleted file mode 100644 index 6b2e29b49cc..00000000000 --- a/j2k/src/org/jetbrains/jet/j2k/ast/types/VarArg.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.j2k.ast.types - -open class VarArg(val `type`: Type) : NotNullType { - override fun toKotlin(): String = `type`.toKotlin() -} diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt index b0834e4581b..58086cff70a 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt @@ -19,16 +19,15 @@ package org.jetbrains.jet.j2k.visitors import com.intellij.psi.* import org.jetbrains.jet.j2k.* import org.jetbrains.jet.j2k.ast.* -import org.jetbrains.jet.j2k.ast.types.Type class ElementVisitor(public val converter: Converter) : JavaElementVisitor() { public var result: Element = Element.Empty protected set override fun visitLocalVariable(variable: PsiLocalVariable) { - var kType = converter.convertType(variable.getType(), variable.isAnnotatedAsNotNull()) + var kType = converter.convertVariableType(variable) if (variable.hasModifierProperty(PsiModifier.FINAL) && variable.getInitializer().isDefinitelyNotNull()) { - kType = kType.convertedToNotNull() + kType = kType.toNotNullType() } result = LocalVariable(Identifier(variable.getName()!!), converter.convertModifierList(variable.getModifierList()), @@ -68,7 +67,7 @@ class ElementVisitor(public val converter: Converter) : JavaElementVisitor() { } override fun visitParameterList(list: PsiParameterList) { - result = ParameterList(converter.convertParameterList(list.getParameters())) + result = converter.convertParameterList(list) } override fun visitComment(comment: PsiComment) { diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt index ef4c34da369..610a30518b3 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt @@ -25,9 +25,9 @@ import com.intellij.psi.CommonClassNames.* import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.jet.lang.types.lang.PrimitiveType import org.jetbrains.jet.j2k.* -import org.jetbrains.jet.j2k.ast.types.ArrayType -open class ExpressionVisitor(public val converter: Converter) : JavaElementVisitor() { +open class ExpressionVisitor(protected val converter: Converter, + private val usageReplacementMap: Map = mapOf()) : JavaElementVisitor() { public var result: Expression = Expression.Empty protected set @@ -141,7 +141,7 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit } protected fun convertMethodCallExpression(expression: PsiMethodCallExpression) { - if (!expression.isSuperConstructorCall() || !isInsidePrimaryConstructor(expression)) { + if (!expression.isSuperConstructorCall() || !expression.isInsidePrimaryConstructor()) { result = MethodCallExpression(converter.convertExpression(expression.getMethodExpression()), converter.convertArguments(expression), converter.convertTypes(expression.getTypeArguments()), @@ -212,7 +212,7 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit } override fun visitReferenceExpression(expression: PsiReferenceExpression) { - val containingConstructor = getContainingConstructor(expression) + val containingConstructor = expression.getContainingConstructor() val insideSecondaryConstructor = containingConstructor != null && !containingConstructor.isPrimaryConstructor() val addReceiver = insideSecondaryConstructor && (expression.getReference()?.resolve() as? PsiField)?.getContainingClass() == containingConstructor!!.getContainingClass() @@ -231,20 +231,21 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit identifier = Identifier("size", isNullable) } else if (qualifier == null) { - val resolved = expression.getReference()?.resolve() - if (resolved is PsiClass) { - if (PrimitiveType.values() any { it.getTypeName().asString() == resolved.getName() }) { - result = Identifier(resolved.getQualifiedName()!!, false) + val target = expression.getReference()?.resolve() + + if (target is PsiClass) { + if (PrimitiveType.values() any { it.getTypeName().asString() == target.getName() }) { + result = Identifier(target.getQualifiedName()!!, false) return } } - if (resolved is PsiMember - && resolved.hasModifierProperty(PsiModifier.STATIC) - && resolved.getContainingClass() != null - && PsiTreeUtil.getParentOfType(expression, javaClass()) != resolved.getContainingClass() - && !isStaticallyImported(resolved, expression)) { - var member = resolved as PsiMember + if (target is PsiMember + && target.hasModifierProperty(PsiModifier.STATIC) + && target.getContainingClass() != null + && PsiTreeUtil.getParentOfType(expression, javaClass()) != target.getContainingClass() + && !isStaticallyImported(target, expression)) { + var member = target as PsiMember var code = Identifier(referencedName).toKotlin() while (member.getContainingClass() != null) { code = Identifier(member.getContainingClass()!!.getName()!!).toKotlin() + "." + code @@ -253,6 +254,13 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit result = Identifier(code, false, false) return } + + if (target is PsiVariable) { + val replacement = usageReplacementMap[target] + if (replacement != null) { + identifier = Identifier(replacement, isNullable) + } + } } result = CallChainExpression(converter.convertExpression(qualifier), identifier) @@ -268,19 +276,13 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit } override fun visitSuperExpression(expression: PsiSuperExpression) { - val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier() - result = SuperExpression((if (qualifier != null) - Identifier(qualifier.getQualifiedName()!!) - else - Identifier.Empty)) + val qualifier = expression.getQualifier() + result = SuperExpression(if (qualifier != null) Identifier(qualifier.getQualifiedName()!!) else Identifier.Empty) } override fun visitThisExpression(expression: PsiThisExpression) { - val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier() - result = ThisExpression((if (qualifier != null) - Identifier(qualifier.getQualifiedName()!!) - else - Identifier.Empty)) + val qualifier = expression.getQualifier() + result = ThisExpression(if (qualifier != null) Identifier(qualifier.getQualifiedName()!!) else Identifier.Empty) } override fun visitTypeCastExpression(expression: PsiTypeCastExpression) { diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt index 9d834f1ee67..c7ada820449 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitorForDirectObjectInheritors.kt @@ -23,16 +23,17 @@ import org.jetbrains.jet.j2k.ast.Identifier import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT import org.jetbrains.jet.j2k.ast.MethodCallExpression -open class ExpressionVisitorForDirectObjectInheritors(converter: Converter) : ExpressionVisitor(converter) { +open class ExpressionVisitorForDirectObjectInheritors(converter: Converter, usageReplacementMap: Map = mapOf()) +: ExpressionVisitor(converter, usageReplacementMap) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { val methodExpression = expression.getMethodExpression() - if (superMethodInvocation(methodExpression, "hashCode")) { + if (isSuperMethodInvocation(methodExpression, "hashCode")) { result = MethodCallExpression.build(Identifier("System", false), "identityHashCode", listOf(Identifier("this"))) } - else if (superMethodInvocation(methodExpression, "equals")) { + else if (isSuperMethodInvocation(methodExpression, "equals")) { result = MethodCallExpression.build(Identifier("this", false), "identityEquals", converter.convertArguments(expression)) } - else if (superMethodInvocation(methodExpression, "toString")) { + else if (isSuperMethodInvocation(methodExpression, "toString")) { result = DummyStringExpression("getJavaClass<${getClassName(methodExpression)}>.getName() + '@' + Integer.toHexString(hashCode())") } else { @@ -40,14 +41,7 @@ open class ExpressionVisitorForDirectObjectInheritors(converter: Converter) : Ex } } - private fun superMethodInvocation(expression: PsiReferenceExpression, methodName: String?): Boolean { - val referenceName: String? = expression.getReferenceName() - val qualifierExpression: PsiExpression? = expression.getQualifierExpression() - if (referenceName == methodName && qualifierExpression is PsiSuperExpression) { - if (qualifierExpression.getType()?.getCanonicalText() == JAVA_LANG_OBJECT) { - return true - } - } - return false - } + private fun isSuperMethodInvocation(expression: PsiReferenceExpression, methodName: String): Boolean + = expression.getReferenceName() == methodName + && (expression.getQualifierExpression() as? PsiSuperExpression)?.getType()?.getCanonicalText() == JAVA_LANG_OBJECT } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt index 0d44b928a52..f81fa378724 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt @@ -32,7 +32,7 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() { } override fun visitBlockStatement(statement: PsiBlockStatement) { - result = converter.convertBlock(statement.getCodeBlock(), true) + result = converter.convertBlock(statement.getCodeBlock()) } override fun visitBreakStatement(statement: PsiBreakStatement) { @@ -217,10 +217,10 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() { val catchBlockParameters = statement.getCatchBlockParameters() for (i in 0..catchBlocks.size - 1) { catches.add(CatchStatement(converter.convertParameter(catchBlockParameters[i], true), - converter.convertBlock(catchBlocks[i], true))) + converter.convertBlock(catchBlocks[i]))) } - result = TryStatement(converter.convertBlock(statement.getTryBlock(), true), - catches, converter.convertBlock(statement.getFinallyBlock(), true)) + result = TryStatement(converter.convertBlock(statement.getTryBlock()), + catches, converter.convertBlock(statement.getFinallyBlock())) } override fun visitWhileStatement(statement: PsiWhileStatement) { diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt index 1cb506fb052..69332b51b77 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt @@ -20,7 +20,6 @@ import com.intellij.psi.* import com.intellij.psi.impl.source.PsiClassReferenceType import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.ast.* -import org.jetbrains.jet.j2k.ast.types.* import java.util.LinkedList import com.intellij.openapi.util.text.StringUtil import java.util.ArrayList @@ -32,7 +31,7 @@ open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor( override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type { val name = primitiveType.getCanonicalText() return if (name == "void") { - UnitType + Type.Unit } else if (PRIMITIVE_TYPES_NAMES.contains(name)) { PrimitiveType(Identifier(StringUtil.capitalize(name))) @@ -120,7 +119,7 @@ open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor( } override fun visitEllipsisType(ellipsisType: PsiEllipsisType): Type { - return VarArg(converter.convertType(ellipsisType.getComponentType())) + return VarArgType(converter.convertType(ellipsisType.getComponentType())) } private fun createQualifiedName(classType: PsiClassType): String { diff --git a/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt b/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt index 25ab48477a6..d202ce4190f 100644 --- a/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt +++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/AbstractJavaToKotlinConverterTest.kt @@ -42,10 +42,7 @@ import java.io.StringReader public abstract class AbstractJavaToKotlinConverterPluginTest() : AbstractJavaToKotlinConverterTest("ide.kt", PluginSettings) public abstract class AbstractJavaToKotlinConverterBasicTest() : AbstractJavaToKotlinConverterTest("kt", TestSettings) -abstract class AbstractJavaToKotlinConverterTest( - val kotlinFileExtension: String, - val settings: ConverterSettings -) : LightIdeaTestCase() { +abstract class AbstractJavaToKotlinConverterTest(val kotlinFileExtension: String, val settings: ConverterSettings ) : LightIdeaTestCase() { val testHeaderPattern = Pattern.compile("//(element|expression|statement|method|class|file|comp)\n") diff --git a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterBasicTestGenerated.java b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterBasicTestGenerated.java index ec425cb083f..64506cd871d 100644 --- a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterBasicTestGenerated.java +++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterBasicTestGenerated.java @@ -720,6 +720,41 @@ public class JavaToKotlinConverterBasicTestGenerated extends AbstractJavaToKotli doTest("j2k/tests/testData/ast/constructors/customerBuilder.java"); } + @TestMetadata("fieldsInitializedFromParams1.java") + public void testFieldsInitializedFromParams1() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.java"); + } + + @TestMetadata("fieldsInitializedFromParams2.java") + public void testFieldsInitializedFromParams2() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.java"); + } + + @TestMetadata("fieldsInitializedFromParams3.java") + public void testFieldsInitializedFromParams3() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.java"); + } + + @TestMetadata("fieldsInitializedFromParams4.java") + public void testFieldsInitializedFromParams4() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.java"); + } + + @TestMetadata("fieldsInitializedFromParams5.java") + public void testFieldsInitializedFromParams5() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.java"); + } + + @TestMetadata("fieldsInitializedFromParams6.java") + public void testFieldsInitializedFromParams6() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.java"); + } + + @TestMetadata("fieldsInitializedFromParams7.java") + public void testFieldsInitializedFromParams7() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.java"); + } + @TestMetadata("genericIdentifier.java") public void testGenericIdentifier() throws Exception { doTest("j2k/tests/testData/ast/constructors/genericIdentifier.java"); diff --git a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterPluginTestGenerated.java b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterPluginTestGenerated.java index de1ad8a5857..566cedfc361 100644 --- a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterPluginTestGenerated.java +++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterPluginTestGenerated.java @@ -720,6 +720,41 @@ public class JavaToKotlinConverterPluginTestGenerated extends AbstractJavaToKotl doTest("j2k/tests/testData/ast/constructors/customerBuilder.java"); } + @TestMetadata("fieldsInitializedFromParams1.java") + public void testFieldsInitializedFromParams1() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.java"); + } + + @TestMetadata("fieldsInitializedFromParams2.java") + public void testFieldsInitializedFromParams2() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.java"); + } + + @TestMetadata("fieldsInitializedFromParams3.java") + public void testFieldsInitializedFromParams3() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.java"); + } + + @TestMetadata("fieldsInitializedFromParams4.java") + public void testFieldsInitializedFromParams4() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.java"); + } + + @TestMetadata("fieldsInitializedFromParams5.java") + public void testFieldsInitializedFromParams5() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.java"); + } + + @TestMetadata("fieldsInitializedFromParams6.java") + public void testFieldsInitializedFromParams6() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.java"); + } + + @TestMetadata("fieldsInitializedFromParams7.java") + public void testFieldsInitializedFromParams7() throws Exception { + doTest("j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.java"); + } + @TestMetadata("genericIdentifier.java") public void testGenericIdentifier() throws Exception { doTest("j2k/tests/testData/ast/constructors/genericIdentifier.java"); diff --git a/j2k/tests/testData/ast/constructors/allCallsPrimary2.ide.kt b/j2k/tests/testData/ast/constructors/allCallsPrimary2.ide.kt index 1b1bef0f85c..c1249fd7180 100644 --- a/j2k/tests/testData/ast/constructors/allCallsPrimary2.ide.kt +++ b/j2k/tests/testData/ast/constructors/allCallsPrimary2.ide.kt @@ -1,10 +1,8 @@ -class C(arg1: Int) { - val myArg1: Int +class C(val myArg1: Int) { var myArg2: Int = 0 var myArg3: Int = 0 { - myArg1 = arg1 myArg2 = 0 myArg3 = 0 } diff --git a/j2k/tests/testData/ast/constructors/allCallsPrimary2.kt b/j2k/tests/testData/ast/constructors/allCallsPrimary2.kt index d48ebd06330..79cd9ab106d 100644 --- a/j2k/tests/testData/ast/constructors/allCallsPrimary2.kt +++ b/j2k/tests/testData/ast/constructors/allCallsPrimary2.kt @@ -1,10 +1,8 @@ -open class C(arg1: Int) { - val myArg1: Int +open class C(val myArg1: Int) { var myArg2: Int = 0 var myArg3: Int = 0 { - myArg1 = arg1 myArg2 = 0 myArg3 = 0 } diff --git a/j2k/tests/testData/ast/constructors/customerBuilder.ide.kt b/j2k/tests/testData/ast/constructors/customerBuilder.ide.kt index 204713f7bba..c417fa78bc5 100644 --- a/j2k/tests/testData/ast/constructors/customerBuilder.ide.kt +++ b/j2k/tests/testData/ast/constructors/customerBuilder.ide.kt @@ -1,8 +1,6 @@ package org.test.customer -class Customer(first: String, last: String) { - public val _firstName: String - public val _lastName: String +class Customer(public val _firstName: String, public val _lastName: String) { public fun getFirstName(): String { return _firstName @@ -19,8 +17,6 @@ class Customer(first: String, last: String) { { doSmthBefore() - _firstName = first - _lastName = last doSmthAfter() } } diff --git a/j2k/tests/testData/ast/constructors/customerBuilder.kt b/j2k/tests/testData/ast/constructors/customerBuilder.kt index 7c8fc460a0a..b109bdf1b99 100644 --- a/j2k/tests/testData/ast/constructors/customerBuilder.kt +++ b/j2k/tests/testData/ast/constructors/customerBuilder.kt @@ -1,8 +1,6 @@ package org.test.customer -open class Customer(first: String?, last: String?) { - public val _firstName: String? - public val _lastName: String? +open class Customer(public val _firstName: String?, public val _lastName: String?) { public open fun getFirstName(): String? { return _firstName @@ -19,8 +17,6 @@ open class Customer(first: String?, last: String?) { { doSmthBefore() - _firstName = first - _lastName = last doSmthAfter() } } diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.ide.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.ide.kt new file mode 100644 index 00000000000..457be03be24 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.ide.kt @@ -0,0 +1 @@ +class C(private val p1: Int, private val myP2: Int, public var p3: Int) {} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.java b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.java new file mode 100644 index 00000000000..f40d7fa457b --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.java @@ -0,0 +1,12 @@ +//file +class C { + private final int p1; + private final int myP2; + public int p3; + + public C(int p1, int p2, int p3) { + this.p1 = p1; + myP2 = p2; + this.p3 = p3; + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.kt new file mode 100644 index 00000000000..8d089c99574 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams1.kt @@ -0,0 +1 @@ +open class C(private val p1: Int, private val myP2: Int, public var p3: Int) {} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.ide.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.ide.kt new file mode 100644 index 00000000000..54787d2524d --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.ide.kt @@ -0,0 +1,5 @@ +class C(private val field: Int) { + { + System.out.println(field) + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.java b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.java new file mode 100644 index 00000000000..a9045a7d86e --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.java @@ -0,0 +1,9 @@ +//file +class C { + private final int field; + + public C(int p) { + field = p + System.out.println(p); + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.kt new file mode 100644 index 00000000000..901a2416b1f --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams2.kt @@ -0,0 +1,5 @@ +open class C(private val field: Int) { + { + System.out?.println(field) + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.ide.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.ide.kt new file mode 100644 index 00000000000..5b8b202efec --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.ide.kt @@ -0,0 +1,9 @@ +class C(p: Int) { + private val p: Int + + { + this.p = p + System.out.println(p++) + System.out.println(p) + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.java b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.java new file mode 100644 index 00000000000..91e78c15041 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.java @@ -0,0 +1,10 @@ +//file +class C { + private final int p; + + public C(int p) { + this.p = p + System.out.println(p++); + System.out.println(p); + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.kt new file mode 100644 index 00000000000..a00f267b501 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams3.kt @@ -0,0 +1,9 @@ +open class C(p: Int) { + private val p: Int + + { + this.p = p + System.out?.println(p++) + System.out?.println(p) + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.ide.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.ide.kt new file mode 100644 index 00000000000..c336b8fd060 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.ide.kt @@ -0,0 +1,7 @@ +class C(p: Int, c: C) { + public var p: Int = 0 + + { + c.p = p + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.java b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.java new file mode 100644 index 00000000000..a4f252e6ab7 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.java @@ -0,0 +1,8 @@ +//file +class C { + public int p; + + public C(int p, C c) { + c.p = p; + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.kt new file mode 100644 index 00000000000..10d99447c01 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams4.kt @@ -0,0 +1,7 @@ +open class C(p: Int, c: C?) { + public var p: Int = 0 + + { + c?.p = p + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.ide.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.ide.kt new file mode 100644 index 00000000000..072f16f3bf5 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.ide.kt @@ -0,0 +1,10 @@ +class C(p: Int) { + public var p: Int = 0 + + { + this.p = 0 + if (p > 0) { + this.p = p + } + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.java b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.java new file mode 100644 index 00000000000..bd361f9f23d --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.java @@ -0,0 +1,11 @@ +//file +class C { + public int p; + + public C(int p) { + this.p = 0 + if (p > 0) { + this.p = p + } + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.kt new file mode 100644 index 00000000000..92b3c24279b --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams5.kt @@ -0,0 +1,10 @@ +open class C(p: Int) { + public var p: Int = 0 + + { + this.p = 0 + if (p > 0) { + this.p = p + } + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.ide.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.ide.kt new file mode 100644 index 00000000000..2e85a74b122 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.ide.kt @@ -0,0 +1,7 @@ +class C(x: String) { + public var x: Any = 0 + + { + this.x = x + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.java b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.java new file mode 100644 index 00000000000..8727c3e26fe --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.java @@ -0,0 +1,8 @@ +//file +class C { + public Object x; + + public C(String x) { + this.x = x; + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.kt new file mode 100644 index 00000000000..bbb7b9e039e --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams6.kt @@ -0,0 +1,7 @@ +open class C(x: String?) { + public var x: Any? = null + + { + this.x = x + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.ide.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.ide.kt new file mode 100644 index 00000000000..1da370ef9b5 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.ide.kt @@ -0,0 +1,9 @@ +class C(x: Any, b: Boolean) { + public var x: Any = 0 + + { + if (b) { + this.x = x + } + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.java b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.java new file mode 100644 index 00000000000..c28829ef740 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.java @@ -0,0 +1,10 @@ +//file +class C { + public Object x; + + public C(Object x, boolean b) { + if (b) { + this.x = x; + } + } +} diff --git a/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.kt b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.kt new file mode 100644 index 00000000000..ba5c0dfd872 --- /dev/null +++ b/j2k/tests/testData/ast/constructors/fieldsInitializedFromParams7.kt @@ -0,0 +1,9 @@ +open class C(x: Any?, b: Boolean) { + public var x: Any? = null + + { + if (b) { + this.x = x + } + } +} diff --git a/j2k/tests/testData/ast/enum/colorEnum.ide.kt b/j2k/tests/testData/ast/enum/colorEnum.ide.kt index 95287f39598..4195c79f8e9 100644 --- a/j2k/tests/testData/ast/enum/colorEnum.ide.kt +++ b/j2k/tests/testData/ast/enum/colorEnum.ide.kt @@ -1,16 +1,10 @@ package demo -enum class MyEnum(_color: Int) { +enum class MyEnum(private val color: Int) { RED : MyEnum(10) BLUE : MyEnum(20) - private val color: Int - public fun getColor(): Int { return color } - - { - color = _color - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/enum/colorEnum.kt b/j2k/tests/testData/ast/enum/colorEnum.kt index 95287f39598..4195c79f8e9 100644 --- a/j2k/tests/testData/ast/enum/colorEnum.kt +++ b/j2k/tests/testData/ast/enum/colorEnum.kt @@ -1,16 +1,10 @@ package demo -enum class MyEnum(_color: Int) { +enum class MyEnum(private val color: Int) { RED : MyEnum(10) BLUE : MyEnum(20) - private val color: Int - public fun getColor(): Int { return color } - - { - color = _color - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.ide.kt b/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.ide.kt index 3cfe7700f2d..e49992d812f 100644 --- a/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.ide.kt +++ b/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.ide.kt @@ -1,17 +1,11 @@ -enum class Color(c: Int) { +enum class Color(private var code: Int) { WHITE : Color(21) BLACK : Color(22) RED : Color(23) YELLOW : Color(24) BLUE : Color(25) - private var code: Int = 0 - public fun getCode(): Int { return code } - - { - code = c - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.java b/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.java index c2f2c98bcb4..243f7e55bd4 100644 --- a/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.java +++ b/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.java @@ -1,13 +1,14 @@ //class enum Color { - WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25); + WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25); - private int code; + private int code; - private Color(int c) { - code = c; - } + private Color(int c) { + code = c; + } - public int getCode() { - return code; - } \ No newline at end of file + public int getCode() { + return code; + } +} \ 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 3cfe7700f2d..e49992d812f 100644 --- a/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.kt +++ b/j2k/tests/testData/ast/enum/fieldsWithPrimaryPrivateConstructor.kt @@ -1,17 +1,11 @@ -enum class Color(c: Int) { +enum class Color(private var code: Int) { WHITE : Color(21) BLACK : Color(22) RED : Color(23) YELLOW : Color(24) BLUE : Color(25) - private var code: Int = 0 - public fun getCode(): Int { return code } - - { - code = c - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/enum/primaryPrivateConstructor.ide.kt b/j2k/tests/testData/ast/enum/primaryPrivateConstructor.ide.kt index 18e22a93922..6fe0bbffb12 100644 --- a/j2k/tests/testData/ast/enum/primaryPrivateConstructor.ide.kt +++ b/j2k/tests/testData/ast/enum/primaryPrivateConstructor.ide.kt @@ -1,13 +1,8 @@ package demo -enum class Color(c: Int) { - private var code: Int = 0 +enum class Color(private var code: Int) { public fun getCode(): Int { return code } - - { - code = c - } } \ 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 18e22a93922..6fe0bbffb12 100644 --- a/j2k/tests/testData/ast/enum/primaryPrivateConstructor.kt +++ b/j2k/tests/testData/ast/enum/primaryPrivateConstructor.kt @@ -1,13 +1,8 @@ package demo -enum class Color(c: Int) { - private var code: Int = 0 +enum class Color(private var code: Int) { public fun getCode(): Int { return code } - - { - code = c - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/function/varVararg.ide.kt b/j2k/tests/testData/ast/function/varVararg.ide.kt index 7f95d27628b..ed47bc9b46a 100644 --- a/j2k/tests/testData/ast/function/varVararg.ide.kt +++ b/j2k/tests/testData/ast/function/varVararg.ide.kt @@ -1,7 +1,7 @@ package demo class Test() { - fun test(vararg var args: Any) { + fun test(vararg args: Any) { args = array(1, 2, 3) } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/function/varVararg.kt b/j2k/tests/testData/ast/function/varVararg.kt index 4cd8dcdf16b..7358fce42e3 100644 --- a/j2k/tests/testData/ast/function/varVararg.kt +++ b/j2k/tests/testData/ast/function/varVararg.kt @@ -1,7 +1,7 @@ package demo open class Test() { - open fun test(vararg var args: Any?) { + open fun test(vararg args: Any?) { args = array(1, 2, 3) } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/function/writableParameter.ide.kt b/j2k/tests/testData/ast/function/writableParameter.ide.kt index 0e7f5d54eb6..d4bd2c26442 100644 --- a/j2k/tests/testData/ast/function/writableParameter.ide.kt +++ b/j2k/tests/testData/ast/function/writableParameter.ide.kt @@ -1,7 +1,7 @@ package demo class Test() { - fun test(var i: Int): Int { + fun test(i: Int): Int { i = 10 return i + 20 } diff --git a/j2k/tests/testData/ast/function/writableParameter.kt b/j2k/tests/testData/ast/function/writableParameter.kt index a05f287437f..dd84d1d238c 100644 --- a/j2k/tests/testData/ast/function/writableParameter.kt +++ b/j2k/tests/testData/ast/function/writableParameter.kt @@ -1,7 +1,7 @@ package demo open class Test() { - open fun test(var i: Int): Int { + open fun test(i: Int): Int { i = 10 return i + 20 } diff --git a/j2k/tests/testData/ast/identifier/finalFieldReference.ide.kt b/j2k/tests/testData/ast/identifier/finalFieldReference.ide.kt index 0f5061f72e7..75f6cfc49a4 100644 --- a/j2k/tests/testData/ast/identifier/finalFieldReference.ide.kt +++ b/j2k/tests/testData/ast/identifier/finalFieldReference.ide.kt @@ -2,14 +2,9 @@ class `$$$$$`() {} class `$`() {} -class `$$`(`$$$$`: `$$$$$`) : `$`() { - val `$$$`: `$$$$$` +class `$$`(val `$$$`: `$$$$$`) : `$`() { public fun `$$$$$$`(): `$$$$$` { return `$$$` } - - { - `$$$` = `$$$$` - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/identifier/finalFieldReference.kt b/j2k/tests/testData/ast/identifier/finalFieldReference.kt index 6919d913d51..4bb37c24e2f 100644 --- a/j2k/tests/testData/ast/identifier/finalFieldReference.kt +++ b/j2k/tests/testData/ast/identifier/finalFieldReference.kt @@ -2,14 +2,9 @@ open class `$$$$$`() {} open class `$`() {} -open class `$$`(`$$$$`: `$$$$$`?) : `$`() { - val `$$$`: `$$$$$`? +open class `$$`(val `$$$`: `$$$$$`?) : `$`() { public open fun `$$$$$$`(): `$$$$$`? { return `$$$` } - - { - `$$$` = `$$$$` - } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.ide.kt b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.ide.kt index c9b0de82178..8bb90366868 100644 --- a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.ide.kt +++ b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.ide.kt @@ -1,9 +1,3 @@ class Base(name: T) {} -class One(name: T, second: K) : Base(name) { - private var mySecond: K = 0 - - { - mySecond = second - } -} \ No newline at end of file +class One(name: T, private var mySecond: K) : Base(name) {} \ No newline at end of file diff --git a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.kt b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.kt index 04c8337df2b..78cd3648e21 100644 --- a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.kt +++ b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseGeneric.kt @@ -1,9 +1,3 @@ open class Base(name: T?) {} -open class One(name: T?, second: K?) : Base(name) { - private var mySecond: K? = null - - { - mySecond = second - } -} \ No newline at end of file +open class One(name: T?, private var mySecond: K?) : Base(name) {} \ No newline at end of file diff --git a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.ide.kt b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.ide.kt index d04f443b2e5..448ce96a267 100644 --- a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.ide.kt +++ b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.ide.kt @@ -1,9 +1,3 @@ class Base(name: String) {} -class One(name: String, second: String) : Base(name) { - private var mySecond: String = 0 - - { - mySecond = second - } -} \ No newline at end of file +class One(name: String, private var mySecond: String) : Base(name) {} \ No newline at end of file diff --git a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.kt b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.kt index 8d89712b956..b6feea16b48 100644 --- a/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.kt +++ b/j2k/tests/testData/ast/inheritance/classOneExtendsBaseWithZeroParamsNonEmptyConstructor.kt @@ -1,9 +1,3 @@ open class Base(name: String?) {} -open class One(name: String?, second: String?) : Base(name) { - private var mySecond: String? = null - - { - mySecond = second - } -} \ No newline at end of file +open class One(name: String?, private var mySecond: String?) : Base(name) {} \ No newline at end of file diff --git a/j2k/tests/testData/ast/issues/kt-1016.ide.kt b/j2k/tests/testData/ast/issues/kt-1016.ide.kt index 456bd25872d..e4f0cd5ae63 100644 --- a/j2k/tests/testData/ast/issues/kt-1016.ide.kt +++ b/j2k/tests/testData/ast/issues/kt-1016.ide.kt @@ -1,9 +1,3 @@ package demo -class C(i: Int) { - private val i: Int - - { - this.i = i - } -} \ No newline at end of file +class C(private val i: Int) {} \ No newline at end of file diff --git a/j2k/tests/testData/ast/issues/kt-1016.kt b/j2k/tests/testData/ast/issues/kt-1016.kt index b339041eee8..72ccceee641 100644 --- a/j2k/tests/testData/ast/issues/kt-1016.kt +++ b/j2k/tests/testData/ast/issues/kt-1016.kt @@ -1,9 +1,3 @@ package demo -open class C(i: Int) { - private val i: Int - - { - this.i = i - } -} \ No newline at end of file +open class C(private val i: Int) {} \ No newline at end of file diff --git a/j2k/tests/testData/ast/issues/kt-836.ide.kt b/j2k/tests/testData/ast/issues/kt-836.ide.kt index f40b1d8b173..c500ce38d60 100644 --- a/j2k/tests/testData/ast/issues/kt-836.ide.kt +++ b/j2k/tests/testData/ast/issues/kt-836.ide.kt @@ -2,16 +2,11 @@ package com.voltvoodoo.saplo4j.model import java.io.Serializable -public class Language(code: String) : Serializable { - protected var code: String = 0 +public class Language(protected var code: String) : Serializable { override fun toString(): String { return this.code } - - { - this.code = code - } } diff --git a/j2k/tests/testData/ast/issues/kt-836.kt b/j2k/tests/testData/ast/issues/kt-836.kt index c36bb16c8d7..07d5cc1539d 100644 --- a/j2k/tests/testData/ast/issues/kt-836.kt +++ b/j2k/tests/testData/ast/issues/kt-836.kt @@ -2,16 +2,11 @@ package com.voltvoodoo.saplo4j.model import java.io.Serializable -public open class Language(code: String?) : Serializable { - protected var code: String? = null +public open class Language(protected var code: String?) : Serializable { override fun toString(): String? { return this.code } - - { - this.code = code - } } diff --git a/j2k/tests/testData/ast/issues/kt-837.ide.kt b/j2k/tests/testData/ast/issues/kt-837.ide.kt index 1e7e085ad2c..ca2b9991a51 100644 --- a/j2k/tests/testData/ast/issues/kt-837.ide.kt +++ b/j2k/tests/testData/ast/issues/kt-837.ide.kt @@ -2,21 +2,16 @@ package com.voltvoodoo.saplo4j.model import java.io.Serializable -public class Language(code: String) : Serializable { - - protected var code: String = 0 +public class Language(protected var code: String) : Serializable { public fun equals(other: Language): Boolean { return other.toString().equals(this.toString()) } - { - this.code = code - } - class object { public var ENGLISH: Language = Language("en") public var SWEDISH: Language = Language("sv") + private val serialVersionUID: Long = -2442762969929206780 } } \ No newline at end of file diff --git a/j2k/tests/testData/ast/issues/kt-837.kt b/j2k/tests/testData/ast/issues/kt-837.kt index 17219cffb16..f42da3f5162 100644 --- a/j2k/tests/testData/ast/issues/kt-837.kt +++ b/j2k/tests/testData/ast/issues/kt-837.kt @@ -2,21 +2,16 @@ package com.voltvoodoo.saplo4j.model import java.io.Serializable -public open class Language(code: String?) : Serializable { - - protected var code: String? = null +public open class Language(protected var code: String?) : Serializable { public open fun equals(other: Language?): Boolean { return other?.toString()?.equals(this.toString())!! } - { - this.code = code - } - class object { public var ENGLISH: Language? = Language("en") public var SWEDISH: Language? = Language("sv") + private val serialVersionUID: Long = -2442762969929206780 } } \ No newline at end of file