From d691abb1c473cfff5ca901091f5f3e3d6ee3ad5a Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 5 Jun 2014 21:36:14 +0400 Subject: [PATCH] Java to Kotlin converter: code refactoring - extracted some code from Converter into TypeConverter --- j2k/src/org/jetbrains/jet/j2k/Converter.kt | 171 ++---------------- .../org/jetbrains/jet/j2k/TypeConverter.kt | 167 +++++++++++++++++ .../org/jetbrains/jet/j2k/ast/Constructors.kt | 2 +- j2k/src/org/jetbrains/jet/j2k/ast/Types.kt | 21 ++- .../jetbrains/jet/j2k/visitors/Dispatcher.kt | 5 +- .../jet/j2k/visitors/ElementVisitor.kt | 10 +- .../jet/j2k/visitors/ExpressionVisitor.kt | 27 +-- .../jetbrains/jet/j2k/visitors/TypeVisitor.kt | 16 +- 8 files changed, 224 insertions(+), 195 deletions(-) create mode 100644 j2k/src/org/jetbrains/jet/j2k/TypeConverter.kt diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt index 794881d1478..71fe26b7ce0 100644 --- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt @@ -27,9 +27,11 @@ import com.intellij.psi.util.PsiUtil public class Converter(val project: Project, val settings: ConverterSettings) { + private val typeConverter = TypeConverter(settings) + private var classIdentifiersSet: MutableSet = HashSet() - private val dispatcher: Dispatcher = Dispatcher(this) + private val dispatcher: Dispatcher = Dispatcher(this, typeConverter) public var methodReturnType: PsiType? = null private set @@ -206,14 +208,14 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return EnumConstant(Identifier(field.getName()!!), getComments(field), modifiers, - convertType(field.getType(), Nullability.NotNull), + typeConverter.convertType(field.getType(), Nullability.NotNull), convertElement(field.getArgumentList())) } return Field(Identifier(field.getName()!!), getComments(field), modifiers, - convertVariableType(field), + typeConverter.convertVariableType(field), convertExpression(field.getInitializer(), field.getType()), field.hasModifierProperty(PsiModifier.FINAL), field.countWriteAccesses(field.getContainingClass())) @@ -221,7 +223,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { private fun convertMethod(method: PsiMethod, membersToRemove: MutableSet): Function { methodReturnType = method.getReturnType() - val returnType = convertMethodReturnType(method) + val returnType = typeConverter.convertMethodReturnType(method) val modifiers = convertModifiers(method) @@ -262,7 +264,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } if (overridesMethodFromObject) { val correctedParameter = Parameter(Identifier("other"), - ClassType(Identifier("Any"), listOf(), Nullability.Nullable, this), + ClassType(Identifier("Any"), listOf(), Nullability.Nullable, settings), Parameter.VarValModifier.None, listOf()) params = ParameterList(listOf(correctedParameter)) @@ -275,38 +277,6 @@ public class Converter(val project: Project, val settings: ConverterSettings) { } } - private fun convertMethodReturnType(method: PsiMethod): Type { - var nullability = method.nullabilityFromAnnotations() - - if (nullability == Nullability.Default) { - var isInAnonymousClass = false - method.getBody()?.accept(object: JavaRecursiveElementVisitor() { - override fun visitAnonymousClass(aClass: PsiAnonymousClass) { - isInAnonymousClass = true - super.visitAnonymousClass(aClass) - isInAnonymousClass = false - } - - override fun visitReturnStatement(statement: PsiReturnStatement) { - if (!isInAnonymousClass && statement.getReturnValue()?.nullability() == Nullability.Nullable) { - nullability = Nullability.Nullable - } - } - }) - } - - if (nullability == Nullability.Default) { - val scope = searchScope(method) - if (scope != null) { - if (findMethodCalls(method, scope).any { isNullableFromUsage(it) }) { - nullability = Nullability.Nullable - } - } - } - - return convertType(method.getReturnType(), nullability) - } - /** * Overrides of methods from Object should not be marked as overrides in Kotlin unless the class itself has java ancestors */ @@ -355,8 +325,8 @@ public class Converter(val project: Project, val settings: ConverterSettings) { for (parameter in params) { val (field, initializationStatement) = findBackingFieldForConstructorParameter(parameter, constructor) ?: continue - val fieldType = convertVariableType(field) - val parameterType = convertVariableType(parameter) + val fieldType = typeConverter.convertVariableType(field) + val parameterType = typeConverter.convertVariableType(parameter) // types can be different only in nullability val `type` = if (fieldType == parameterType) { fieldType @@ -376,12 +346,12 @@ public class Converter(val project: Project, val settings: ConverterSettings) { usageReplacementMap.put(parameter, field.getName()!!) } } - dispatcher.expressionVisitor = ExpressionVisitor(this, usageReplacementMap) + dispatcher.expressionVisitor = ExpressionVisitor(this, typeConverter, usageReplacementMap) try { Block(convertStatements(body.getStatements().filter{ !statementsToRemove.contains(it) }), false) } finally { - dispatcher.expressionVisitor = ExpressionVisitor(this, mapOf()) + dispatcher.expressionVisitor = ExpressionVisitor(this, typeConverter, mapOf()) } } else { @@ -466,7 +436,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { public fun convertElement(element: PsiElement?): Element { if (element == null) return Element.Empty - val elementVisitor = ElementVisitor(this) + val elementVisitor = ElementVisitor(this, typeConverter) element.accept(elementVisitor) return elementVisitor.result } @@ -483,122 +453,11 @@ public class Converter(val project: Project, val settings: ConverterSettings) { return TypeElement(if (element == null) Type.Empty else - convertType(element.getType())) - } - - public fun convertType(`type`: PsiType?, nullability: Nullability = Nullability.Default): Type { - if (`type` == null) return Type.Empty - - val result = `type`.accept(TypeVisitor(this))!! - return when (nullability) { - Nullability.NotNull -> result.toNotNullType() - Nullability.Nullable -> result.toNullableType() - Nullability.Default -> result - } - } - - public fun convertTypes(types: Array): List { - return types.map { convertType(it) } - } - - public fun convertVariableType(variable: PsiVariable): Type { - var nullability = variable.nullabilityFromAnnotations() - - if (nullability == Nullability.Default) { - val initializer = variable.getInitializer() - if (initializer != null) { - val initializerNullability = initializer.nullability() - if (variable.hasModifierProperty(PsiModifier.FINAL)) { //TODO: replace check for final modifier with effective final - nullability = initializerNullability - } - else if (initializerNullability == Nullability.Nullable) { // if variable is not final then non-nullability of initializer does not mean that variable is non-null - nullability = Nullability.Nullable - } - } - } - - if (nullability == Nullability.Default) { - val scope = searchScope(variable) - if (scope != null) { - if (findVariableUsages(variable, scope).any { isNullableFromUsage(it) }) { - nullability = Nullability.Nullable - } - } - } - - if (nullability == Nullability.Default && variable is PsiParameter) { - val method = variable.getDeclarationScope() as? PsiMethod - if (method != null) { - val scope = searchScope(method) - if (scope != null) { - val parameters = method.getParameterList().getParameters() - val parameterIndex = parameters.indexOf(variable) - for (call in findMethodCalls(method, scope)) { - val args = call.getArgumentList().getExpressions() - if (args.size == parameters.size) { - if (args[parameterIndex].nullability() == Nullability.Nullable) { - nullability = Nullability.Nullable - break - } - } - } - } - } - } - - return convertType(variable.getType(), nullability) - } - - private fun searchScope(element: PsiElement): PsiElement? { - return when(element) { - is PsiParameter -> element.getDeclarationScope() - is PsiField -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.getContainingClass() else element.getContainingFile() - is PsiMethod -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.getContainingClass() else element.getContainingFile() - is PsiLocalVariable -> element.getContainingMethod() - else -> null - } - } - - private fun PsiExpression.nullability(): Nullability { - return when (this) { - is PsiLiteralExpression -> if (getValue() != null) Nullability.NotNull else Nullability.Nullable - - is PsiNewExpression -> Nullability.NotNull - - is PsiConditionalExpression -> { - val nullability1 = getThenExpression()?.nullability() - if (nullability1 == Nullability.Nullable) return Nullability.Nullable - val nullability2 = getElseExpression()?.nullability() - if (nullability2 == Nullability.Nullable) return Nullability.Nullable - if (nullability1 == Nullability.NotNull && nullability2 == Nullability.NotNull) return Nullability.NotNull - Nullability.Default - } - - is PsiParenthesizedExpression -> getExpression()?.nullability() ?: Nullability.Default - - //TODO: some other cases - - else -> Nullability.Default - } - } - - private fun isNullableFromUsage(usage: PsiExpression): Boolean { - val parent = usage.getParent() ?: return false - if (parent is PsiAssignmentExpression && parent.getOperationTokenType() == JavaTokenType.EQ && usage == parent.getLExpression()) { - return parent.getRExpression()?.nullability() == Nullability.Nullable - } - else if (parent is PsiBinaryExpression) { - val operationType = parent.getOperationTokenType() - if (operationType == JavaTokenType.EQEQ || operationType == JavaTokenType.NE) { - val otherOperand = if (usage == parent.getLOperand()) parent.getROperand() else parent.getLOperand() - return otherOperand?.nullability() == Nullability.Nullable - } - } - return false + typeConverter.convertType(element.getType())) } private fun convertToNotNullableTypes(types: Array): List - = types.map { convertType(it, Nullability.NotNull) } + = types.map { typeConverter.convertType(it, Nullability.NotNull) } public fun convertParameterList(parameterList: PsiParameterList): ParameterList = ParameterList(parameterList.getParameters().map { convertParameter(it) }) @@ -607,7 +466,7 @@ public class Converter(val project: Project, val settings: ConverterSettings) { nullability: Nullability = Nullability.Default, varValModifier: Parameter.VarValModifier = Parameter.VarValModifier.None, modifiers: Collection = listOf()): Parameter { - var `type` = convertVariableType(parameter) + var `type` = typeConverter.convertVariableType(parameter) when (nullability) { Nullability.NotNull -> `type` = `type`.toNotNullType() Nullability.Nullable -> `type` = `type`.toNullableType() diff --git a/j2k/src/org/jetbrains/jet/j2k/TypeConverter.kt b/j2k/src/org/jetbrains/jet/j2k/TypeConverter.kt new file mode 100644 index 00000000000..9b84706beab --- /dev/null +++ b/j2k/src/org/jetbrains/jet/j2k/TypeConverter.kt @@ -0,0 +1,167 @@ +/* + * 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 + +import org.jetbrains.jet.j2k.ast.Type +import org.jetbrains.jet.j2k.ast.Nullability +import com.intellij.psi.* +import org.jetbrains.jet.j2k.visitors.TypeVisitor + +class TypeConverter(val settings: ConverterSettings) { + public fun convertType(`type`: PsiType?, nullability: Nullability = Nullability.Default): Type { + if (`type` == null) return Type.Empty + + val result = `type`.accept(TypeVisitor(this))!! + return when (nullability) { + Nullability.NotNull -> result.toNotNullType() + Nullability.Nullable -> result.toNullableType() + Nullability.Default -> result + } + } + + public fun convertTypes(types: Array): List { + return types.map { convertType(it) } + } + + public fun convertVariableType(variable: PsiVariable): Type { + var nullability = variable.nullabilityFromAnnotations() + + if (nullability == Nullability.Default) { + val initializer = variable.getInitializer() + if (initializer != null) { + val initializerNullability = initializer.nullability() + if (variable.hasModifierProperty(PsiModifier.FINAL)) { //TODO: replace check for final modifier with effective final + nullability = initializerNullability + } + else if (initializerNullability == Nullability.Nullable) { // if variable is not final then non-nullability of initializer does not mean that variable is non-null + nullability = Nullability.Nullable + } + } + } + + if (nullability == Nullability.Default) { + val scope = searchScope(variable) + if (scope != null) { + if (findVariableUsages(variable, scope).any { isNullableFromUsage(it) }) { + nullability = Nullability.Nullable + } + } + } + + if (nullability == Nullability.Default && variable is PsiParameter) { + val method = variable.getDeclarationScope() as? PsiMethod + if (method != null) { + val scope = searchScope(method) + if (scope != null) { + val parameters = method.getParameterList().getParameters() + val parameterIndex = parameters.indexOf(variable) + for (call in findMethodCalls(method, scope)) { + val args = call.getArgumentList().getExpressions() + if (args.size == parameters.size) { + if (args[parameterIndex].nullability() == Nullability.Nullable) { + nullability = Nullability.Nullable + break + } + } + } + } + } + } + + return convertType(variable.getType(), nullability) + } + + public fun convertMethodReturnType(method: PsiMethod): Type { + var nullability = method.nullabilityFromAnnotations() + + if (nullability == Nullability.Default) { + var isInAnonymousClass = false + method.getBody()?.accept(object: JavaRecursiveElementVisitor() { + override fun visitAnonymousClass(aClass: PsiAnonymousClass) { + isInAnonymousClass = true + super.visitAnonymousClass(aClass) + isInAnonymousClass = false + } + + override fun visitReturnStatement(statement: PsiReturnStatement) { + if (!isInAnonymousClass && statement.getReturnValue()?.nullability() == Nullability.Nullable) { + nullability = Nullability.Nullable + } + } + }) + } + + if (nullability == Nullability.Default) { + val scope = searchScope(method) + if (scope != null) { + if (findMethodCalls(method, scope).any { isNullableFromUsage(it) }) { + nullability = Nullability.Nullable + } + } + } + + return convertType(method.getReturnType(), nullability) + } + + private fun searchScope(element: PsiElement): PsiElement? { + return when(element) { + is PsiParameter -> element.getDeclarationScope() + is PsiField -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.getContainingClass() else element.getContainingFile() + is PsiMethod -> if (element.hasModifierProperty(PsiModifier.PRIVATE)) element.getContainingClass() else element.getContainingFile() + is PsiLocalVariable -> element.getContainingMethod() + else -> null + } + } + + private fun PsiExpression.nullability(): Nullability { + return when (this) { + is PsiLiteralExpression -> if (getValue() != null) Nullability.NotNull else Nullability.Nullable + + is PsiNewExpression -> Nullability.NotNull + + is PsiConditionalExpression -> { + val nullability1 = getThenExpression()?.nullability() + if (nullability1 == Nullability.Nullable) return Nullability.Nullable + val nullability2 = getElseExpression()?.nullability() + if (nullability2 == Nullability.Nullable) return Nullability.Nullable + if (nullability1 == Nullability.NotNull && nullability2 == Nullability.NotNull) return Nullability.NotNull + Nullability.Default + } + + is PsiParenthesizedExpression -> getExpression()?.nullability() ?: Nullability.Default + + //TODO: some other cases + + else -> Nullability.Default + } + } + + private fun isNullableFromUsage(usage: PsiExpression): Boolean { + val parent = usage.getParent() ?: return false + if (parent is PsiAssignmentExpression && parent.getOperationTokenType() == JavaTokenType.EQ && usage == parent.getLExpression()) { + return parent.getRExpression()?.nullability() == Nullability.Nullable + } + else if (parent is PsiBinaryExpression) { + val operationType = parent.getOperationTokenType() + if (operationType == JavaTokenType.EQEQ || operationType == JavaTokenType.NE) { + val otherOperand = if (usage == parent.getLOperand()) parent.getROperand() else parent.getLOperand() + return otherOperand?.nullability() == Nullability.Nullable + } + } + return false + } +} diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt index a4912571c36..fd47996ca5e 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Constructors.kt @@ -60,7 +60,7 @@ class SecondaryConstructor(converter: Converter, val typeParameters = ArrayList() typeParameters.addAll(containingClass.typeParameterList.parameters) return Function(converter, Identifier("init"), MemberComments.Empty, modifiers, - ClassType(containingClass.name, typeParameters, Nullability.NotNull, converter), + ClassType(containingClass.name, typeParameters, Nullability.NotNull, converter.settings), TypeParameterList(typeParameters), parameterList, block, false) } } diff --git a/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt b/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt index 18e9d565615..5346dae31f3 100644 --- a/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt +++ b/j2k/src/org/jetbrains/jet/j2k/ast/Types.kt @@ -18,6 +18,7 @@ package org.jetbrains.jet.j2k.ast import org.jetbrains.jet.j2k.Converter import java.util.ArrayList +import org.jetbrains.jet.j2k.ConverterSettings fun Type.isPrimitive(): Boolean = this is PrimitiveType fun Type.isUnit(): Boolean = this == Type.Unit @@ -28,11 +29,11 @@ enum class Nullability { Default } -abstract class MayBeNullableType(nullability: Nullability, val converter: Converter) : Type { +abstract class MayBeNullableType(nullability: Nullability, val settings: ConverterSettings) : Type { override val isNullable: Boolean = when (nullability) { Nullability.Nullable -> true Nullability.NotNull -> false - Nullability.Default -> !converter.settings.forceNotNullTypes + Nullability.Default -> !settings.forceNotNullTypes } } @@ -73,8 +74,8 @@ trait Type : Element { override fun toString(): String = toKotlin() } -open class ClassType(val `type`: Identifier, val parameters: List, nullability: Nullability, converter: Converter) - : MayBeNullableType(nullability, converter) { +open class ClassType(val `type`: Identifier, val parameters: List, nullability: Nullability, settings: ConverterSettings) + : MayBeNullableType(nullability, settings) { override fun toKotlin(): String { // TODO change to map() when KT-2051 is fixed @@ -90,12 +91,12 @@ open class ClassType(val `type`: Identifier, val parameters: List, null } - override fun toNotNullType(): Type = ClassType(`type`, parameters, Nullability.NotNull, converter) - override fun toNullableType(): Type = ClassType(`type`, parameters, Nullability.Nullable, converter) + override fun toNotNullType(): Type = ClassType(`type`, parameters, Nullability.NotNull, settings) + override fun toNullableType(): Type = ClassType(`type`, parameters, Nullability.Nullable, settings) } -class ArrayType(val elementType: Type, nullability: Nullability, converter: Converter) - : MayBeNullableType(nullability, converter) { +class ArrayType(val elementType: Type, nullability: Nullability, settings: ConverterSettings) + : MayBeNullableType(nullability, settings) { override fun toKotlin(): String { if (elementType is PrimitiveType) { @@ -105,8 +106,8 @@ class ArrayType(val elementType: Type, nullability: Nullability, converter: Conv return "Array<" + elementType.toKotlin() + ">" + isNullableStr() } - override fun toNotNullType(): Type = ArrayType(elementType, Nullability.NotNull, converter) - override fun toNullableType(): Type = ArrayType(elementType, Nullability.Nullable, converter) + override fun toNotNullType(): Type = ArrayType(elementType, Nullability.NotNull, settings) + override fun toNullableType(): Type = ArrayType(elementType, Nullability.Nullable, settings) } open class InProjectionType(val bound: Type) : NotNullType { diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/Dispatcher.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/Dispatcher.kt index 616a36bbe7f..13519d0dbce 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/Dispatcher.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/Dispatcher.kt @@ -17,7 +17,8 @@ package org.jetbrains.jet.j2k.visitors import org.jetbrains.jet.j2k.Converter +import org.jetbrains.jet.j2k.TypeConverter -open class Dispatcher(converter: Converter) { - var expressionVisitor: ExpressionVisitor = ExpressionVisitor(converter) +open class Dispatcher(converter: Converter, typeConverter: TypeConverter) { + var expressionVisitor: ExpressionVisitor = ExpressionVisitor(converter, typeConverter) } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt index 03616073236..68410680a48 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ElementVisitor.kt @@ -20,14 +20,14 @@ import com.intellij.psi.* import org.jetbrains.jet.j2k.* import org.jetbrains.jet.j2k.ast.* -class ElementVisitor(public val converter: Converter) : JavaElementVisitor() { +class ElementVisitor(private val converter: Converter, private val typeConverter: TypeConverter) : JavaElementVisitor() { public var result: Element = Element.Empty protected set override fun visitLocalVariable(variable: PsiLocalVariable) { result = LocalVariable(Identifier(variable.getName()!!), converter.convertModifiers(variable), - { converter.convertVariableType(variable) }, + { typeConverter.convertVariableType(variable) }, converter.convertExpression(variable.getInitializer(), variable.getType()), converter.settings.forceLocalVariableImmutability || variable.hasModifierProperty(PsiModifier.FINAL), converter.settings) @@ -38,7 +38,7 @@ class ElementVisitor(public val converter: Converter) : JavaElementVisitor() { } override fun visitReferenceElement(reference: PsiJavaCodeReferenceElement) { - val types = converter.convertTypes(reference.getTypeParameters()) + val types = typeConverter.convertTypes(reference.getTypeParameters()) if (!reference.isQualified()) { result = ReferenceElement(Identifier(reference.getReferenceName()!!), types) } @@ -55,12 +55,12 @@ class ElementVisitor(public val converter: Converter) : JavaElementVisitor() { } override fun visitTypeElement(`type`: PsiTypeElement) { - result = TypeElement(converter.convertType(`type`.getType())) + result = TypeElement(typeConverter.convertType(`type`.getType())) } override fun visitTypeParameter(classParameter: PsiTypeParameter) { result = TypeParameter(Identifier(classParameter.getName()!!), - classParameter.getExtendsListTypes().map { converter.convertType(it) }) + classParameter.getExtendsListTypes().map { typeConverter.convertType(it) }) } override fun visitParameterList(list: PsiParameterList) { diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt index 14acb476896..4d45237b26c 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/ExpressionVisitor.kt @@ -34,8 +34,9 @@ import org.jetbrains.jet.lang.psi.psiUtil.isExtensionDeclaration import org.jetbrains.jet.lang.psi.JetPropertyAccessor import com.intellij.psi.impl.light.LightField -open class ExpressionVisitor(protected val converter: Converter, - private val usageReplacementMap: Map = mapOf()) : JavaElementVisitor() { +class ExpressionVisitor(private val converter: Converter, + private val typeConverter: TypeConverter, + private val usageReplacementMap: Map = mapOf()) : JavaElementVisitor() { public var result: Expression = Expression.Empty protected set @@ -48,7 +49,7 @@ open class ExpressionVisitor(protected val converter: Converter, } override fun visitArrayInitializerExpression(expression: PsiArrayInitializerExpression) { - val expressionType = converter.convertType(expression.getType()) + val expressionType = typeConverter.convertType(expression.getType()) assert(expressionType is ArrayType, "Array initializer must have array type") result = ArrayInitializerExpression(expressionType as ArrayType, converter.convertExpressions(expression.getInitializers())) @@ -192,14 +193,14 @@ open class ExpressionVisitor(protected val converter: Converter, val qualifier = converter.convertExpression(arguments.firstOrNull()) MethodCallExpression(QualifiedExpression(qualifier, Identifier(origin.getName()!!, false)), convertArguments(expression, isExtension = true), - converter.convertTypes(expression.getTypeArguments()), - converter.convertType(expression.getType()).isNullable) + typeConverter.convertTypes(expression.getTypeArguments()), + typeConverter.convertType(expression.getType()).isNullable) } else { MethodCallExpression(Identifier(origin.getName()!!, false), convertArguments(expression), - converter.convertTypes(expression.getTypeArguments()), - converter.convertType(expression.getType()).isNullable) + typeConverter.convertTypes(expression.getTypeArguments()), + typeConverter.convertType(expression.getType()).isNullable) } return } @@ -209,8 +210,8 @@ open class ExpressionVisitor(protected val converter: Converter, result = MethodCallExpression(converter.convertExpression(methodExpr), convertArguments(expression), - converter.convertTypes(expression.getTypeArguments()), - converter.convertType(expression.getType()).isNullable) + typeConverter.convertTypes(expression.getTypeArguments()), + typeConverter.convertType(expression.getType()).isNullable) } override fun visitNewExpression(expression: PsiNewExpression) { @@ -240,14 +241,14 @@ open class ExpressionVisitor(protected val converter: Converter, } val reference = expression.getClassReference() - val typeParameters = if (reference != null) converter.convertTypes(reference.getTypeParameters()) else listOf() + val typeParameters = if (reference != null) typeConverter.convertTypes(reference.getTypeParameters()) else listOf() return QualifiedExpression(Identifier(constructor.getName(), false), MethodCallExpression(Identifier("init"), converter.convertExpressions(arguments), typeParameters, false)) } private fun createNewEmptyArrayWithoutInitialization(expression: PsiNewExpression): Expression { return ArrayWithoutInitializationExpression( - converter.convertType(expression.getType(), Nullability.NotNull), + typeConverter.convertType(expression.getType(), Nullability.NotNull), converter.convertExpressions(expression.getArrayDimensions())) } @@ -276,7 +277,7 @@ open class ExpressionVisitor(protected val converter: Converter, } override fun visitReferenceExpression(expression: PsiReferenceExpression) { - val isNullable = converter.convertType(expression.getType(), expression.nullability()).isNullable + val isNullable = typeConverter.convertType(expression.getType(), expression.nullability()).isNullable val referencedName = expression.getReferenceName()!! var identifier: Expression = Identifier(referencedName, isNullable) val qualifier = expression.getQualifierExpression() @@ -368,7 +369,7 @@ open class ExpressionVisitor(protected val converter: Converter, result = MethodCallExpression.build(converter.convertExpression(operand), typeConversion) } else { - result = TypeCastExpression(converter.convertType(castType.getType()), + result = TypeCastExpression(typeConverter.convertType(castType.getType()), converter.convertExpression(operand)) } } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt index 3ab3a7fc326..db3ce2944fc 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.kt @@ -18,16 +18,16 @@ package org.jetbrains.jet.j2k.visitors import com.intellij.psi.* import com.intellij.psi.impl.source.PsiClassReferenceType -import org.jetbrains.jet.j2k.Converter import org.jetbrains.jet.j2k.ast.* import java.util.LinkedList import com.intellij.openapi.util.text.StringUtil import java.util.ArrayList import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType +import org.jetbrains.jet.j2k.TypeConverter private val PRIMITIVE_TYPES_NAMES = JvmPrimitiveType.values().map { it.getName() } -open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor() { +open class TypeVisitor(private val converter: TypeConverter) : PsiTypeVisitor() { override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type { val name = primitiveType.getCanonicalText() return if (name == "void") { @@ -42,7 +42,7 @@ open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor( } override fun visitArrayType(arrayType: PsiArrayType): Type { - return ArrayType(converter.convertType(arrayType.getComponentType()), Nullability.Default, converter) + return ArrayType(converter.convertType(arrayType.getComponentType()), Nullability.Default, converter.settings) } override fun visitClassType(classType: PsiClassType): Type { @@ -53,18 +53,18 @@ open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor( if (resolvedClassTypeParams.size() == 1) { if ((resolvedClassTypeParams.single() as ClassType).`type`.name == "Any") { starParamList.add(StarProjectionType()) - return ClassType(identifier, starParamList, Nullability.Default, converter) + return ClassType(identifier, starParamList, Nullability.Default, converter.settings) } else { - return ClassType(identifier, resolvedClassTypeParams, Nullability.Default, converter) + return ClassType(identifier, resolvedClassTypeParams, Nullability.Default, converter.settings) } } else { - return ClassType(identifier, resolvedClassTypeParams, Nullability.Default, converter) + return ClassType(identifier, resolvedClassTypeParams, Nullability.Default, converter.settings) } } else { - return ClassType(identifier, converter.convertTypes(classType.getParameters()), Nullability.Default, converter) + return ClassType(identifier, converter.convertTypes(classType.getParameters()), Nullability.Default, converter.settings) } } @@ -99,7 +99,7 @@ open class TypeVisitor(private val converter: Converter) : PsiTypeVisitor( ClassType(Identifier(getClassTypeName(superTypes[0])), converter.convertTypes(superTypes[0].getParameters()), Nullability.Default, - converter) + converter.settings) else StarProjectionType() typeParams.add(boundType)