Java to Kotlin convertor: generating of val/var constructor parameters when possible

This commit is contained in:
Valentin Kipyatkov
2014-06-02 22:03:33 +04:00
parent 846f2d9954
commit abfd2d68b9
90 changed files with 820 additions and 734 deletions
@@ -23,6 +23,14 @@ import com.intellij.psi.JavaRecursiveElementVisitor
import java.util.LinkedHashSet import java.util.LinkedHashSet
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethodCallExpression 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 { fun PsiMethod.isPrimaryConstructor(): Boolean {
if (!isConstructor()) return false if (!isConstructor()) return false
@@ -63,11 +71,11 @@ fun PsiClass.getPrimaryConstructor(): PsiMethod? {
} }
} }
fun isInsidePrimaryConstructor(element: PsiElement): Boolean fun PsiElement.isInsidePrimaryConstructor(): Boolean
= getContainingConstructor(element)?.isPrimaryConstructor() ?: false = getContainingConstructor()?.isPrimaryConstructor() ?: false
fun getContainingConstructor(element: PsiElement): PsiMethod? { fun PsiElement.getContainingConstructor(): PsiMethod? {
var context = element.getContext() var context = getContext()
while (context != null) { while (context != null) {
val _context = context!! val _context = context!!
if (_context is PsiMethod) { if (_context is PsiMethod) {
@@ -90,3 +98,4 @@ fun PsiMethodCallExpression.isSuperConstructorCall(): Boolean {
fun PsiReferenceExpression.isThisConstructorCall(): Boolean fun PsiReferenceExpression.isThisConstructorCall(): Boolean
= getReferences().filter { it.getCanonicalText() == "this" }.map { it.resolve() }.any { it is PsiMethod && it.isConstructor() } = getReferences().filter { it.getCanonicalText() == "this" }.map { it.resolve() }.any { it is PsiMethod && it.isConstructor() }
+166 -91
View File
@@ -18,14 +18,12 @@ package org.jetbrains.jet.j2k
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.jet.j2k.ast.* 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 org.jetbrains.jet.j2k.visitors.*
import java.util.* import java.util.*
import com.intellij.psi.CommonClassNames.* import com.intellij.psi.CommonClassNames.*
import org.jetbrains.jet.lang.types.expressions.OperatorConventions.* import org.jetbrains.jet.lang.types.expressions.OperatorConventions.*
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.util.PsiUtil
public class Converter(val project: Project, val settings: ConverterSettings) { 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) { private fun convertTopElement(element: PsiElement?): Element? = when(element) {
is PsiJavaFile -> convertFile(element) is PsiJavaFile -> convertFile(element)
is PsiClass -> convertClass(element) is PsiClass -> convertClass(element)
is PsiMethod -> convertMethod(element) is PsiMethod -> convertMethod(element, HashSet())
is PsiField -> convertField(element) is PsiField -> convertField(element)
is PsiStatement -> convertStatement(element) is PsiStatement -> convertStatement(element)
is PsiExpression -> convertExpression(element) is PsiExpression -> convertExpression(element)
@@ -72,13 +70,29 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
} }
public fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass { public fun convertAnonymousClass(anonymousClass: PsiAnonymousClass): AnonymousClass {
return AnonymousClass(this, convertMembers(anonymousClass)) return AnonymousClass(this, convertClassBody(anonymousClass))
} }
private fun convertMembers(psiClass: PsiClass): List<Element> { private fun convertClassBody(psiClass: PsiClass): List<Element> {
val allChildren = psiClass.getChildren().toList() val membersToRemove = HashSet<PsiMember>()
val lBraceIndex = allChildren.indexOf(psiClass.getLBrace()) val convertedMembers = LinkedHashMap<PsiElement, Element>()
return allChildren.subList(lBraceIndex, allChildren.size).map { convertMember(it) }.filterNotNull() 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<PsiMember>): 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 { private fun getComments(member: PsiMember): MemberComments {
@@ -93,39 +107,31 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
return MemberComments(whiteSpacesAndComments) 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 { private fun convertClass(psiClass: PsiClass): Class {
val modifiers = convertModifierList(psiClass.getModifierList()) val modifiers = convertModifierList(psiClass.getModifierList())
val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList()) val typeParameters = convertTypeParameterList(psiClass.getTypeParameterList())
val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes()) val implementsTypes = convertToNotNullableTypes(psiClass.getImplementsListTypes())
val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes()) val extendsTypes = convertToNotNullableTypes(psiClass.getExtendsListTypes())
val name = Identifier(psiClass.getName()!!) val name = Identifier(psiClass.getName()!!)
val members = ArrayList(convertMembers(psiClass)) val classBodyElements = ArrayList(convertClassBody(psiClass))
when { 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 -> { else -> {
if (psiClass.getConstructors().size > 1 && psiClass.getPrimaryConstructor() == null) { if (psiClass.getPrimaryConstructor() == null && psiClass.getConstructors().size > 1) {
val finalOrWithEmptyInitializerFields = members.filterIsInstance(javaClass<Field>()).filter { it.isVal() || it.initializer.toKotlin().isEmpty() } val finalOrWithEmptyInitializerFields = classBodyElements.filterIsInstance(javaClass<Field>()).filter { it.isVal() || it.initializer.toKotlin().isEmpty() }
val initializers = HashMap<String, String>() val initializers = HashMap<String, String>()
for (member in members) { for (element in classBodyElements) {
if (member is Constructor && !member.isPrimary) { if (element is SecondaryConstructor) {
for (field in finalOrWithEmptyInitializerFields) { for (field in finalOrWithEmptyInitializerFields) {
initializers.put(field.identifier.toKotlin(), getDefaultInitializer(field)) initializers.put(field.identifier.toKotlin(), getDefaultInitializer(field))
} }
val newStatements = ArrayList<Statement>() val newStatements = ArrayList<Statement>()
for (statement in member.block!!.statements) { for (statement in element.block!!.statements) {
var keepStatement = true var keepStatement = true
if (statement is AssignmentExpression) { if (statement is AssignmentExpression) {
val assignee = statement.left 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))) newStatements.add(0, DummyStringExpression("val __ = " + createPrimaryConstructorInvocation(name.toKotlin(), finalOrWithEmptyInitializerFields, initializers)))
member.block = Block(newStatements) element.block = Block(newStatements)
} }
} }
//TODO: comments? //TODO: comments?
members.add(Constructor(this, Identifier.Empty, MemberComments.Empty, Collections.emptySet<Modifier>(), val parameters = finalOrWithEmptyInitializerFields.map { Parameter(Identifier("_" + it.identifier.name), it.`type`, Parameter.VarValModifier.None, listOf()) }
ClassType(name, listOf(), false, this), classBodyElements.add(PrimaryConstructor(this, MemberComments.Empty, Collections.emptySet<Modifier>(),
TypeParameterList.Empty, ParameterList(parameters),
ParameterList(createParametersFromFields(finalOrWithEmptyInitializerFields)), Block(createInitStatementsFromFields(finalOrWithEmptyInitializerFields))))
Block(createInitStatementsFromFields(finalOrWithEmptyInitializerFields)),
true))
} }
val baseClassParams: List<Expression> = run { val baseClassParams: List<Expression> = 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<PsiField, PsiStatement>? {
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 { 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 { private fun convertField(field: PsiField): Field {
@@ -192,9 +226,9 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
convertElement(field.getArgumentList())) convertElement(field.getArgumentList()))
} }
var kType = convertType(field.getType(), field.isAnnotatedAsNotNull()) var kType = convertVariableType(field)
if (field.hasModifierProperty(PsiModifier.FINAL) && field.getInitializer().isDefinitelyNotNull()) { if (field.hasModifierProperty(PsiModifier.FINAL) && field.getInitializer().isDefinitelyNotNull()) {
kType = kType.convertedToNotNull(); kType = kType.toNotNullType();
} }
return Field(Identifier(field.getName()!!), return Field(Identifier(field.getName()!!),
@@ -205,60 +239,97 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
field.countWriteAccesses(field.getContainingClass())) field.countWriteAccesses(field.getContainingClass()))
} }
private fun convertMethod(method: PsiMethod): Function { private fun convertMethod(method: PsiMethod, membersToRemove: MutableSet<PsiMember>): Function {
return convertMethod(method, true)
}
private fun convertMethod(method: PsiMethod, notEmpty: Boolean): Function {
if (directlyOverridesMethodFromObject(method)) { if (directlyOverridesMethodFromObject(method)) {
dispatcher.expressionVisitor = ExpressionVisitorForDirectObjectInheritors(this) dispatcher.expressionVisitor = ExpressionVisitorForDirectObjectInheritors(this)
} }
else { else {
dispatcher.expressionVisitor = ExpressionVisitor(this) 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) try {
val typeParameterList = convertTypeParameterList(method.getTypeParameterList()) methodReturnType = method.getReturnType()
val modifiers = HashSet(convertModifierList(method.getModifierList())) val returnType = convertType(method.getReturnType(), method.isAnnotatedAsNotNull())
if (isOverride(method)) {
modifiers.add(Modifier.OVERRIDE) 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<PsiParameter, PsiField>()
val body = method.getBody()
val block = if (body != null) {
val statementsToRemove = HashSet<PsiStatement>()
val usageReplacementMap = HashMap<PsiVariable, String>()
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)
}
} }
finally {
val containingClass = method.getContainingClass() dispatcher.expressionVisitor = ExpressionVisitor(this)
if (containingClass != null && containingClass.isInterface()) {
modifiers.remove(Modifier.ABSTRACT)
} }
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 { public fun convertBlock(block: PsiCodeBlock?): Block {
val result = ArrayList<Parameter>()
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 {
if (block == null) return Block.Empty 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<PsiElement>): StatementList { public fun convertStatements(statements: List<PsiElement>): StatementList {
@@ -302,13 +373,13 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
public fun convertTypeElement(element: PsiTypeElement?): TypeElement { public fun convertTypeElement(element: PsiTypeElement?): TypeElement {
return TypeElement(if (element == null) return TypeElement(if (element == null)
EmptyType() Type.Empty
else else
convertType(element.getType())) convertType(element.getType()))
} }
public fun convertType(`type`: PsiType?): Type { public fun convertType(`type`: PsiType?): Type {
if (`type` == null) return EmptyType() if (`type` == null) return Type.Empty
return `type`.accept<Type>(TypeVisitor(this))!! return `type`.accept<Type>(TypeVisitor(this))!!
} }
@@ -320,22 +391,30 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
public fun convertType(`type`: PsiType?, notNull: Boolean): Type { public fun convertType(`type`: PsiType?, notNull: Boolean): Type {
val result = convertType(`type`) val result = convertType(`type`)
if (notNull) { if (notNull) {
return result.convertedToNotNull() return result.toNotNullType()
} }
return result return result
} }
public fun convertVariableType(variable: PsiVariable): Type
= convertType(variable.getType(), variable.isAnnotatedAsNotNull())
private fun convertToNotNullableTypes(types: Array<out PsiType?>): List<Type> private fun convertToNotNullableTypes(types: Array<out PsiType?>): List<Type>
= types.map { convertType(it).convertedToNotNull() } = types.map { convertType(it).toNotNullType() }
public fun convertParameterList(parameters: Array<PsiParameter>): List<Parameter> public fun convertParameterList(parameters: PsiParameterList): ParameterList
= parameters.map { convertParameter(it) } = ParameterList(parameters.getParameters().map { convertParameter(it) })
public fun convertParameter(parameter: PsiParameter, forceNotNull: Boolean = false): Parameter { public fun convertParameter(parameter: PsiParameter,
return Parameter(Identifier(parameter.getName()!!), forceNotNull: Boolean = false,
convertType(parameter.getType(), varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None,
forceNotNull || parameter.isAnnotatedAsNotNull()), true) modifiers: Collection<Modifier> = 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<Expression> { public fun convertArguments(expression: PsiCallExpression): List<Expression> {
@@ -380,10 +459,6 @@ public class Converter(val project: Project, val settings: ConverterSettings) {
return expression return expression
} }
private fun createParametersFromFields(fields: List<Field>): List<Parameter> {
return fields.map { Parameter(Identifier("_" + it.identifier.name), it.`type`, true) }
}
private fun createInitStatementsFromFields(fields: List<Field>): List<Statement> { private fun createInitStatementsFromFields(fields: List<Field>): List<Statement> {
val result = ArrayList<Statement>() val result = ArrayList<Statement>()
for (field in fields) { for (field in fields) {
+23 -10
View File
@@ -24,26 +24,34 @@ import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiNewExpression import com.intellij.psi.PsiNewExpression
import org.jetbrains.jet.j2k.ast.Field import org.jetbrains.jet.j2k.ast.Field
import org.jetbrains.jet.lang.types.expressions.OperatorConventions import org.jetbrains.jet.lang.types.expressions.OperatorConventions
import com.intellij.psi.util.PsiUtil
import com.intellij.psi.PsiModifierListOwner 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 quoteKeywords(packageName: String): String = packageName.split("\\.").map { Identifier(it).toKotlin() }.makeString(".")
fun PsiElement.countWriteAccesses(scope: PsiElement?): Int { fun findExpressionReferences(element: PsiElement, scope: PsiElement): Collection<PsiReferenceExpression> {
if (scope == null) return 0 class Visitor : JavaRecursiveElementVisitor() {
val refs = ArrayList<PsiReferenceExpression>()
var writes = 0
scope.accept(object: JavaRecursiveElementVisitor() {
override fun visitReferenceExpression(expression: PsiReferenceExpression) { override fun visitReferenceExpression(expression: PsiReferenceExpression) {
super.visitReferenceExpression(expression) super.visitReferenceExpression(expression)
if (PsiUtil.isAccessedForWriting(expression) && expression.isReferenceTo(this@countWriteAccesses)) { if (expression.isReferenceTo(element)) {
writes++ 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 fun PsiModifierListOwner.isAnnotatedAsNotNull(): Boolean
= getModifierList()?.getAnnotations()?.any { NOT_NULL_ANNOTATIONS.contains(it.getQualifiedName()) } ?: false = getModifierList()?.getAnnotations()?.any { NOT_NULL_ANNOTATIONS.contains(it.getQualifiedName()) } ?: false
@@ -66,4 +74,9 @@ fun getDefaultInitializer(field: Field): String {
else -> "0" else -> "0"
} }
} }
} }
fun isQualifierEmptyOrThis(ref: PsiReferenceExpression): Boolean {
val qualifier = ref.getQualifierExpression()
return qualifier == null || (qualifier is PsiThisExpression && qualifier.getQualifier() == null)
}
@@ -17,10 +17,9 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import org.jetbrains.jet.j2k.ast.types.Type
import java.util.Collections import java.util.Collections
class AnonymousClass(converter: Converter, members: List<Element>) class AnonymousClass(converter: Converter, bodyElements: List<Element>)
: Class(converter, : Class(converter,
Identifier("anonClass"), Identifier("anonClass"),
MemberComments.Empty, MemberComments.Empty,
@@ -29,6 +28,6 @@ class AnonymousClass(converter: Converter, members: List<Element>)
listOf(), listOf(),
listOf(), listOf(),
listOf(), listOf(),
members) { bodyElements) {
override fun toKotlin() = bodyToKotlin() override fun toKotlin() = bodyToKotlin()
} }
@@ -17,8 +17,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.lang.types.expressions.OperatorConventions 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>) : Expression() { open class ArrayInitializerExpression(val arrayType: ArrayType, val initializers: List<Expression>) : Expression() {
override fun toKotlin(): String { override fun toKotlin(): String {
@@ -32,14 +30,14 @@ open class ArrayInitializerExpression(val arrayType: ArrayType, val initializers
private fun createArrayFunction(): String { private fun createArrayFunction(): String {
val elementType = arrayType.elementType val elementType = arrayType.elementType
if (elementType.isPrimitive()) { 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 { private fun innerTypeStr(): String {
return arrayType.convertedToNotNull().toKotlin().replace("Array", "").toLowerCase() return arrayType.toNotNullType().toKotlin().replace("Array", "").toLowerCase()
} }
private fun explicitConvertIfNeeded(i: Expression): String { private fun explicitConvertIfNeeded(i: Expression): String {
@@ -16,10 +16,6 @@
package org.jetbrains.jet.j2k.ast 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>) : Expression() { open class ArrayWithoutInitializationExpression(val `type`: Type, val expressions: List<Expression>) : Expression() {
override fun toKotlin(): String { override fun toKotlin(): String {
if (`type` is ArrayType) { if (`type` is ArrayType) {
@@ -55,17 +51,17 @@ open class ArrayWithoutInitializationExpression(val `type`: Type, val expression
return if (`type` is ArrayType) return if (`type` is ArrayType)
when (`type`.elementType) { when (`type`.elementType) {
is PrimitiveType -> is PrimitiveType ->
`type`.convertedToNotNull().toKotlin() `type`.toNotNullType().toKotlin()
is ArrayType -> is ArrayType ->
if (hasInit) if (hasInit)
`type`.convertedToNotNull().toKotlin() `type`.toNotNullType().toKotlin()
else else
"arrayOfNulls<" + `type`.elementType.toKotlin() + ">" "arrayOfNulls<" + `type`.elementType.toKotlin() + ">"
else -> else ->
"arrayOfNulls<" + `type`.elementType.toKotlin() + ">" "arrayOfNulls<" + `type`.elementType.toKotlin() + ">"
} }
else else
`type`.convertedToNotNull().toKotlin() `type`.toNotNullType().toKotlin()
} }
} }
} }
+35 -45
View File
@@ -17,8 +17,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter 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.HashSet
import java.util.ArrayList import java.util.ArrayList
@@ -31,53 +29,50 @@ open class Class(
val extendsTypes: List<Type>, val extendsTypes: List<Type>,
val baseClassParams: List<Expression>, val baseClassParams: List<Expression>,
val implementsTypes: List<Type>, val implementsTypes: List<Type>,
val members: List<Element> val bodyElements: List<Element>
) : Member(comments, modifiers) { ) : 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" 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 val constructor = classMembers.primaryConstructor
return if (constructor != null) constructor.primarySignatureToKotlin() else "()" return if (constructor != null) constructor.signatureToKotlin() else "()"
} }
fun primaryConstructorBodyToKotlin(): String? { protected fun primaryConstructorBodyToKotlin(): String {
val maybeConstructor = classMembers.primaryConstructor val constructor = classMembers.primaryConstructor
if (maybeConstructor != null && !(maybeConstructor.block?.isEmpty ?: true)) { if (constructor != null && !(constructor.block?.isEmpty ?: true)) {
return "\n" + maybeConstructor.primaryBodyToKotlin() + "\n" return "\n" + constructor.bodyToKotlin() + "\n"
} }
return "" return ""
} }
fun secondaryConstructorsAsStaticInitFunctions(): MemberList { private fun secondaryConstructorsAsStaticInitFunctions(): MemberList {
return MemberList(classMembers.secondaryConstructors.elements.map { if (it is Constructor) constructorToInit(it) else it }) return MemberList(classMembers.secondaryConstructors.elements.map { if (it is SecondaryConstructor) it.toInitFunction(this) else it })
} }
private fun constructorToInit(f: Function): Function { private fun baseClassSignatureWithParams(): List<String> {
val modifiers = HashSet<Modifier>(f.modifiers) if (keyword.equals("class") && extendsTypes.size() == 1) {
modifiers.add(Modifier.STATIC)
val statements = ArrayList(f.block?.statements ?: ArrayList())
statements.add(ReturnStatement(Identifier("__")))
val block = Block(statements)
val constructorTypeParameters = ArrayList<TypeParameter>()
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<String> {
if (TYPE.equals("class") && extendsTypes.size() == 1) {
val baseParams = baseClassParams.toKotlin(", ") val baseParams = baseClassParams.toKotlin(", ")
return arrayListOf(extendsTypes[0].toKotlin() + "(" + baseParams + ")") return arrayListOf(extendsTypes[0].toKotlin() + "(" + baseParams + ")")
} }
return extendsTypes.map { it.toKotlin() } return extendsTypes.map { it.toKotlin() }
} }
fun implementTypesToKotlin(): String { protected fun implementTypesToKotlin(): String {
val allTypes = ArrayList<String>() val allTypes = ArrayList<String>()
allTypes.addAll(baseClassSignatureWithParams()) allTypes.addAll(baseClassSignatureWithParams())
allTypes.addAll(implementsTypes.map { it.toKotlin() }) allTypes.addAll(implementsTypes.map { it.toKotlin() })
@@ -87,9 +82,9 @@ open class Class(
" : " + allTypes.makeString(", ") " : " + allTypes.makeString(", ")
} }
fun modifiersToKotlin(): String { protected fun modifiersToKotlin(): String {
val modifierList = ArrayList<Modifier>() val modifierList = ArrayList<Modifier>()
val modifier = accessModifier() val modifier = modifiers.accessModifier()
if (modifier != null) { if (modifier != null) {
modifierList.add(modifier) modifierList.add(modifier)
} }
@@ -102,15 +97,20 @@ open class Class(
return modifierList.toKotlin() 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 { fun bodyToKotlin(): String {
return " {" + classMembers.nonStaticMembers.toKotlin() + primaryConstructorBodyToKotlin() + classObjectToKotlin() + "}" 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 secondaryConstructorsAsStaticInitFunctions = secondaryConstructorsAsStaticInitFunctions()
val staticMembers = classMembers.staticMembers val staticMembers = classMembers.staticMembers
if (secondaryConstructorsAsStaticInitFunctions.isEmpty() && staticMembers.isEmpty()) { if (secondaryConstructorsAsStaticInitFunctions.isEmpty() && staticMembers.isEmpty()) {
@@ -118,14 +118,4 @@ open class Class(
} }
return "\nclass object {${secondaryConstructorsAsStaticInitFunctions.toKotlin()}${staticMembers.toKotlin()}}" return "\nclass object {${secondaryConstructorsAsStaticInitFunctions.toKotlin()}${staticMembers.toKotlin()}}"
} }
override fun toKotlin(): String =
commentsToKotlin() +
modifiersToKotlin() +
TYPE + " " + name.toKotlin() +
typeParameterList.toKotlin() +
primaryConstructorSignatureToKotlin() +
implementTypesToKotlin() +
typeParameterList.whereToKotlin().withPrefix(" ") +
bodyToKotlin()
} }
@@ -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<Modifier>,
`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()
}
}
@@ -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<Modifier>,
parameterList: ParameterList,
block: Block
) : Function(converter, Identifier.Empty, comments, modifiers, Type.Empty, TypeParameterList.Empty, parameterList, block)
class PrimaryConstructor(converter: Converter,
comments: MemberComments,
modifiers: Set<Modifier>,
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<Modifier>,
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<TypeParameter>()
typeParameters.addAll(containingClass.typeParameterList.parameters)
return Function(converter, Identifier("init"), MemberComments.Empty, modifiers,
ClassType(containingClass.name, typeParameters, false, converter),
TypeParameterList(typeParameters), parameterList, block)
}
}
+2 -3
View File
@@ -17,7 +17,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import org.jetbrains.jet.j2k.ast.types.Type
class Enum( class Enum(
converter: Converter, converter: Converter,
@@ -28,9 +27,9 @@ class Enum(
extendsTypes: List<Type>, extendsTypes: List<Type>,
baseClassParams: List<Expression>, baseClassParams: List<Expression>,
implementsTypes: List<Type>, implementsTypes: List<Type>,
members: List<Element> bodyElements: List<Element>
) : Class(converter, name, comments, modifiers, typeParameterList, ) : Class(converter, name, comments, modifiers, typeParameterList,
extendsTypes, baseClassParams, implementsTypes, members) { extendsTypes, baseClassParams, implementsTypes, bodyElements) {
override fun primaryConstructorSignatureToKotlin(): String { override fun primaryConstructorSignatureToKotlin(): String {
val s: String = super.primaryConstructorSignatureToKotlin() val s: String = super.primaryConstructorSignatureToKotlin()
@@ -16,15 +16,13 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
open class EnumConstant( open class EnumConstant(
identifier: Identifier, identifier: Identifier,
members: MemberComments, members: MemberComments,
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
`type`: Type, `type`: Type,
params: Element params: Element
) : Field(identifier, members, modifiers, `type`.convertedToNotNull(), params, 0) { ) : Field(identifier, members, modifiers, `type`.toNotNullType(), params, 0) {
override fun toKotlin(): String { override fun toKotlin(): String {
if (initializer.toKotlin().isEmpty()) { if (initializer.toKotlin().isEmpty()) {
@@ -16,8 +16,6 @@
package org.jetbrains.jet.j2k.ast 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() { open class ArrayAccessExpression(val expression: Expression, val index: Expression, val lvalue: Boolean) : Expression() {
override fun toKotlin() = expression.toKotlin() + override fun toKotlin() = expression.toKotlin() +
(if (!lvalue && expression.isNullable) "!!" else "") + (if (!lvalue && expression.isNullable) "!!" else "") +
+1 -2
View File
@@ -16,7 +16,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.j2k.* import org.jetbrains.jet.j2k.*
import java.util.ArrayList import java.util.ArrayList
@@ -35,7 +34,7 @@ open class Field(
modifierList.add(Modifier.ABSTRACT) modifierList.add(Modifier.ABSTRACT)
} }
val modifier = accessModifier() val modifier = modifiers.accessModifier()
if (modifier != null) { if (modifier != null) {
modifierList.add(modifier) modifierList.add(modifier)
} }
@@ -16,9 +16,7 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
import java.util.ArrayList import java.util.ArrayList
import org.jetbrains.jet.j2k.ast.types.isUnit
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
open class Function( open class Function(
@@ -28,7 +26,7 @@ open class Function(
modifiers: Set<Modifier>, modifiers: Set<Modifier>,
val `type`: Type, val `type`: Type,
val typeParameterList: TypeParameterList, val typeParameterList: TypeParameterList,
val params: Element, val parameterList: ParameterList,
var block: Block? var block: Block?
) : Member(comments, modifiers) { ) : Member(comments, modifiers) {
@@ -39,7 +37,7 @@ open class Function(
resultingModifiers.add(Modifier.OVERRIDE) resultingModifiers.add(Modifier.OVERRIDE)
} }
val accessModifier = accessModifier() val accessModifier = modifiers.accessModifier()
if (accessModifier != null && !isOverride) { if (accessModifier != null && !isOverride) {
resultingModifiers.add(accessModifier) resultingModifiers.add(accessModifier)
} }
@@ -49,10 +47,10 @@ open class Function(
} }
if (converter.settings.openByDefault && if (converter.settings.openByDefault &&
!modifiers.contains(Modifier.ABSTRACT) && !modifiers.contains(Modifier.ABSTRACT) &&
!isOverride && !isOverride &&
!modifiers.contains(Modifier.FINAL) && !modifiers.contains(Modifier.FINAL) &&
!modifiers.contains(Modifier.PRIVATE)) { !modifiers.contains(Modifier.PRIVATE)) {
resultingModifiers.add(Modifier.OPEN) resultingModifiers.add(Modifier.OPEN)
} }
@@ -69,7 +67,7 @@ open class Function(
return commentsToKotlin() + return commentsToKotlin() +
modifiersToKotlin() + modifiersToKotlin() +
"fun ${typeParameterList.toKotlin().withSuffix(" ")}${name.toKotlin()}" + "fun ${typeParameterList.toKotlin().withSuffix(" ")}${name.toKotlin()}" +
"(${params.toKotlin()})" + "(${parameterList.toKotlin()})" +
returnTypeToKotlin() + returnTypeToKotlin() +
typeParameterList.whereToKotlin() + typeParameterList.whereToKotlin() +
block?.toKotlin() block?.toKotlin()
@@ -16,7 +16,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
class LocalVariable( class LocalVariable(
+21 -25
View File
@@ -25,10 +25,6 @@ class MemberComments(elements: List<Element>) : WhiteSpaceSeparatedElementList(e
} }
abstract class Member(val comments: MemberComments, val modifiers: Set<Modifier>) : Element { abstract class Member(val comments: MemberComments, val modifiers: Set<Modifier>) : 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 isAbstract(): Boolean = modifiers.contains(Modifier.ABSTRACT)
fun isStatic(): Boolean = modifiers.contains(Modifier.STATIC) fun isStatic(): Boolean = modifiers.contains(Modifier.STATIC)
fun commentsToKotlin(): String = comments.toKotlin() fun commentsToKotlin(): String = comments.toKotlin()
@@ -42,28 +38,28 @@ class MemberList(elements: List<Element>) : WhiteSpaceSeparatedElementList(eleme
get() = elements.filter { it is Member }.map { it as Member } get() = elements.filter { it is Member }.map { it as Member }
} }
class ClassMembers( class ClassMembers private(
val primaryConstructor: Constructor?, val primaryConstructor: PrimaryConstructor?,
val secondaryConstructors: MemberList, val secondaryConstructors: MemberList,
val allMembers: MemberList, val allMembers: MemberList,
val staticMembers: MemberList, val staticMembers: MemberList,
val nonStaticMembers: MemberList val nonStaticMembers: MemberList) {
) { class object {
} public fun fromBodyElements(elements: List<Element>): ClassMembers {
val groups = splitInGroups(elements)
fun parseClassMembers(elements: List<Element>): ClassMembers { val constructors = groups.filter { it.member is Constructor }
val groups = splitInGroups(elements) val primaryConstructor = constructors.map { it.member }.filterIsInstance(javaClass<PrimaryConstructor>()).firstOrNull()
val constructors = groups.filter { it.member is Constructor } val secondaryConstructors = constructors.filter { it.member is SecondaryConstructor }
val primaryConstructor = constructors.map { it.member }.find { (it as Constructor).isPrimary } val nonConstructors = groups.filter { it.member !is Constructor }
val secondaryConstructors = constructors.filter { !(it.member as Constructor).isPrimary } val staticMembers = nonConstructors.filter { it.member.isStatic() }
val nonConstructors = groups.filter { it.member !is Constructor } val nonStaticMembers = nonConstructors.filter { !it.member.isStatic() }
val staticMembers = nonConstructors.filter { it.member.isStatic() } return ClassMembers(primaryConstructor,
val nonStaticMembers = nonConstructors.filter { !it.member.isStatic() } secondaryConstructors.toMemberList(),
return ClassMembers(primaryConstructor as Constructor?, nonConstructors.toMemberList(),
secondaryConstructors.toMemberList(), staticMembers.toMemberList(),
nonConstructors.toMemberList(), nonStaticMembers.toMemberList())
staticMembers.toMemberList(), }
nonStaticMembers.toMemberList()) }
} }
private fun List<MemberHolder>.toMemberList() = MemberList(flatMap { it.elements }) private fun List<MemberHolder>.toMemberList() = MemberList(flatMap { it.elements })
@@ -74,8 +70,8 @@ private fun splitInGroups(elements: List<Element>): List<MemberHolder> {
for (element in elements) { for (element in elements) {
currentGroup.add(element) currentGroup.add(element)
if (element is Member) { if (element is Member) {
result.add(Pair(element, currentGroup)) result.add(element to currentGroup)
currentGroup = ArrayList<Element>() currentGroup = ArrayList()
} }
} }
if (result.isNotEmpty()) { if (result.isNotEmpty()) {
@@ -16,7 +16,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
import java.util.ArrayList import java.util.ArrayList
open class MethodCallExpression( open class MethodCallExpression(
+25 -1
View File
@@ -16,6 +16,11 @@
package org.jetbrains.jet.j2k.ast 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) { enum class Modifier(val name: String) {
PUBLIC: Modifier("public") PUBLIC: Modifier("public")
PROTECTED: Modifier("protected") PROTECTED: Modifier("protected")
@@ -25,6 +30,25 @@ enum class Modifier(val name: String) {
ABSTRACT: Modifier("abstract") ABSTRACT: Modifier("abstract")
FINAL: Modifier("final") FINAL: Modifier("final")
OPEN: Modifier("open") OPEN: Modifier("open")
NOT_OPEN: Modifier("not open") NOT_OPEN: Modifier("not open") //TODO: drop it
OVERRIDE: Modifier("override") 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<Modifier>.accessModifier(): Modifier? {
return firstOrNull { ACCESS_MODIFIERS.contains(it) }
}
fun Collection<Modifier>.toKotlin(): String
= if (isNotEmpty()) map { it.toKotlin() }.filterNotNull().makeString(" ") + " " else ""
+24 -12
View File
@@ -16,19 +16,31 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type class Parameter(val identifier: Identifier, val `type`: Type, val varVal: Parameter.VarValModifier, val modifiers: Collection<Modifier>) : Expression() {
import org.jetbrains.jet.j2k.ast.types.VarArg //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 { override fun toKotlin(): String {
val vararg: String = (if (`type` is VarArg) val builder = StringBuilder()
"vararg "
else builder.append(modifiers.toKotlin())
"")
val `var`: String? = (if (readOnly) if (`type` is VarArgType) {
"" assert(varVal == VarValModifier.None)
else builder.append("vararg ")
"var ") }
return vararg + `var` + identifier.toKotlin() + " : " + `type`.toKotlin()
when (varVal) {
VarValModifier.Var -> builder.append("var ")
VarValModifier.Val -> builder.append("val ")
}
builder.append(identifier.toKotlin()).append(": ").append(`type`.toKotlin())
return builder.toString()
} }
} }
@@ -16,8 +16,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
class ReferenceElement(val reference: Identifier, val types: List<Type>) : Element { class ReferenceElement(val reference: Identifier, val types: List<Type>) : Element {
override fun toKotlin() = reference.toKotlin() + types.toKotlin(", ", "<", ">") override fun toKotlin() = reference.toKotlin() + types.toKotlin(", ", "<", ">")
} }
+3 -4
View File
@@ -17,7 +17,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import org.jetbrains.jet.j2k.ast.types.Type
class Trait( class Trait(
converter: Converter, converter: Converter,
@@ -28,11 +27,11 @@ class Trait(
extendsTypes: List<Type>, extendsTypes: List<Type>,
baseClassParams: List<Expression>, baseClassParams: List<Expression>,
implementsTypes: List<Type>, implementsTypes: List<Type>,
members: List<Element> bodyElements: List<Element>
) : Class(converter, name, comments, modifiers, typeParameterList, ) : Class(converter, name, comments, modifiers, typeParameterList,
extendsTypes, baseClassParams, implementsTypes, members) { extendsTypes, baseClassParams, implementsTypes, bodyElements) {
override val TYPE: String override val keyword: String
get() = "trait" get() = "trait"
override fun primaryConstructorSignatureToKotlin() = "" override fun primaryConstructorSignatureToKotlin() = ""
@@ -16,10 +16,8 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
open class TypeElement(val `type`: Type) : Element { open class TypeElement(val `type`: Type) : Element {
override fun toKotlin() = `type`.toKotlin() override fun toKotlin() = `type`.toKotlin()
fun toKotlinNotNull(): String = `type`.convertedToNotNull().toKotlin() fun toKotlinNotNull(): String = `type`.toNotNullType().toKotlin()
} }
@@ -16,7 +16,6 @@
package org.jetbrains.jet.j2k.ast package org.jetbrains.jet.j2k.ast
import org.jetbrains.jet.j2k.ast.types.Type
import com.intellij.psi.PsiTypeParameter import com.intellij.psi.PsiTypeParameter
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import com.intellij.psi.PsiTypeParameterList import com.intellij.psi.PsiTypeParameterList
+113
View File
@@ -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<Element>, nullable: Boolean,
converter: Converter) : MayBeNullableType(nullable, converter) {
override fun toKotlin(): String {
// TODO change to map() when KT-2051 is fixed
val parametersToKotlin = ArrayList<String>()
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()
}
@@ -21,9 +21,6 @@ import java.util.ArrayList
fun List<Node>.toKotlin(separator: String, prefix: String = "", postfix: String = ""): String fun List<Node>.toKotlin(separator: String, prefix: String = "", postfix: String = ""): String
= if (isNotEmpty()) map { it.toKotlin() }.makeString(separator, prefix, postfix) else "" = if (isNotEmpty()) map { it.toKotlin() }.makeString(separator, prefix, postfix) else ""
fun Collection<Modifier>.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.withSuffix(suffix: String): String = if (isEmpty()) "" else this + suffix
fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this fun String.withPrefix(prefix: String): String = if (isEmpty()) "" else prefix + this
fun Expression.withPrefix(prefix: String): String = if (isEmpty) "" else prefix + toKotlin() fun Expression.withPrefix(prefix: String): String = if (isEmpty) "" else prefix + toKotlin()
@@ -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)
}
@@ -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<Element>, nullable: Boolean,
converter: Converter) : MayBeNullableType(nullable, converter) {
override fun toKotlin(): String {
// TODO change to map() when KT-2051 is fixed
val parametersToKotlin = ArrayList<String>()
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)
}
@@ -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"
}
@@ -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()
}
@@ -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()
}
@@ -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()
}
@@ -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 = "*"
}
@@ -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 ""
}
}
@@ -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()
}
@@ -19,16 +19,15 @@ package org.jetbrains.jet.j2k.visitors
import com.intellij.psi.* import com.intellij.psi.*
import org.jetbrains.jet.j2k.* import org.jetbrains.jet.j2k.*
import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.*
import org.jetbrains.jet.j2k.ast.types.Type
class ElementVisitor(public val converter: Converter) : JavaElementVisitor() { class ElementVisitor(public val converter: Converter) : JavaElementVisitor() {
public var result: Element = Element.Empty public var result: Element = Element.Empty
protected set protected set
override fun visitLocalVariable(variable: PsiLocalVariable) { 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()) { if (variable.hasModifierProperty(PsiModifier.FINAL) && variable.getInitializer().isDefinitelyNotNull()) {
kType = kType.convertedToNotNull() kType = kType.toNotNullType()
} }
result = LocalVariable(Identifier(variable.getName()!!), result = LocalVariable(Identifier(variable.getName()!!),
converter.convertModifierList(variable.getModifierList()), converter.convertModifierList(variable.getModifierList()),
@@ -68,7 +67,7 @@ class ElementVisitor(public val converter: Converter) : JavaElementVisitor() {
} }
override fun visitParameterList(list: PsiParameterList) { override fun visitParameterList(list: PsiParameterList) {
result = ParameterList(converter.convertParameterList(list.getParameters())) result = converter.convertParameterList(list)
} }
override fun visitComment(comment: PsiComment) { override fun visitComment(comment: PsiComment) {
@@ -25,9 +25,9 @@ import com.intellij.psi.CommonClassNames.*
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.jet.lang.types.lang.PrimitiveType import org.jetbrains.jet.lang.types.lang.PrimitiveType
import org.jetbrains.jet.j2k.* 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<PsiVariable, String> = mapOf()) : JavaElementVisitor() {
public var result: Expression = Expression.Empty public var result: Expression = Expression.Empty
protected set protected set
@@ -141,7 +141,7 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
} }
protected fun convertMethodCallExpression(expression: PsiMethodCallExpression) { protected fun convertMethodCallExpression(expression: PsiMethodCallExpression) {
if (!expression.isSuperConstructorCall() || !isInsidePrimaryConstructor(expression)) { if (!expression.isSuperConstructorCall() || !expression.isInsidePrimaryConstructor()) {
result = MethodCallExpression(converter.convertExpression(expression.getMethodExpression()), result = MethodCallExpression(converter.convertExpression(expression.getMethodExpression()),
converter.convertArguments(expression), converter.convertArguments(expression),
converter.convertTypes(expression.getTypeArguments()), converter.convertTypes(expression.getTypeArguments()),
@@ -212,7 +212,7 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
} }
override fun visitReferenceExpression(expression: PsiReferenceExpression) { override fun visitReferenceExpression(expression: PsiReferenceExpression) {
val containingConstructor = getContainingConstructor(expression) val containingConstructor = expression.getContainingConstructor()
val insideSecondaryConstructor = containingConstructor != null && !containingConstructor.isPrimaryConstructor() val insideSecondaryConstructor = containingConstructor != null && !containingConstructor.isPrimaryConstructor()
val addReceiver = insideSecondaryConstructor && (expression.getReference()?.resolve() as? PsiField)?.getContainingClass() == containingConstructor!!.getContainingClass() 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) identifier = Identifier("size", isNullable)
} }
else if (qualifier == null) { else if (qualifier == null) {
val resolved = expression.getReference()?.resolve() val target = expression.getReference()?.resolve()
if (resolved is PsiClass) {
if (PrimitiveType.values() any { it.getTypeName().asString() == resolved.getName() }) { if (target is PsiClass) {
result = Identifier(resolved.getQualifiedName()!!, false) if (PrimitiveType.values() any { it.getTypeName().asString() == target.getName() }) {
result = Identifier(target.getQualifiedName()!!, false)
return return
} }
} }
if (resolved is PsiMember if (target is PsiMember
&& resolved.hasModifierProperty(PsiModifier.STATIC) && target.hasModifierProperty(PsiModifier.STATIC)
&& resolved.getContainingClass() != null && target.getContainingClass() != null
&& PsiTreeUtil.getParentOfType(expression, javaClass<PsiClass>()) != resolved.getContainingClass() && PsiTreeUtil.getParentOfType(expression, javaClass<PsiClass>()) != target.getContainingClass()
&& !isStaticallyImported(resolved, expression)) { && !isStaticallyImported(target, expression)) {
var member = resolved as PsiMember var member = target as PsiMember
var code = Identifier(referencedName).toKotlin() var code = Identifier(referencedName).toKotlin()
while (member.getContainingClass() != null) { while (member.getContainingClass() != null) {
code = Identifier(member.getContainingClass()!!.getName()!!).toKotlin() + "." + code code = Identifier(member.getContainingClass()!!.getName()!!).toKotlin() + "." + code
@@ -253,6 +254,13 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
result = Identifier(code, false, false) result = Identifier(code, false, false)
return return
} }
if (target is PsiVariable) {
val replacement = usageReplacementMap[target]
if (replacement != null) {
identifier = Identifier(replacement, isNullable)
}
}
} }
result = CallChainExpression(converter.convertExpression(qualifier), identifier) result = CallChainExpression(converter.convertExpression(qualifier), identifier)
@@ -268,19 +276,13 @@ open class ExpressionVisitor(public val converter: Converter) : JavaElementVisit
} }
override fun visitSuperExpression(expression: PsiSuperExpression) { override fun visitSuperExpression(expression: PsiSuperExpression) {
val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier() val qualifier = expression.getQualifier()
result = SuperExpression((if (qualifier != null) result = SuperExpression(if (qualifier != null) Identifier(qualifier.getQualifiedName()!!) else Identifier.Empty)
Identifier(qualifier.getQualifiedName()!!)
else
Identifier.Empty))
} }
override fun visitThisExpression(expression: PsiThisExpression) { override fun visitThisExpression(expression: PsiThisExpression) {
val qualifier: PsiJavaCodeReferenceElement? = expression.getQualifier() val qualifier = expression.getQualifier()
result = ThisExpression((if (qualifier != null) result = ThisExpression(if (qualifier != null) Identifier(qualifier.getQualifiedName()!!) else Identifier.Empty)
Identifier(qualifier.getQualifiedName()!!)
else
Identifier.Empty))
} }
override fun visitTypeCastExpression(expression: PsiTypeCastExpression) { override fun visitTypeCastExpression(expression: PsiTypeCastExpression) {
@@ -23,16 +23,17 @@ import org.jetbrains.jet.j2k.ast.Identifier
import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
import org.jetbrains.jet.j2k.ast.MethodCallExpression import org.jetbrains.jet.j2k.ast.MethodCallExpression
open class ExpressionVisitorForDirectObjectInheritors(converter: Converter) : ExpressionVisitor(converter) { open class ExpressionVisitorForDirectObjectInheritors(converter: Converter, usageReplacementMap: Map<PsiVariable, String> = mapOf())
: ExpressionVisitor(converter, usageReplacementMap) {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) { override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
val methodExpression = expression.getMethodExpression() val methodExpression = expression.getMethodExpression()
if (superMethodInvocation(methodExpression, "hashCode")) { if (isSuperMethodInvocation(methodExpression, "hashCode")) {
result = MethodCallExpression.build(Identifier("System", false), "identityHashCode", listOf(Identifier("this"))) 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)) 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())") result = DummyStringExpression("getJavaClass<${getClassName(methodExpression)}>.getName() + '@' + Integer.toHexString(hashCode())")
} }
else { else {
@@ -40,14 +41,7 @@ open class ExpressionVisitorForDirectObjectInheritors(converter: Converter) : Ex
} }
} }
private fun superMethodInvocation(expression: PsiReferenceExpression, methodName: String?): Boolean { private fun isSuperMethodInvocation(expression: PsiReferenceExpression, methodName: String): Boolean
val referenceName: String? = expression.getReferenceName() = expression.getReferenceName() == methodName
val qualifierExpression: PsiExpression? = expression.getQualifierExpression() && (expression.getQualifierExpression() as? PsiSuperExpression)?.getType()?.getCanonicalText() == JAVA_LANG_OBJECT
if (referenceName == methodName && qualifierExpression is PsiSuperExpression) {
if (qualifierExpression.getType()?.getCanonicalText() == JAVA_LANG_OBJECT) {
return true
}
}
return false
}
} }
@@ -32,7 +32,7 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
} }
override fun visitBlockStatement(statement: PsiBlockStatement) { override fun visitBlockStatement(statement: PsiBlockStatement) {
result = converter.convertBlock(statement.getCodeBlock(), true) result = converter.convertBlock(statement.getCodeBlock())
} }
override fun visitBreakStatement(statement: PsiBreakStatement) { override fun visitBreakStatement(statement: PsiBreakStatement) {
@@ -217,10 +217,10 @@ class StatementVisitor(public val converter: Converter) : JavaElementVisitor() {
val catchBlockParameters = statement.getCatchBlockParameters() val catchBlockParameters = statement.getCatchBlockParameters()
for (i in 0..catchBlocks.size - 1) { for (i in 0..catchBlocks.size - 1) {
catches.add(CatchStatement(converter.convertParameter(catchBlockParameters[i], true), catches.add(CatchStatement(converter.convertParameter(catchBlockParameters[i], true),
converter.convertBlock(catchBlocks[i], true))) converter.convertBlock(catchBlocks[i])))
} }
result = TryStatement(converter.convertBlock(statement.getTryBlock(), true), result = TryStatement(converter.convertBlock(statement.getTryBlock()),
catches, converter.convertBlock(statement.getFinallyBlock(), true)) catches, converter.convertBlock(statement.getFinallyBlock()))
} }
override fun visitWhileStatement(statement: PsiWhileStatement) { override fun visitWhileStatement(statement: PsiWhileStatement) {
@@ -20,7 +20,6 @@ import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiClassReferenceType import com.intellij.psi.impl.source.PsiClassReferenceType
import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.Converter
import org.jetbrains.jet.j2k.ast.* import org.jetbrains.jet.j2k.ast.*
import org.jetbrains.jet.j2k.ast.types.*
import java.util.LinkedList import java.util.LinkedList
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import java.util.ArrayList import java.util.ArrayList
@@ -32,7 +31,7 @@ open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor<Type>(
override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type { override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type {
val name = primitiveType.getCanonicalText() val name = primitiveType.getCanonicalText()
return if (name == "void") { return if (name == "void") {
UnitType Type.Unit
} }
else if (PRIMITIVE_TYPES_NAMES.contains(name)) { else if (PRIMITIVE_TYPES_NAMES.contains(name)) {
PrimitiveType(Identifier(StringUtil.capitalize(name))) PrimitiveType(Identifier(StringUtil.capitalize(name)))
@@ -120,7 +119,7 @@ open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor<Type>(
} }
override fun visitEllipsisType(ellipsisType: PsiEllipsisType): Type { override fun visitEllipsisType(ellipsisType: PsiEllipsisType): Type {
return VarArg(converter.convertType(ellipsisType.getComponentType())) return VarArgType(converter.convertType(ellipsisType.getComponentType()))
} }
private fun createQualifiedName(classType: PsiClassType): String { private fun createQualifiedName(classType: PsiClassType): String {
@@ -42,10 +42,7 @@ import java.io.StringReader
public abstract class AbstractJavaToKotlinConverterPluginTest() : AbstractJavaToKotlinConverterTest("ide.kt", PluginSettings) public abstract class AbstractJavaToKotlinConverterPluginTest() : AbstractJavaToKotlinConverterTest("ide.kt", PluginSettings)
public abstract class AbstractJavaToKotlinConverterBasicTest() : AbstractJavaToKotlinConverterTest("kt", TestSettings) public abstract class AbstractJavaToKotlinConverterBasicTest() : AbstractJavaToKotlinConverterTest("kt", TestSettings)
abstract class AbstractJavaToKotlinConverterTest( abstract class AbstractJavaToKotlinConverterTest(val kotlinFileExtension: String, val settings: ConverterSettings ) : LightIdeaTestCase() {
val kotlinFileExtension: String,
val settings: ConverterSettings
) : LightIdeaTestCase() {
val testHeaderPattern = Pattern.compile("//(element|expression|statement|method|class|file|comp)\n") val testHeaderPattern = Pattern.compile("//(element|expression|statement|method|class|file|comp)\n")
@@ -720,6 +720,41 @@ public class JavaToKotlinConverterBasicTestGenerated extends AbstractJavaToKotli
doTest("j2k/tests/testData/ast/constructors/customerBuilder.java"); 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") @TestMetadata("genericIdentifier.java")
public void testGenericIdentifier() throws Exception { public void testGenericIdentifier() throws Exception {
doTest("j2k/tests/testData/ast/constructors/genericIdentifier.java"); doTest("j2k/tests/testData/ast/constructors/genericIdentifier.java");
@@ -720,6 +720,41 @@ public class JavaToKotlinConverterPluginTestGenerated extends AbstractJavaToKotl
doTest("j2k/tests/testData/ast/constructors/customerBuilder.java"); 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") @TestMetadata("genericIdentifier.java")
public void testGenericIdentifier() throws Exception { public void testGenericIdentifier() throws Exception {
doTest("j2k/tests/testData/ast/constructors/genericIdentifier.java"); doTest("j2k/tests/testData/ast/constructors/genericIdentifier.java");
@@ -1,10 +1,8 @@
class C(arg1: Int) { class C(val myArg1: Int) {
val myArg1: Int
var myArg2: Int = 0 var myArg2: Int = 0
var myArg3: Int = 0 var myArg3: Int = 0
{ {
myArg1 = arg1
myArg2 = 0 myArg2 = 0
myArg3 = 0 myArg3 = 0
} }
@@ -1,10 +1,8 @@
open class C(arg1: Int) { open class C(val myArg1: Int) {
val myArg1: Int
var myArg2: Int = 0 var myArg2: Int = 0
var myArg3: Int = 0 var myArg3: Int = 0
{ {
myArg1 = arg1
myArg2 = 0 myArg2 = 0
myArg3 = 0 myArg3 = 0
} }
@@ -1,8 +1,6 @@
package org.test.customer package org.test.customer
class Customer(first: String, last: String) { class Customer(public val _firstName: String, public val _lastName: String) {
public val _firstName: String
public val _lastName: String
public fun getFirstName(): String { public fun getFirstName(): String {
return _firstName return _firstName
@@ -19,8 +17,6 @@ class Customer(first: String, last: String) {
{ {
doSmthBefore() doSmthBefore()
_firstName = first
_lastName = last
doSmthAfter() doSmthAfter()
} }
} }
@@ -1,8 +1,6 @@
package org.test.customer package org.test.customer
open class Customer(first: String?, last: String?) { open class Customer(public val _firstName: String?, public val _lastName: String?) {
public val _firstName: String?
public val _lastName: String?
public open fun getFirstName(): String? { public open fun getFirstName(): String? {
return _firstName return _firstName
@@ -19,8 +17,6 @@ open class Customer(first: String?, last: String?) {
{ {
doSmthBefore() doSmthBefore()
_firstName = first
_lastName = last
doSmthAfter() doSmthAfter()
} }
} }
@@ -0,0 +1 @@
class C(private val p1: Int, private val myP2: Int, public var p3: Int) {}
@@ -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;
}
}
@@ -0,0 +1 @@
open class C(private val p1: Int, private val myP2: Int, public var p3: Int) {}
@@ -0,0 +1,5 @@
class C(private val field: Int) {
{
System.out.println(field)
}
}
@@ -0,0 +1,9 @@
//file
class C {
private final int field;
public C(int p) {
field = p
System.out.println(p);
}
}
@@ -0,0 +1,5 @@
open class C(private val field: Int) {
{
System.out?.println(field)
}
}
@@ -0,0 +1,9 @@
class C(p: Int) {
private val p: Int
{
this.p = p
System.out.println(p++)
System.out.println(p)
}
}
@@ -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);
}
}
@@ -0,0 +1,9 @@
open class C(p: Int) {
private val p: Int
{
this.p = p
System.out?.println(p++)
System.out?.println(p)
}
}
@@ -0,0 +1,7 @@
class C(p: Int, c: C) {
public var p: Int = 0
{
c.p = p
}
}
@@ -0,0 +1,8 @@
//file
class C {
public int p;
public C(int p, C c) {
c.p = p;
}
}
@@ -0,0 +1,7 @@
open class C(p: Int, c: C?) {
public var p: Int = 0
{
c?.p = p
}
}
@@ -0,0 +1,10 @@
class C(p: Int) {
public var p: Int = 0
{
this.p = 0
if (p > 0) {
this.p = p
}
}
}
@@ -0,0 +1,11 @@
//file
class C {
public int p;
public C(int p) {
this.p = 0
if (p > 0) {
this.p = p
}
}
}
@@ -0,0 +1,10 @@
open class C(p: Int) {
public var p: Int = 0
{
this.p = 0
if (p > 0) {
this.p = p
}
}
}
@@ -0,0 +1,7 @@
class C(x: String) {
public var x: Any = 0
{
this.x = x
}
}
@@ -0,0 +1,8 @@
//file
class C {
public Object x;
public C(String x) {
this.x = x;
}
}
@@ -0,0 +1,7 @@
open class C(x: String?) {
public var x: Any? = null
{
this.x = x
}
}
@@ -0,0 +1,9 @@
class C(x: Any, b: Boolean) {
public var x: Any = 0
{
if (b) {
this.x = x
}
}
}
@@ -0,0 +1,10 @@
//file
class C {
public Object x;
public C(Object x, boolean b) {
if (b) {
this.x = x;
}
}
}
@@ -0,0 +1,9 @@
open class C(x: Any?, b: Boolean) {
public var x: Any? = null
{
if (b) {
this.x = x
}
}
}
+1 -7
View File
@@ -1,16 +1,10 @@
package demo package demo
enum class MyEnum(_color: Int) { enum class MyEnum(private val color: Int) {
RED : MyEnum(10) RED : MyEnum(10)
BLUE : MyEnum(20) BLUE : MyEnum(20)
private val color: Int
public fun getColor(): Int { public fun getColor(): Int {
return color return color
} }
{
color = _color
}
} }
+1 -7
View File
@@ -1,16 +1,10 @@
package demo package demo
enum class MyEnum(_color: Int) { enum class MyEnum(private val color: Int) {
RED : MyEnum(10) RED : MyEnum(10)
BLUE : MyEnum(20) BLUE : MyEnum(20)
private val color: Int
public fun getColor(): Int { public fun getColor(): Int {
return color return color
} }
{
color = _color
}
} }
@@ -1,17 +1,11 @@
enum class Color(c: Int) { enum class Color(private var code: Int) {
WHITE : Color(21) WHITE : Color(21)
BLACK : Color(22) BLACK : Color(22)
RED : Color(23) RED : Color(23)
YELLOW : Color(24) YELLOW : Color(24)
BLUE : Color(25) BLUE : Color(25)
private var code: Int = 0
public fun getCode(): Int { public fun getCode(): Int {
return code return code
} }
{
code = c
}
} }
@@ -1,13 +1,14 @@
//class //class
enum Color { 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) { private Color(int c) {
code = c; code = c;
} }
public int getCode() { public int getCode() {
return code; return code;
} }
}
@@ -1,17 +1,11 @@
enum class Color(c: Int) { enum class Color(private var code: Int) {
WHITE : Color(21) WHITE : Color(21)
BLACK : Color(22) BLACK : Color(22)
RED : Color(23) RED : Color(23)
YELLOW : Color(24) YELLOW : Color(24)
BLUE : Color(25) BLUE : Color(25)
private var code: Int = 0
public fun getCode(): Int { public fun getCode(): Int {
return code return code
} }
{
code = c
}
} }
@@ -1,13 +1,8 @@
package demo package demo
enum class Color(c: Int) { enum class Color(private var code: Int) {
private var code: Int = 0
public fun getCode(): Int { public fun getCode(): Int {
return code return code
} }
{
code = c
}
} }
@@ -1,13 +1,8 @@
package demo package demo
enum class Color(c: Int) { enum class Color(private var code: Int) {
private var code: Int = 0
public fun getCode(): Int { public fun getCode(): Int {
return code return code
} }
{
code = c
}
} }
@@ -1,7 +1,7 @@
package demo package demo
class Test() { class Test() {
fun test(vararg var args: Any) { fun test(vararg args: Any) {
args = array<Int>(1, 2, 3) args = array<Int>(1, 2, 3)
} }
} }
+1 -1
View File
@@ -1,7 +1,7 @@
package demo package demo
open class Test() { open class Test() {
open fun test(vararg var args: Any?) { open fun test(vararg args: Any?) {
args = array<Int?>(1, 2, 3) args = array<Int?>(1, 2, 3)
} }
} }
@@ -1,7 +1,7 @@
package demo package demo
class Test() { class Test() {
fun test(var i: Int): Int { fun test(i: Int): Int {
i = 10 i = 10
return i + 20 return i + 20
} }
@@ -1,7 +1,7 @@
package demo package demo
open class Test() { open class Test() {
open fun test(var i: Int): Int { open fun test(i: Int): Int {
i = 10 i = 10
return i + 20 return i + 20
} }
@@ -2,14 +2,9 @@ class `$$$$$`() {}
class `$`() {} class `$`() {}
class `$$`(`$$$$`: `$$$$$`) : `$`() { class `$$`(val `$$$`: `$$$$$`) : `$`() {
val `$$$`: `$$$$$`
public fun `$$$$$$`(): `$$$$$` { public fun `$$$$$$`(): `$$$$$` {
return `$$$` return `$$$`
} }
{
`$$$` = `$$$$`
}
} }
@@ -2,14 +2,9 @@ open class `$$$$$`() {}
open class `$`() {} open class `$`() {}
open class `$$`(`$$$$`: `$$$$$`?) : `$`() { open class `$$`(val `$$$`: `$$$$$`?) : `$`() {
val `$$$`: `$$$$$`?
public open fun `$$$$$$`(): `$$$$$`? { public open fun `$$$$$$`(): `$$$$$`? {
return `$$$` return `$$$`
} }
{
`$$$` = `$$$$`
}
} }
@@ -1,9 +1,3 @@
class Base<T>(name: T) {} class Base<T>(name: T) {}
class One<T, K>(name: T, second: K) : Base<T>(name) { class One<T, K>(name: T, private var mySecond: K) : Base<T>(name) {}
private var mySecond: K = 0
{
mySecond = second
}
}
@@ -1,9 +1,3 @@
open class Base<T>(name: T?) {} open class Base<T>(name: T?) {}
open class One<T, K>(name: T?, second: K?) : Base<T?>(name) { open class One<T, K>(name: T?, private var mySecond: K?) : Base<T?>(name) {}
private var mySecond: K? = null
{
mySecond = second
}
}
@@ -1,9 +1,3 @@
class Base(name: String) {} class Base(name: String) {}
class One(name: String, second: String) : Base(name) { class One(name: String, private var mySecond: String) : Base(name) {}
private var mySecond: String = 0
{
mySecond = second
}
}
@@ -1,9 +1,3 @@
open class Base(name: String?) {} open class Base(name: String?) {}
open class One(name: String?, second: String?) : Base(name) { open class One(name: String?, private var mySecond: String?) : Base(name) {}
private var mySecond: String? = null
{
mySecond = second
}
}
+1 -7
View File
@@ -1,9 +1,3 @@
package demo package demo
class C(i: Int) { class C(private val i: Int) {}
private val i: Int
{
this.i = i
}
}
+1 -7
View File
@@ -1,9 +1,3 @@
package demo package demo
open class C(i: Int) { open class C(private val i: Int) {}
private val i: Int
{
this.i = i
}
}
+1 -6
View File
@@ -2,16 +2,11 @@ package com.voltvoodoo.saplo4j.model
import java.io.Serializable import java.io.Serializable
public class Language(code: String) : Serializable { public class Language(protected var code: String) : Serializable {
protected var code: String = 0
override fun toString(): String { override fun toString(): String {
return this.code return this.code
} }
{
this.code = code
}
} }
+1 -6
View File
@@ -2,16 +2,11 @@ package com.voltvoodoo.saplo4j.model
import java.io.Serializable import java.io.Serializable
public open class Language(code: String?) : Serializable { public open class Language(protected var code: String?) : Serializable {
protected var code: String? = null
override fun toString(): String? { override fun toString(): String? {
return this.code return this.code
} }
{
this.code = code
}
} }
+2 -7
View File
@@ -2,21 +2,16 @@ package com.voltvoodoo.saplo4j.model
import java.io.Serializable import java.io.Serializable
public class Language(code: String) : Serializable { public class Language(protected var code: String) : Serializable {
protected var code: String = 0
public fun equals(other: Language): Boolean { public fun equals(other: Language): Boolean {
return other.toString().equals(this.toString()) return other.toString().equals(this.toString())
} }
{
this.code = code
}
class object { class object {
public var ENGLISH: Language = Language("en") public var ENGLISH: Language = Language("en")
public var SWEDISH: Language = Language("sv") public var SWEDISH: Language = Language("sv")
private val serialVersionUID: Long = -2442762969929206780 private val serialVersionUID: Long = -2442762969929206780
} }
} }
+2 -7
View File
@@ -2,21 +2,16 @@ package com.voltvoodoo.saplo4j.model
import java.io.Serializable import java.io.Serializable
public open class Language(code: String?) : Serializable { public open class Language(protected var code: String?) : Serializable {
protected var code: String? = null
public open fun equals(other: Language?): Boolean { public open fun equals(other: Language?): Boolean {
return other?.toString()?.equals(this.toString())!! return other?.toString()?.equals(this.toString())!!
} }
{
this.code = code
}
class object { class object {
public var ENGLISH: Language? = Language("en") public var ENGLISH: Language? = Language("en")
public var SWEDISH: Language? = Language("sv") public var SWEDISH: Language? = Language("sv")
private val serialVersionUID: Long = -2442762969929206780 private val serialVersionUID: Long = -2442762969929206780
} }
} }