mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-16 15:52:18 +00:00
New J2K: move type calculation to expression node
This commit is contained in:
@@ -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<JKSymbol>(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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<JKFieldAccessExpression>()
|
||||
?.identifier
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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<JKClass>()?.classKind == JKClass.ClassKind.COMPANION
|
||||
is JKUnresolvedMethod -> false
|
||||
}
|
||||
|
||||
private val JKMethodSymbol.parameterNames: List<String>?
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<JKVariable> {
|
||||
class JKUniverseFieldSymbol(override val typeFactory: JKTypeFactory) : JKFieldSymbol(), JKUniverseSymbol<JKVariable> {
|
||||
override val fieldType: JKType
|
||||
get() = target.type.type
|
||||
|
||||
@@ -50,7 +46,7 @@ class JKMultiverseKtEnumEntrySymbol(
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKFieldSymbol(), JKMultiverseKtSymbol<KtEnumEntry> {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -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<JKMethod> {
|
||||
override val receiverType: JKType?
|
||||
get() = target.parent.safeAs<JKClass>()?.let {
|
||||
JKClassTypeImpl(symbolProvider.provideUniverseSymbol(it), emptyList()/*TODO*/)
|
||||
JKClassType(symbolProvider.provideUniverseSymbol(it), emptyList())
|
||||
}
|
||||
override val parameterTypes: List<JKType>
|
||||
get() = target.parameters.map { it.type.type }
|
||||
@@ -48,7 +48,7 @@ class JKMultiverseMethodSymbol(
|
||||
) : JKMethodSymbol(), JKMultiverseSymbol<PsiMethod> {
|
||||
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<JKType>
|
||||
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<JKType>
|
||||
get() = emptyList()
|
||||
}
|
||||
|
||||
@@ -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<JKParameter> 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<JKParameter> by children(parameters)
|
||||
override var block: JKBlock by child(JKBodyStub)
|
||||
|
||||
@@ -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<JKParameter>,
|
||||
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<JKNameIdentifier>) : JKExpression() {
|
||||
var statement: JKStatement by child(statement)
|
||||
val labels: List<JKNameIdentifier> 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<JKAnnotationMe
|
||||
constructor(vararg initializers: JKAnnotationMemberValue) : this(initializers.toList())
|
||||
|
||||
val initializers: List<JKAnnotationMemberValue> 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<JKKtTryCatchSection> 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<JKExpression>, 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<JKExpression>, 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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -16,31 +16,24 @@ interface JKType {
|
||||
|
||||
interface JKWildCardType : JKType
|
||||
|
||||
interface JKNoType : JKType
|
||||
|
||||
interface JKParametrizedType : JKType {
|
||||
val parameters: List<JKType>
|
||||
}
|
||||
|
||||
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<JKType> = emptyList(),
|
||||
override val nullability: Nullability = Nullability.Default
|
||||
) : JKClassType
|
||||
) : JKParametrizedType
|
||||
|
||||
|
||||
object JKStarProjectionTypeImpl : JKStarProjectionType
|
||||
|
||||
@@ -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 <reified T : JKType> 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 : JKType> 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
|
||||
|
||||
Reference in New Issue
Block a user