Java to Kotlin converter: code refactoring - extracted some code from Converter into TypeConverter
This commit is contained in:
@@ -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<String> = 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<PsiMember>): 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<Type>(TypeVisitor(this))!!
|
||||
return when (nullability) {
|
||||
Nullability.NotNull -> result.toNotNullType()
|
||||
Nullability.Nullable -> result.toNullableType()
|
||||
Nullability.Default -> result
|
||||
}
|
||||
}
|
||||
|
||||
public fun convertTypes(types: Array<PsiType>): List<Type> {
|
||||
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<out PsiType?>): List<Type>
|
||||
= 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<Modifier> = listOf()): Parameter {
|
||||
var `type` = convertVariableType(parameter)
|
||||
var `type` = typeConverter.convertVariableType(parameter)
|
||||
when (nullability) {
|
||||
Nullability.NotNull -> `type` = `type`.toNotNullType()
|
||||
Nullability.Nullable -> `type` = `type`.toNullableType()
|
||||
|
||||
@@ -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<Type>(TypeVisitor(this))!!
|
||||
return when (nullability) {
|
||||
Nullability.NotNull -> result.toNotNullType()
|
||||
Nullability.Nullable -> result.toNullableType()
|
||||
Nullability.Default -> result
|
||||
}
|
||||
}
|
||||
|
||||
public fun convertTypes(types: Array<PsiType>): List<Type> {
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ class SecondaryConstructor(converter: Converter,
|
||||
val typeParameters = ArrayList<TypeParameter>()
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Element>, nullability: Nullability, converter: Converter)
|
||||
: MayBeNullableType(nullability, converter) {
|
||||
open class ClassType(val `type`: Identifier, val parameters: List<Element>, 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<Element>, 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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<PsiVariable, String> = mapOf()) : JavaElementVisitor() {
|
||||
class ExpressionVisitor(private val converter: Converter,
|
||||
private val typeConverter: TypeConverter,
|
||||
private val usageReplacementMap: Map<PsiVariable, String> = 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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Type>() {
|
||||
open class TypeVisitor(private val converter: TypeConverter) : PsiTypeVisitor<Type>() {
|
||||
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<Type>(
|
||||
}
|
||||
|
||||
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<Type>(
|
||||
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<Type>(
|
||||
ClassType(Identifier(getClassTypeName(superTypes[0])),
|
||||
converter.convertTypes(superTypes[0].getParameters()),
|
||||
Nullability.Default,
|
||||
converter)
|
||||
converter.settings)
|
||||
else
|
||||
StarProjectionType()
|
||||
typeParams.add(boundType)
|
||||
|
||||
Reference in New Issue
Block a user