From b2002d56bdf27bd709d642c38bb8cce4805af3da Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Mon, 9 Sep 2019 09:55:28 +0300 Subject: [PATCH] New J2K: move type calculation to expression node --- .../kotlin/nj2k/JavaToJKTreeBuilder.kt | 47 ++++++---- .../jetbrains/kotlin/nj2k/NewCodeBuilder.kt | 2 +- .../conversions/ArrayInitializerConversion.kt | 4 +- .../conversions/ArrayOperationsConversion.kt | 4 +- .../conversions/BuiltinMembersConversion.kt | 9 +- .../kotlin/nj2k/conversions/ForConversion.kt | 12 +-- .../conversions/ImplicitCastsConversion.kt | 1 + .../JavaStandardMethodsConversion.kt | 3 +- .../MethodReferenceToLambdaConversion.kt | 28 +++++- .../OperatorExpressionConversion.kt | 5 +- ...eterModificationInMethodCallsConversion.kt | 2 +- .../nj2k/conversions/TypeMappingConversion.kt | 6 +- .../org/jetbrains/kotlin/nj2k/expressions.kt | 2 + .../kotlin/nj2k/symbols/JKFieldSymbol.kt | 12 +-- .../kotlin/nj2k/symbols/JKMethodSymbol.kt | 14 +-- .../kotlin/nj2k/tree/declarations.kt | 9 +- .../jetbrains/kotlin/nj2k/tree/expressions.kt | 93 +++++++++++-------- .../kotlin/nj2k/types/JKTypeFactory.kt | 3 + .../org/jetbrains/kotlin/nj2k/types/types.kt | 15 +-- .../jetbrains/kotlin/nj2k/types/typesUtils.kt | 62 ++----------- 20 files changed, 159 insertions(+), 174 deletions(-) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt index 4892012f4a8..72b5fccdebf 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt @@ -60,8 +60,10 @@ class JavaToJKTreeBuilder constructor( converterServices: NewJavaToKotlinServices, private val importStorage: ImportStorage ) { - private fun PsiType.toJK() = - typeFactory.fromPsiType(this) + private fun PsiType?.toJK(): JKType { + if (this == null) return JKNoType + return typeFactory.fromPsiType(this) + } private val expressionTreeMapper = ExpressionTreeMapper() @@ -128,14 +130,19 @@ class JavaToJKTreeBuilder constructor( is PsiInstanceOfExpression -> toJK() is PsiThisExpression -> JKThisExpression( - qualifier?.referenceName?.let { JKLabelText(JKNameIdentifier(it)) } ?: JKLabelEmpty() + qualifier?.referenceName?.let { JKLabelText(JKNameIdentifier(it)) } ?: JKLabelEmpty(), + type.toJK() ) is PsiSuperExpression -> JKSuperExpression( - qualifier?.referenceName?.let { JKLabelText(JKNameIdentifier(it)) } ?: JKLabelEmpty() + qualifier?.referenceName?.let { JKLabelText(JKNameIdentifier(it)) } ?: JKLabelEmpty(), + type.toJK() ) is PsiConditionalExpression -> JKIfElseExpression( - condition.toJK(), thenExpression.toJK(), elseExpression.toJK() + condition.toJK(), + thenExpression.toJK(), + elseExpression.toJK(), + type.toJK() ) is PsiPolyadicExpression -> { val token = JKOperatorToken.fromElementType(operationTokenType) @@ -175,7 +182,7 @@ class JavaToJKTreeBuilder constructor( } fun PsiInstanceOfExpression.toJK(): JKIsExpression = - JKIsExpression(operand.toJK(), JKTypeElement(checkType?.type?.toJK() ?: JKNoTypeImpl)) + JKIsExpression(operand.toJK(), JKTypeElement(checkType?.type?.toJK() ?: JKNoType)) .also { it.assignNonCodeElements(this) } @@ -293,8 +300,8 @@ class JavaToJKTreeBuilder constructor( return when { methodExpression.referenceNameElement is PsiKeyword -> { val callee = when ((methodExpression.referenceNameElement as PsiKeyword).tokenType) { - SUPER_KEYWORD -> JKSuperExpression() - THIS_KEYWORD -> JKThisExpression(JKLabelEmpty()) + SUPER_KEYWORD -> JKSuperExpression(JKLabelEmpty(), JKNoType) + THIS_KEYWORD -> JKThisExpression(JKLabelEmpty(), JKNoType) else -> throwCanNotConvertError("unknown keyword in callee position") } JKDelegationConstructorCall(symbol as JKMethodSymbol, callee, arguments.toJK()) @@ -337,7 +344,7 @@ class JavaToJKTreeBuilder constructor( propertyAccessExpression ) else propertyAccessExpression - } else propertyAccessExpression.qualified(qualifier) as JKExpression + } else propertyAccessExpression.qualified(qualifier) when (if (isExtension) parameterCount - 1 else parameterCount) { 0 /* getter */ -> @@ -383,7 +390,7 @@ class JavaToJKTreeBuilder constructor( }?.takeUnless { type -> type.isKotlinFunctionalType }?.toJK() - ?.asTypeElement() ?: JKTypeElement(JKNoTypeImpl) + ?.asTypeElement() ?: JKTypeElement(JKNoType) fun PsiMethodReferenceExpression.toJK(): JKMethodReferenceExpression { val symbol = symbolProvider.provideSymbolForReference(this).let { symbol -> @@ -494,14 +501,15 @@ class JavaToJKTreeBuilder constructor( } - fun PsiArrayAccessExpression.toJK(): JKExpression { - return JKArrayAccessExpression( - arrayExpression.toJK(), - indexExpression?.toJK() ?: throwCanNotConvertError() - ).also { - it.assignNonCodeElements(this) - } - } + fun PsiArrayAccessExpression.toJK(): JKExpression = + arrayExpression.toJK() + .callOn( + symbolProvider.provideMethodSymbol("kotlin.Array.get"), + arguments = listOf(indexExpression?.toJK() ?: JKStubExpression()) + ).also { + it.assignNonCodeElements(this) + } + fun PsiTypeCastExpression.toJK(): JKExpression { return JKTypeCastExpression( @@ -622,7 +630,7 @@ class JavaToJKTreeBuilder constructor( with(expressionTreeMapper) { argumentList?.toJK() ?: JKArgumentList() }, initializingClass?.createClassBody() ?: JKClassBody(), JKTypeElement( - JKClassTypeImpl( + JKClassType( symbolProvider.provideDirectSymbol(containingClass ?: throwCanNotConvertError()) as JKClassSymbol, emptyList() ) @@ -784,7 +792,6 @@ class JavaToJKTreeBuilder constructor( ).also { symbolProvider.provideUniverseSymbol(this, it) it.psi = this - }.also { it.assignNonCodeElements(this) } } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt index 205654a3ee3..8b40e235c60 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt @@ -904,7 +904,7 @@ private class JKPrinter( } fun renderType(type: JKType, owner: JKTreeElement?) { - if (type is JKNoTypeImpl) return + if (type is JKNoType) return if (type is JKCapturedType) { when (val wildcard = type.wildcardType) { is JKVarianceTypeParameterType -> { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt index 3b120b2b925..2f7561f802b 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt @@ -75,13 +75,13 @@ class ArrayInitializerConversion(context: NewJ2kConverterContext) : RecursiveApp JKTypeArgumentList(listOf(JKTypeElement(arrayType))) ) } - var resultType = JKClassTypeImpl( + var resultType = JKClassType( symbolProvider.provideClassSymbol(type.arrayFqName()), if (type is JKJavaPrimitiveType) emptyList() else listOf(type), Nullability.Default ) for (i in 0 until dimensions.size - 2) { - resultType = JKClassTypeImpl( + resultType = JKClassType( symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.array.toSafe()), listOf(resultType), Nullability.Default diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt index d4d8289b199..36899018b4d 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt @@ -13,9 +13,7 @@ package org.jetbrains.kotlin.nj2k.conversions import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext import org.jetbrains.kotlin.nj2k.symbols.JKUniverseFieldSymbol import org.jetbrains.kotlin.nj2k.tree.* - import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType -import org.jetbrains.kotlin.nj2k.types.type import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -34,7 +32,7 @@ class ArrayOperationsConversion(context: NewJ2kConverterContext) : RecursiveAppl } private fun JKExpression.isArrayOrVarargTypeParameter(): Boolean { - if (type(typeFactory) is JKJavaArrayType) return true + if (calculateType(typeFactory) is JKJavaArrayType) return true val parameter = safeAs() ?.identifier diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt index aadb5d2c466..da5c986db28 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.nj2k.symbols.deepestFqName import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.types.isArrayType import org.jetbrains.kotlin.nj2k.types.isStringType -import org.jetbrains.kotlin.nj2k.types.type import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -268,7 +267,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli Method("java.lang.String.indexOf") convertTo Method("kotlin.text.indexOf"), Method("java.lang.String.lastIndexOf") convertTo Method("kotlin.text.lastIndexOf"), Method("java.lang.String.getBytes") convertTo Method("kotlin.text.toByteArray") - withByArgumentsFilter { it.singleOrNull()?.type(typeFactory)?.isStringType() == true } + withByArgumentsFilter { it.singleOrNull()?.calculateType(typeFactory)?.isStringType() == true } withArgumentsProvider { arguments -> val argument = arguments.arguments.single()::value.detached() val call = JKCallExpressionImpl( @@ -281,7 +280,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli Method("java.lang.String.valueOf") convertTo ExtensionMethod("kotlin.Any.toString") withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER - withByArgumentsFilter { it.isNotEmpty() && it.first().type(typeFactory)?.isArrayType() == false }, + withByArgumentsFilter { it.isNotEmpty() && it.first().calculateType(typeFactory)?.isArrayType() == false }, Method("java.lang.String.getChars") convertTo Method("kotlin.text.toCharArray") @@ -297,12 +296,12 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli Method("java.lang.String.valueOf") convertTo Method("kotlin.String") withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER - withByArgumentsFilter { it.isNotEmpty() && it.first().type(typeFactory)?.isArrayType() == true }, + withByArgumentsFilter { it.isNotEmpty() && it.first().calculateType(typeFactory)?.isArrayType() == true }, Method("java.lang.String.copyValueOf") convertTo Method("kotlin.String") withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER - withByArgumentsFilter { it.isNotEmpty() && it.first().type(typeFactory)?.isArrayType() == true }, + withByArgumentsFilter { it.isNotEmpty() && it.first().calculateType(typeFactory)?.isArrayType() == true }, Method("java.lang.String.replaceAll") convertTo Method("kotlin.text.replace") diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt index 8ef9d3d1543..d9701d7139d 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt @@ -16,8 +16,7 @@ import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType -import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl -import org.jetbrains.kotlin.nj2k.types.type +import org.jetbrains.kotlin.nj2k.types.JKNoType import kotlin.math.abs @@ -136,11 +135,11 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver KtTokens.EXCLEQ -> false else -> return null } - val range = forIterationRange(start, right, reversed, inclusive, loopVarPsi) + val range = forIterationRange(start, right, reversed, inclusive) val explicitType = if (context.converter.settings.specifyLocalVariableTypeByDefault) JKJavaPrimitiveType.INT - else JKNoTypeImpl + else JKNoType val loopVarDeclaration = JKForLoopVariable( JKTypeElement(explicitType), @@ -169,8 +168,7 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver start: JKExpression, bound: JKExpression, reversed: Boolean, - inclusiveComparison: Boolean, - psiContext: PsiElement + inclusiveComparison: Boolean ): JKExpression { indicesIterationRange(start, bound, reversed, inclusiveComparison)?.also { return it } return when { @@ -262,7 +260,7 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver private fun indicesByArrayLength(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? { val methodCall = javaSizeCall.selector as? JKFieldAccessExpression ?: return null - val receiverType = javaSizeCall.receiver.type(typeFactory) + val receiverType = javaSizeCall.receiver.calculateType(typeFactory) if (methodCall.identifier.name == "length" && receiverType is JKJavaArrayType) { return toIndicesCall(javaSizeCall) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt index cdbb9a3b5c9..d3366ccbdec 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt @@ -149,6 +149,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic ) } + private fun JKExpression.castTo(toType: JKType, strict: Boolean = false): JKExpression? { val expressionType = calculateType(typeFactory) if (expressionType == toType) return null diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt index 64da08fa966..0dff413a8ef 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedClassSymbol import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.types.JKClassType -import org.jetbrains.kotlin.nj2k.types.JKClassTypeImpl import org.jetbrains.kotlin.nj2k.types.JKJavaVoidType import org.jetbrains.kotlin.nj2k.types.updateNullability @@ -36,7 +35,7 @@ class JavaStandardMethodsConversion(context: NewJ2kConverterContext) : Recursive if (hasNoCloneableInSuperClasses) { element.inheritance.implements += JKTypeElement( - JKClassTypeImpl( + JKClassType( JKUnresolvedClassSymbol("Cloneable", typeFactory), emptyList(), Nullability.NotNull ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt index c0e900c244b..a92eecce578 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.nj2k.conversions import com.intellij.lang.jvm.JvmModifier +import com.intellij.psi.PsiModifier import org.jetbrains.kotlin.codegen.kotlinType import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext @@ -14,6 +15,7 @@ import org.jetbrains.kotlin.nj2k.qualified import org.jetbrains.kotlin.nj2k.symbols.* import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.types.* +import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -37,7 +39,7 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur ?.let { classAccessExpression -> JKParameter( JKTypeElement( - parametersTypesByFunctionalInterface?.firstOrNull() ?: JKClassTypeImpl(classAccessExpression.identifier) + parametersTypesByFunctionalInterface?.firstOrNull() ?: JKClassType(classAccessExpression.identifier) ), JKNameIdentifier(RECEIVER_NAME), isVarArgs = false @@ -90,8 +92,8 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur element::functionalType.detached(), JKTypeElement( when (symbol) { - is JKMethodSymbol -> symbol.returnType ?: JKNoTypeImpl - is JKClassSymbol -> JKClassTypeImpl(symbol) + is JKMethodSymbol -> symbol.returnType ?: JKNoType + is JKClassSymbol -> JKClassType(symbol) is JKUnresolvedSymbol -> return recurse(element) else -> error("Symbol should be either method symbol or class symbol, but it is ${symbol::class}") } @@ -127,6 +129,26 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur } } + + private val JKMethodSymbol.isStatic: Boolean + get() = when (this) { + is JKMultiverseFunctionSymbol -> target.parent is KtObjectDeclaration + is JKMultiverseMethodSymbol -> target.hasModifierProperty(PsiModifier.STATIC) + is JKUniverseMethodSymbol -> target.parent?.parent?.safeAs()?.classKind == JKClass.ClassKind.COMPANION + is JKUnresolvedMethod -> false + } + + private val JKMethodSymbol.parameterNames: List? + get() { + return when (this) { + is JKMultiverseFunctionSymbol -> target.valueParameters.map { it.name ?: return null } + is JKMultiverseMethodSymbol -> target.parameters.map { it.name ?: return null } + is JKUniverseMethodSymbol -> target.parameters.map { it.name.value } + is JKUnresolvedMethod -> null + } + } + + companion object { private const val RECEIVER_NAME = "obj" //name taken from old j2k } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt index 69cc77ad6a1..60324605bf5 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt @@ -9,15 +9,14 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext import org.jetbrains.kotlin.nj2k.callOn import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.types.isStringType -import org.jetbrains.kotlin.nj2k.types.type class AnyWithStringConcatenationConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) { override fun applyToElement(element: JKTreeElement): JKTreeElement { if (element !is JKBinaryExpression) return recurse(element) if (element.operator.token == JKOperatorToken.PLUS - && element.right.type(typeFactory)?.isStringType() == true - && element.left.type(typeFactory)?.isStringType() == false + && element.right.calculateType(typeFactory).isStringType() + && !element.left.calculateType(typeFactory).isStringType() ) { return recurse( JKBinaryExpression( diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt index 9651443eabc..26b5968f433 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt @@ -20,7 +20,7 @@ class ParameterModificationInMethodCallsConversion(context: NewJ2kConverterConte if (parameter.hasWritableUsages(element.block, context)) { val parameterType = if (parameter.isVarArgs) { - JKClassTypeImpl( + JKClassType( symbolProvider.provideClassSymbol(parameter.type.type.arrayFqName()), if (parameter.type.type is JKJavaPrimitiveType) emptyList() else listOf( diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt index 546d50ef1fb..20ffd213bb5 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt @@ -74,7 +74,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab is JKJavaVoidType -> typeFactory.types.unit is JKJavaArrayType -> - JKClassTypeImpl( + JKClassType( symbolProvider.provideClassSymbol(type.arrayFqName()), if (type is JKJavaPrimitiveType) emptyList() else listOf(type.mapType(typeElement)), nullability @@ -102,7 +102,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab } private fun JKClassType.mapClassType(): JKClassType = - JKClassTypeImpl( + JKClassType( classReference.mapClassSymbol(), parameters.map { it.mapType(null) }, nullability @@ -123,7 +123,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab if (this is JKClassType && parameters.isEmpty()) { val parametersCount = classReference.expectedTypeParametersCount() val typeParameters = List(parametersCount) { typeParameter } - JKClassTypeImpl( + JKClassType( classReference, typeParameters, nullability diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt index c850fb14655..1cb4ce25f40 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt @@ -12,6 +12,8 @@ import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedMethod import org.jetbrains.kotlin.nj2k.tree.* + + import org.jetbrains.kotlin.nj2k.types.JKNoType import org.jetbrains.kotlin.nj2k.types.JKType import org.jetbrains.kotlin.nj2k.types.JKTypeFactory diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt index 482d7eba556..498dc85bda4 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt @@ -7,13 +7,9 @@ package org.jetbrains.kotlin.nj2k.symbols import com.intellij.psi.PsiVariable -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.j2k.ast.Nullability import org.jetbrains.kotlin.nj2k.tree.JKVariable -import org.jetbrains.kotlin.nj2k.types.toJK -import org.jetbrains.kotlin.nj2k.types.JKClassTypeImpl -import org.jetbrains.kotlin.nj2k.types.JKType -import org.jetbrains.kotlin.nj2k.types.JKTypeFactory +import org.jetbrains.kotlin.nj2k.types.* import org.jetbrains.kotlin.psi.KtCallableDeclaration import org.jetbrains.kotlin.psi.KtEnumEntry import org.jetbrains.kotlin.psi.psiUtil.containingClass @@ -22,7 +18,7 @@ sealed class JKFieldSymbol : JKSymbol { abstract val fieldType: JKType? } -class JKUniverseFieldSymbol( override val typeFactory: JKTypeFactory) : JKFieldSymbol(), JKUniverseSymbol { +class JKUniverseFieldSymbol(override val typeFactory: JKTypeFactory) : JKFieldSymbol(), JKUniverseSymbol { override val fieldType: JKType get() = target.type.type @@ -50,7 +46,7 @@ class JKMultiverseKtEnumEntrySymbol( override val typeFactory: JKTypeFactory ) : JKFieldSymbol(), JKMultiverseKtSymbol { override val fieldType: JKType? - get() = JKClassTypeImpl( + get() = JKClassType( symbolProvider.provideDirectSymbol(target.containingClass()!!) as JKClassSymbol, emptyList(), Nullability.NotNull @@ -62,6 +58,6 @@ class JKUnresolvedField( override val typeFactory: JKTypeFactory ) : JKFieldSymbol(), JKUnresolvedSymbol { override val fieldType: JKType - get() = JKClassTypeImpl(symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.nothing.toSafe()), emptyList()) + get() = typeFactory.types.nullableAny } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt index 4e7cb15baf3..afa259cfe64 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt @@ -16,8 +16,8 @@ import org.jetbrains.kotlin.nj2k.tree.JKClass import org.jetbrains.kotlin.nj2k.tree.JKMethod import org.jetbrains.kotlin.nj2k.types.asType import org.jetbrains.kotlin.nj2k.types.toJK -import org.jetbrains.kotlin.nj2k.types.JKClassTypeImpl -import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl +import org.jetbrains.kotlin.nj2k.types.JKClassType +import org.jetbrains.kotlin.nj2k.types.JKNoType import org.jetbrains.kotlin.nj2k.types.JKType import org.jetbrains.kotlin.nj2k.types.JKTypeFactory import org.jetbrains.kotlin.psi.KtFunction @@ -32,7 +32,7 @@ sealed class JKMethodSymbol : JKSymbol { class JKUniverseMethodSymbol(override val typeFactory: JKTypeFactory) : JKMethodSymbol(), JKUniverseSymbol { override val receiverType: JKType? get() = target.parent.safeAs()?.let { - JKClassTypeImpl(symbolProvider.provideUniverseSymbol(it), emptyList()/*TODO*/) + JKClassType(symbolProvider.provideUniverseSymbol(it), emptyList()) } override val parameterTypes: List get() = target.parameters.map { it.type.type } @@ -48,7 +48,7 @@ class JKMultiverseMethodSymbol( ) : JKMethodSymbol(), JKMultiverseSymbol { override val receiverType: JKType? get() = target.containingClass?.let { - JKClassTypeImpl(symbolProvider.provideDirectSymbol(it) as JKClassSymbol, emptyList()/*TODO*/) + JKClassType(symbolProvider.provideDirectSymbol(it) as JKClassSymbol, emptyList()) } override val parameterTypes: List get() = target.parameterList.parameters.map { typeFactory.fromPsiType(it.type) } @@ -76,7 +76,7 @@ class JKMultiverseFunctionSymbol( val type = parameter.typeReference?.toJK(typeFactory) type?.let { if (parameter.isVarArg) { - JKClassTypeImpl( + JKClassType( symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.array.toSafe()), listOf(it) ) @@ -91,12 +91,12 @@ class JKMultiverseFunctionSymbol( class JKUnresolvedMethod( override val target: String, override val typeFactory: JKTypeFactory, - override val returnType: JKType = JKNoTypeImpl + override val returnType: JKType = JKNoType ) : JKMethodSymbol(), JKUnresolvedSymbol { constructor(target: PsiReference, typeFactory: JKTypeFactory) : this(target.canonicalText, typeFactory) override val receiverType: JKType? - get() = null + get() = typeFactory.types.nullableAny override val parameterTypes: List get() = emptyList() } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/declarations.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/declarations.kt index fadf87c058d..7a9547709d2 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/declarations.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/declarations.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.nj2k.tree import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor -import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl +import org.jetbrains.kotlin.nj2k.types.JKNoType abstract class JKDeclaration : JKTreeElement(), PsiOwner by PsiOwnerImpl() { abstract val name: JKNameIdentifier @@ -168,15 +168,13 @@ class JKConstructorImpl( visibilityElement: JKVisibilityModifierElement, modalityElement: JKModalityModifierElement ) : JKConstructor() { - override var returnType: JKTypeElement by child(JKTypeElement(JKNoTypeImpl)) - + override var returnType: JKTypeElement by child(JKTypeElement(JKNoType)) override var name: JKNameIdentifier by child(name) override var parameters: List by children(parameters) override var block: JKBlock by child(block) override var delegationCall: JKExpression by child(delegationCall) override var typeParameterList: JKTypeParameterList by child(JKTypeParameterList()) override var annotationList: JKAnnotationList by child(annotationList) - override var otherModifierElements by children(otherModifierElements) override var visibilityElement by child(visibilityElement) override var modalityElement by child(modalityElement) @@ -194,8 +192,7 @@ class JKKtPrimaryConstructor( visibilityElement: JKVisibilityModifierElement, modalityElement: JKModalityModifierElement ) : JKConstructor() { - override var returnType: JKTypeElement by child(JKTypeElement(JKNoTypeImpl)) - + override var returnType: JKTypeElement by child(JKTypeElement(JKNoType)) override var name: JKNameIdentifier by child(name) override var parameters: List by children(parameters) override var block: JKBlock by child(JKBodyStub) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt index 8f8bc07a685..ec6396686fe 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt @@ -9,14 +9,16 @@ import org.jetbrains.kotlin.nj2k.symbols.* import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor -import org.jetbrains.kotlin.nj2k.types.JKContextType -import org.jetbrains.kotlin.nj2k.types.JKNoTypeImpl -import org.jetbrains.kotlin.nj2k.types.JKType +import org.jetbrains.kotlin.nj2k.types.* -abstract class JKExpression : JKAnnotationMemberValue(), PsiOwner by PsiOwnerImpl() +abstract class JKExpression : JKAnnotationMemberValue(), PsiOwner by PsiOwnerImpl() { + // we don't need exact type here (eg with substituted type parameters) + abstract fun calculateType(typeFactory: JKTypeFactory): JKType +} abstract class JKOperatorExpression : JKExpression() { abstract var operator: JKOperator + override fun calculateType(typeFactory: JKTypeFactory) = operator.returnType } class JKBinaryExpression( @@ -50,31 +52,20 @@ class JKQualifiedExpression( ) : JKExpression() { var receiver: JKExpression by child(receiver) var selector: JKExpression by child(selector) - + override fun calculateType(typeFactory: JKTypeFactory) = selector.calculateType(typeFactory) override fun accept(visitor: JKVisitor) = visitor.visitQualifiedExpression(this) } -class JKArrayAccessExpression( - expression: JKExpression, - indexExpression: JKExpression -) : JKExpression() { - var expression: JKExpression by child(expression) - var indexExpression: JKExpression by child(indexExpression) - - override fun accept(visitor: JKVisitor) = visitor.visitArrayAccessExpression(this) -} - - class JKParenthesizedExpression(expression: JKExpression) : JKExpression() { var expression: JKExpression by child(expression) - + override fun calculateType(typeFactory: JKTypeFactory) = expression.calculateType(typeFactory) override fun accept(visitor: JKVisitor) = visitor.visitParenthesizedExpression(this) } class JKTypeCastExpression(expression: JKExpression, type: JKTypeElement) : JKExpression() { var expression by child(expression) var type by child(type) - + override fun calculateType(typeFactory: JKTypeFactory) = type.type override fun accept(visitor: JKVisitor) = visitor.visitTypeCastExpression(this) } @@ -84,38 +75,57 @@ class JKLiteralExpression( ) : JKExpression() { override fun accept(visitor: JKVisitor) = visitor.visitLiteralExpression(this) + override fun calculateType(typeFactory: JKTypeFactory) = when (type) { + LiteralType.CHAR -> typeFactory.types.char + LiteralType.BOOLEAN -> typeFactory.types.boolean + LiteralType.INT -> typeFactory.types.int + LiteralType.LONG -> typeFactory.types.long + LiteralType.FLOAT -> typeFactory.types.float + LiteralType.DOUBLE -> typeFactory.types.double + LiteralType.NULL -> typeFactory.types.nullableAny + LiteralType.STRING -> typeFactory.types.string + } + enum class LiteralType { STRING, CHAR, BOOLEAN, NULL, INT, LONG, FLOAT, DOUBLE } } class JKStubExpression : JKExpression() { + override fun calculateType(typeFactory: JKTypeFactory) = JKNoType override fun accept(visitor: JKVisitor) = visitor.visitStubExpression(this) } -class JKThisExpression(qualifierLabel: JKLabel) : JKExpression() { +class JKThisExpression(qualifierLabel: JKLabel, private val type: JKType) : JKExpression() { var qualifierLabel: JKLabel by child(qualifierLabel) - + override fun calculateType(typeFactory: JKTypeFactory) = type override fun accept(visitor: JKVisitor) = visitor.visitThisExpression(this) } -class JKSuperExpression(qualifierLabel: JKLabel = JKLabelEmpty()) : JKExpression() { +class JKSuperExpression(qualifierLabel: JKLabel, private val type: JKType) : JKExpression() { var qualifierLabel: JKLabel by child(qualifierLabel) + override fun calculateType(typeFactory: JKTypeFactory) = type override fun accept(visitor: JKVisitor) = visitor.visitSuperExpression(this) } -class JKIfElseExpression(condition: JKExpression, thenBranch: JKExpression, elseBranch: JKExpression) : JKExpression() { +class JKIfElseExpression( + condition: JKExpression, + thenBranch: JKExpression, + elseBranch: JKExpression, + private val type: JKType +) : JKExpression() { var condition by child(condition) var thenBranch by child(thenBranch) var elseBranch by child(elseBranch) + override fun calculateType(typeFactory: JKTypeFactory): JKType = type override fun accept(visitor: JKVisitor) = visitor.visitIfElseExpression(this) } class JKLambdaExpression( statement: JKStatement, parameters: List, - functionalType: JKTypeElement = JKTypeElement(JKNoTypeImpl), + functionalType: JKTypeElement = JKTypeElement(JKNoType), returnType: JKTypeElement = JKTypeElement(JKContextType) ) : JKExpression() { var statement by child(statement) @@ -123,6 +133,7 @@ class JKLambdaExpression( var functionalType by child(functionalType) val returnType by child(returnType) + override fun calculateType(typeFactory: JKTypeFactory): JKType = JKNoType override fun accept(visitor: JKVisitor) = visitor.visitLambdaExpression(this) } @@ -130,6 +141,7 @@ class JKLambdaExpression( abstract class JKCallExpression : JKExpression(), JKTypeArgumentListOwner { abstract val identifier: JKMethodSymbol abstract var arguments: JKArgumentList + override fun calculateType(typeFactory: JKTypeFactory): JKType = identifier.returnType ?: JKNoType } class JKDelegationConstructorCall( @@ -140,7 +152,6 @@ class JKDelegationConstructorCall( override var typeArgumentList: JKTypeArgumentList by child(JKTypeArgumentList()) val expression: JKExpression by child(expression) override var arguments: JKArgumentList by child(arguments) - override fun accept(visitor: JKVisitor) = visitor.visitDelegationConstructorCall(this) } @@ -164,20 +175,24 @@ class JKNewExpression( var typeArgumentList by child(typeArgumentList) var arguments by child(arguments) var classBody by child(classBody) + override fun calculateType(typeFactory: JKTypeFactory) = classSymbol.asType() override fun accept(visitor: JKVisitor) = visitor.visitNewExpression(this) } class JKFieldAccessExpression(var identifier: JKFieldSymbol) : JKExpression() { + override fun calculateType(typeFactory: JKTypeFactory) = identifier.fieldType ?: JKNoType override fun accept(visitor: JKVisitor) = visitor.visitFieldAccessExpression(this) } class JKPackageAccessExpression(var identifier: JKPackageSymbol) : JKExpression() { + override fun calculateType(typeFactory: JKTypeFactory) = JKNoType override fun accept(visitor: JKVisitor) = visitor.visitPackageAccessExpression(this) } class JKClassAccessExpression(var identifier: JKClassSymbol) : JKExpression() { + override fun calculateType(typeFactory: JKTypeFactory) = JKNoType override fun accept(visitor: JKVisitor) = visitor.visitClassAccessExpression(this) } @@ -189,7 +204,7 @@ class JKMethodReferenceExpression( ) : JKExpression() { val qualifier by child(qualifier) val functionalType by child(functionalType) - + override fun calculateType(typeFactory: JKTypeFactory): JKType = JKNoType override fun accept(visitor: JKVisitor) = visitor.visitMethodReferenceExpression(this) } @@ -197,6 +212,7 @@ class JKMethodReferenceExpression( class JKLabeledExpression(statement: JKStatement, labels: List) : JKExpression() { var statement: JKStatement by child(statement) val labels: List by children(labels) + override fun calculateType(typeFactory: JKTypeFactory) = typeFactory.types.unit override fun accept(visitor: JKVisitor) = visitor.visitLabeledExpression(this) } @@ -205,6 +221,10 @@ class JKClassLiteralExpression( var literalType: ClassLiteralType ) : JKExpression() { val classType: JKTypeElement by child(classType) + override fun calculateType(typeFactory: JKTypeFactory): JKType = when (literalType) { + ClassLiteralType.KOTLIN_CLASS -> typeFactory.types.kotlinClass + else -> typeFactory.types.javaKlass + } override fun accept(visitor: JKVisitor) = visitor.visitClassLiteralExpression(this) @@ -221,6 +241,7 @@ abstract class JKKtAssignmentChainLink : JKExpression() { abstract val receiver: JKExpression abstract val assignmentStatement: JKKtAssignmentStatement abstract val field: JKExpression + override fun calculateType(typeFactory: JKTypeFactory) = field.calculateType(typeFactory) } class JKAssignmentChainAlsoLink( @@ -231,7 +252,6 @@ class JKAssignmentChainAlsoLink( override val receiver by child(receiver) override val assignmentStatement by child(assignmentStatement) override val field by child(field) - override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainAlsoLink(this) } @@ -243,7 +263,6 @@ class JKAssignmentChainLetLink( override val receiver by child(receiver) override val assignmentStatement by child(assignmentStatement) override val field by child(field) - override fun accept(visitor: JKVisitor) = visitor.visitAssignmentChainLetLink(this) } @@ -251,16 +270,18 @@ class JKAssignmentChainLetLink( class JKIsExpression(expression: JKExpression, type: JKTypeElement) : JKExpression() { var type by child(type) var expression by child(expression) - + override fun calculateType(typeFactory: JKTypeFactory) = typeFactory.types.boolean override fun accept(visitor: JKVisitor) = visitor.visitIsExpression(this) } class JKKtThrowExpression(exception: JKExpression) : JKExpression() { var exception: JKExpression by child(exception) + override fun calculateType(typeFactory: JKTypeFactory) = typeFactory.types.nothing override fun accept(visitor: JKVisitor) = visitor.visitKtThrowExpression(this) } class JKKtItExpression(val type: JKType) : JKExpression() { + override fun calculateType(typeFactory: JKTypeFactory) = type override fun accept(visitor: JKVisitor) = visitor.visitKtItExpression(this) } @@ -268,6 +289,7 @@ class JKKtAnnotationArrayInitializerExpression(initializers: List by children(initializers) + override fun calculateType(typeFactory: JKTypeFactory) = JKNoType override fun accept(visitor: JKVisitor) = visitor.visitKtAnnotationArrayInitializerExpression(this) } @@ -279,27 +301,23 @@ class JKKtTryExpression( var tryBlock: JKBlock by child(tryBlock) var finallyBlock: JKBlock by child(finallyBlock) var catchSections: List by children(catchSections) - override fun accept(visitor: JKVisitor) = visitor.visitKtTryExpression(this) -} + override fun calculateType(typeFactory: JKTypeFactory) = + typeFactory.types.unit // as converted from Java try statement -class JKKtTryCatchSection( - parameter: JKParameter, - block: JKBlock -) : JKTreeElement() { - var parameter: JKParameter by child(parameter) - var block: JKBlock by child(block) - override fun accept(visitor: JKVisitor) = visitor.visitKtTryCatchSection(this) + override fun accept(visitor: JKVisitor) = visitor.visitKtTryExpression(this) } class JKJavaNewEmptyArray(initializer: List, type: JKTypeElement) : JKExpression() { val type by child(type) var initializer by children(initializer) + override fun calculateType(typeFactory: JKTypeFactory) = type.type override fun accept(visitor: JKVisitor) = visitor.visitJavaNewEmptyArray(this) } class JKJavaNewArray(initializer: List, type: JKTypeElement) : JKExpression() { val type by child(type) var initializer by children(initializer) + override fun calculateType(typeFactory: JKTypeFactory) = type.type override fun accept(visitor: JKVisitor) = visitor.visitJavaNewArray(this) } @@ -311,5 +329,6 @@ class JKJavaAssignmentExpression( ) : JKExpression() { var field by child(field) var expression by child(expression) + override fun calculateType(typeFactory: JKTypeFactory) = field.calculateType(typeFactory) override fun accept(visitor: JKVisitor) = visitor.visitJavaAssignmentExpression(this) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt index 41ad9fc1e44..2997f34951d 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt @@ -51,6 +51,9 @@ class JKTypeFactory(val symbolProvider: JKSymbolProvider) { val unit = typeByFqName(KotlinBuiltIns.FQ_NAMES.unit) val nothing = typeByFqName(KotlinBuiltIns.FQ_NAMES.nothing) val nullableAny = typeByFqName(KotlinBuiltIns.FQ_NAMES.any, nullability = Nullability.Nullable) + + val javaKlass = typeByFqName(FqNameUnsafe(CommonClassNames.JAVA_LANG_CLASS)) + val kotlinClass = typeByFqName(KotlinBuiltIns.FQ_NAMES.kClass) } fun fromPrimitiveType(primitiveType: JKJavaPrimitiveType) = when (primitiveType.jvmPrimitiveType) { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/types/types.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/types.kt index 86d63b420d7..1e9670b786a 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/types/types.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/types.kt @@ -16,31 +16,24 @@ interface JKType { interface JKWildCardType : JKType -interface JKNoType : JKType - interface JKParametrizedType : JKType { val parameters: List } -interface JKClassType : JKParametrizedType { - val classReference: JKClassSymbol - override val nullability: Nullability -} - interface JKStarProjectionType : JKWildCardType { override val nullability: Nullability get() = Nullability.NotNull } -object JKNoTypeImpl : JKNoType { +object JKNoType : JKType { override val nullability: Nullability = Nullability.NotNull } -data class JKClassTypeImpl( - override val classReference: JKClassSymbol, +data class JKClassType( + val classReference: JKClassSymbol, override val parameters: List = emptyList(), override val nullability: Nullability = Nullability.Default -) : JKClassType +) : JKParametrizedType object JKStarProjectionTypeImpl : JKStarProjectionType diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt index b5bb42798a5..198c0faf0fc 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt @@ -16,9 +16,7 @@ import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import org.jetbrains.kotlin.j2k.ast.Nullability import org.jetbrains.kotlin.nj2k.JKSymbolProvider import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol -import org.jetbrains.kotlin.nj2k.toJkType import org.jetbrains.kotlin.nj2k.tree.* - import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtTypeReference import org.jetbrains.kotlin.resolve.BindingContext @@ -26,57 +24,11 @@ import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.utils.addToStdlib.safeAs -fun JKExpression.type(typeFactory: JKTypeFactory): JKType? = - when (this) { - is JKLiteralExpression -> type.toJkType(typeFactory) - is JKOperatorExpression -> { - when (val operator = operator) { - is JKKtOperatorImpl -> operator.returnType - is JKKtSpreadOperator -> (this as JKPrefixExpression).expression.type(typeFactory)//TODO ger real type - else -> error("Cannot get type of ${operator::class}, it should be first converted to KtOperator") - } - } - is JKCallExpression -> identifier.returnType - is JKFieldAccessExpression -> identifier.fieldType - is JKQualifiedExpression -> selector.type(typeFactory) - is JKKtThrowExpression -> typeFactory.types.nothing - is JKClassAccessExpression -> - JKClassTypeImpl(identifier, emptyList(), Nullability.NotNull) - is JKIsExpression -> typeFactory.types.boolean - is JKParenthesizedExpression -> expression.type(typeFactory) - is JKTypeCastExpression -> type.type - is JKThisExpression -> null// TODO return actual type - is JKSuperExpression -> null// TODO return actual type - is JKStubExpression -> null - is JKIfElseExpression -> thenBranch.type(typeFactory)// TODO return actual type - is JKArrayAccessExpression -> - (expression.type(typeFactory) as? JKParametrizedType)?.parameters?.lastOrNull() - is JKClassLiteralExpression -> { - val symbol = when (literalType) { - JKClassLiteralExpression.ClassLiteralType.KOTLIN_CLASS -> - typeFactory.symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.kClass.toSafe()) - JKClassLiteralExpression.ClassLiteralType.JAVA_CLASS, - JKClassLiteralExpression.ClassLiteralType.JAVA_PRIMITIVE_CLASS, JKClassLiteralExpression.ClassLiteralType.JAVA_VOID_TYPE -> - typeFactory.symbolProvider.provideClassSymbol("java.lang.Class") - } - JKClassTypeImpl(symbol, listOf(classType.type), Nullability.NotNull) - } - is JKKtAnnotationArrayInitializerExpression -> JKNoTypeImpl //TODO - is JKLambdaExpression -> returnType.type - is JKLabeledExpression -> typeFactory.types.unit - is JKMethodReferenceExpression -> JKNoTypeImpl //TODO - is JKAssignmentChainAlsoLink -> receiver.type(typeFactory) - is JKAssignmentChainLetLink -> field.type(typeFactory) - is JKKtItExpression -> type - is JKNewExpression -> JKClassTypeImpl(classSymbol) - else -> TODO(this::class.java.toString()) - } - fun JKType.asTypeElement() = JKTypeElement(this) fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType = - JKClassTypeImpl(this, emptyList(), nullability) + JKClassType(this, emptyList(), nullability) val PsiType.isKotlinFunctionalType: Boolean get() { @@ -112,8 +64,8 @@ private val jvmPrimitiveTypesPriority = fun JKType.applyRecursive(transform: (JKType) -> JKType?): JKType = transform(this) ?: when (this) { is JKTypeParameterType -> this - is JKClassTypeImpl -> - JKClassTypeImpl( + is JKClassType -> + JKClassType( classReference, parameters.map { it.applyRecursive(transform) }, nullability @@ -133,7 +85,7 @@ inline fun T.updateNullability(newNullability: Nullability) if (nullability == newNullability) this else when (this) { is JKTypeParameterType -> JKTypeParameterType(identifier, newNullability) - is JKClassTypeImpl -> JKClassTypeImpl(classReference, parameters, newNullability) + is JKClassType -> JKClassType(classReference, parameters, newNullability) is JKNoType -> this is JKJavaVoidType -> this is JKJavaPrimitiveType -> this @@ -148,8 +100,8 @@ fun T.updateNullabilityRecursively(newNullability: Nullability): T applyRecursive { when (it) { is JKTypeParameterType -> JKTypeParameterType(it.identifier, newNullability) - is JKClassTypeImpl -> - JKClassTypeImpl( + is JKClassType -> + JKClassType( it.classReference, it.parameters.map { it.updateNullabilityRecursively(newNullability) }, newNullability @@ -271,7 +223,7 @@ fun JKType.isInterface(): Boolean = fun JKType.replaceJavaClassWithKotlinClassType(symbolProvider: JKSymbolProvider): JKType = applyRecursive { type -> if (type is JKClassType && type.classReference.fqName == "java.lang.Class") { - JKClassTypeImpl( + JKClassType( symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.kClass.toSafe()), type.parameters.map { it.replaceJavaClassWithKotlinClassType(symbolProvider) }, Nullability.NotNull