New J2K: introduce TypeFactory for creating J2K types
This commit is contained in:
@@ -6,12 +6,17 @@
|
||||
package org.jetbrains.kotlin.nj2k
|
||||
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
|
||||
interface Conversion {
|
||||
val context: NewJ2kConverterContext
|
||||
val symbolProvider
|
||||
|
||||
val symbolProvider: JKSymbolProvider
|
||||
get() = context.symbolProvider
|
||||
|
||||
val typeFactory: JKTypeFactory
|
||||
get() = context.typeFactory
|
||||
|
||||
fun runConversion(treeRoots: List<JKTreeElement>, context: NewJ2kConverterContext): Boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.nj2k.conversions.JKResolver
|
||||
import org.jetbrains.kotlin.nj2k.symbols.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
|
||||
@@ -24,6 +25,7 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
private val resolver = JKResolver(project, module, contextElement)
|
||||
|
||||
private val elementVisitor = ElementVisitor()
|
||||
lateinit var typeFactory: JKTypeFactory
|
||||
|
||||
fun preBuildTree(inputElements: List<PsiElement>) {
|
||||
inputElements.forEach { it.accept(elementVisitor) }
|
||||
@@ -31,19 +33,19 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
|
||||
private fun symbolForNonKotlinElement(psi: PsiElement) =
|
||||
when (psi) {
|
||||
is PsiTypeParameter -> JKMultiverseTypeParameterSymbol(psi, this)
|
||||
is KtTypeParameter -> JKMultiverseKtTypeParameterSymbol(psi, this)
|
||||
is KtEnumEntry -> JKMultiverseKtEnumEntrySymbol(psi, this)
|
||||
is PsiClass -> JKMultiverseClassSymbol(psi, this)
|
||||
is KtClassOrObject -> JKMultiverseKtClassSymbol(psi, this)
|
||||
is PsiMethod -> JKMultiverseMethodSymbol(psi, this)
|
||||
is PsiField -> JKMultiverseFieldSymbol(psi, this)
|
||||
is KtFunction -> JKMultiverseFunctionSymbol(psi, this)
|
||||
is KtProperty -> JKMultiversePropertySymbol(psi, this)
|
||||
is KtParameter -> JKMultiversePropertySymbol(psi, this)
|
||||
is PsiParameter -> JKMultiverseFieldSymbol(psi, this)
|
||||
is PsiLocalVariable -> JKMultiverseFieldSymbol(psi, this)
|
||||
is PsiPackage -> JKMultiversePackageSymbol(psi, this)
|
||||
is PsiTypeParameter -> JKMultiverseTypeParameterSymbol(psi, typeFactory)
|
||||
is KtTypeParameter -> JKMultiverseKtTypeParameterSymbol(psi, typeFactory)
|
||||
is KtEnumEntry -> JKMultiverseKtEnumEntrySymbol(psi, typeFactory)
|
||||
is PsiClass -> JKMultiverseClassSymbol(psi, typeFactory)
|
||||
is KtClassOrObject -> JKMultiverseKtClassSymbol(psi, typeFactory)
|
||||
is PsiMethod -> JKMultiverseMethodSymbol(psi, typeFactory)
|
||||
is PsiField -> JKMultiverseFieldSymbol(psi, typeFactory)
|
||||
is KtFunction -> JKMultiverseFunctionSymbol(psi, typeFactory)
|
||||
is KtProperty -> JKMultiversePropertySymbol(psi, typeFactory)
|
||||
is KtParameter -> JKMultiversePropertySymbol(psi, typeFactory)
|
||||
is PsiParameter -> JKMultiverseFieldSymbol(psi, typeFactory)
|
||||
is PsiLocalVariable -> JKMultiverseFieldSymbol(psi, typeFactory)
|
||||
is PsiPackage -> JKMultiversePackageSymbol(psi, typeFactory)
|
||||
else -> TODO(psi::class.toString())
|
||||
}
|
||||
|
||||
@@ -62,8 +64,8 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
if (target != null) return provideDirectSymbol(target) as T
|
||||
return (if (isAssignable<T, JKUnresolvedField>()) JKUnresolvedField(
|
||||
reference.canonicalText,
|
||||
this
|
||||
) else JKUnresolvedMethod(reference)) as T
|
||||
typeFactory
|
||||
) else JKUnresolvedMethod(reference, typeFactory)) as T
|
||||
}
|
||||
|
||||
fun provideUniverseSymbol(psi: PsiElement, jk: JKDeclaration): JKSymbol = provideUniverseSymbol(psi).also {
|
||||
@@ -79,10 +81,10 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
fun provideUniverseSymbol(psi: PsiElement): JKSymbol =
|
||||
symbolsByPsi.getOrPut(psi) {
|
||||
when (psi) {
|
||||
is PsiVariable -> JKUniverseFieldSymbol(this)
|
||||
is PsiMethod -> JKUniverseMethodSymbol(this)
|
||||
is PsiTypeParameter -> JKUniverseTypeParameterSymbol(this)
|
||||
is PsiClass -> JKUniverseClassSymbol(this)
|
||||
is PsiVariable -> JKUniverseFieldSymbol(typeFactory)
|
||||
is PsiMethod -> JKUniverseMethodSymbol(typeFactory)
|
||||
is PsiTypeParameter -> JKUniverseTypeParameterSymbol(typeFactory)
|
||||
is PsiClass -> JKUniverseClassSymbol(typeFactory)
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
@@ -95,15 +97,15 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
}
|
||||
|
||||
fun provideUniverseSymbol(jk: JKClass): JKClassSymbol = symbolsByJK.getOrPut(jk) {
|
||||
JKUniverseClassSymbol(this).also { it.target = jk }
|
||||
JKUniverseClassSymbol(typeFactory).also { it.target = jk }
|
||||
} as JKClassSymbol
|
||||
|
||||
fun provideUniverseSymbol(jk: JKVariable): JKFieldSymbol = symbolsByJK.getOrPut(jk) {
|
||||
JKUniverseFieldSymbol(this).also { it.target = jk }
|
||||
JKUniverseFieldSymbol(typeFactory).also { it.target = jk }
|
||||
} as JKFieldSymbol
|
||||
|
||||
fun provideUniverseSymbol(jk: JKMethod): JKMethodSymbol = symbolsByJK.getOrPut(jk) {
|
||||
JKUniverseMethodSymbol(this).also { it.target = jk }
|
||||
JKUniverseMethodSymbol(typeFactory).also { it.target = jk }
|
||||
} as JKMethodSymbol
|
||||
|
||||
|
||||
@@ -112,7 +114,7 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
resolver.resolveClass(fqName)?.let {
|
||||
provideDirectSymbol(it) as? JKClassSymbol
|
||||
}
|
||||
} as? JKClassSymbol ?: JKUnresolvedClassSymbol(fqName.asString())
|
||||
} as? JKClassSymbol ?: JKUnresolvedClassSymbol(fqName.asString(), typeFactory)
|
||||
|
||||
fun provideClassSymbol(fqName: String): JKClassSymbol =
|
||||
provideClassSymbol(FqName(fqName.asSafeFqNameString()))
|
||||
@@ -125,7 +127,7 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
resolver.resolveMethod(fqName)?.let {
|
||||
provideDirectSymbol(it) as? JKMethodSymbol
|
||||
}
|
||||
} as? JKMethodSymbol ?: JKUnresolvedMethod(fqName.asString())
|
||||
} as? JKMethodSymbol ?: JKUnresolvedMethod(fqName.asString(), typeFactory)
|
||||
|
||||
fun provideMethodSymbol(fqName: String): JKMethodSymbol =
|
||||
provideMethodSymbol(FqName(fqName.asSafeFqNameString()))
|
||||
@@ -135,7 +137,7 @@ class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElem
|
||||
resolver.resolveField(fqName)?.let {
|
||||
provideDirectSymbol(it) as? JKFieldSymbol
|
||||
}
|
||||
} as? JKFieldSymbol ?: JKUnresolvedField(fqName.asString(), this)
|
||||
} as? JKFieldSymbol ?: JKUnresolvedField(fqName.asString(), typeFactory)
|
||||
|
||||
fun provideFieldSymbol(fqName: String): JKFieldSymbol =
|
||||
provideFieldSymbol(FqName(fqName.asSafeFqNameString()))
|
||||
|
||||
@@ -45,6 +45,9 @@ import org.jetbrains.kotlin.nj2k.symbols.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
@@ -53,10 +56,13 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
class JavaToJKTreeBuilder constructor(
|
||||
var symbolProvider: JKSymbolProvider,
|
||||
private val symbolProvider: JKSymbolProvider,
|
||||
private val typeFactory: JKTypeFactory,
|
||||
converterServices: NewJavaToKotlinServices,
|
||||
private val importStorage: ImportStorage
|
||||
) {
|
||||
private fun PsiType.toJK() =
|
||||
typeFactory.fromPsiType(this)
|
||||
|
||||
private val expressionTreeMapper = ExpressionTreeMapper()
|
||||
|
||||
@@ -153,7 +159,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
|
||||
fun PsiClassObjectAccessExpressionImpl.toJK(): JKClassLiteralExpression {
|
||||
val type = operand.type.toJK(symbolProvider).updateNullabilityRecursively(Nullability.NotNull)
|
||||
val type = operand.type.toJK().updateNullabilityRecursively(Nullability.NotNull)
|
||||
return JKClassLiteralExpressionImpl(
|
||||
JKTypeElementImpl(type),
|
||||
when (type) {
|
||||
@@ -167,7 +173,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
|
||||
fun PsiInstanceOfExpression.toJK(): JKKtIsExpression =
|
||||
JKKtIsExpressionImpl(operand.toJK(), JKTypeElementImpl(checkType?.type?.toJK(symbolProvider) ?: JKNoTypeImpl))
|
||||
JKKtIsExpressionImpl(operand.toJK(), JKTypeElementImpl(checkType?.type?.toJK() ?: JKNoTypeImpl))
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
@@ -270,7 +276,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
val target = methodExpression.resolve()
|
||||
val symbol = target?.let {
|
||||
symbolProvider.provideDirectSymbol(it)
|
||||
} ?: JKUnresolvedMethod(methodExpression)
|
||||
} ?: JKUnresolvedMethod(methodExpression, typeFactory)
|
||||
|
||||
return when {
|
||||
methodExpression.referenceNameElement is PsiKeyword -> {
|
||||
@@ -340,7 +346,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
else -> {
|
||||
JKJavaMethodCallExpressionImpl(
|
||||
JKMultiverseMethodSymbol(target, symbolProvider),
|
||||
JKMultiverseMethodSymbol(target, typeFactory),
|
||||
arguments.toJK(),
|
||||
typeArguments
|
||||
).qualified(qualifier)
|
||||
@@ -365,14 +371,14 @@ class JavaToJKTreeBuilder constructor(
|
||||
type.safeAs<PsiClassType>()?.parameters?.any { it is PsiCapturedWildcardType } == true
|
||||
}?.takeUnless { type ->
|
||||
type.isKotlinFunctionalType
|
||||
}?.toJK(symbolProvider)
|
||||
}?.toJK()
|
||||
?.asTypeElement() ?: JKTypeElementImpl(JKNoTypeImpl)
|
||||
|
||||
fun PsiMethodReferenceExpression.toJK(): JKMethodReferenceExpression {
|
||||
val symbol = symbolProvider.provideSymbolForReference<JKSymbol>(this).let { symbol ->
|
||||
when {
|
||||
symbol.isUnresolved && isConstructor -> JKUnresolvedClassSymbol(qualifier?.text ?: text)
|
||||
symbol.isUnresolved && !isConstructor -> JKUnresolvedMethod(referenceName ?: text)
|
||||
symbol.isUnresolved && isConstructor -> JKUnresolvedClassSymbol(qualifier?.text ?: text, typeFactory)
|
||||
symbol.isUnresolved && !isConstructor -> JKUnresolvedMethod(referenceName ?: text, typeFactory)
|
||||
else -> symbol
|
||||
}
|
||||
}
|
||||
@@ -412,7 +418,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
fun PsiArrayInitializerExpression.toJK(): JKExpression {
|
||||
return JKJavaNewArrayImpl(
|
||||
initializers.map { it.toJK() },
|
||||
JKTypeElementImpl(type?.toJK(symbolProvider).safeAs<JKJavaArrayType>()?.type ?: JKContextType)
|
||||
JKTypeElementImpl(type?.toJK().safeAs<JKJavaArrayType>()?.type ?: JKContextType)
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
@@ -438,7 +444,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
JKJavaNewEmptyArrayImpl(
|
||||
dimensions.map { it?.toJK() ?: JKStubExpressionImpl() },
|
||||
JKTypeElementImpl(generateSequence(type?.toJK(symbolProvider)) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
||||
JKTypeElementImpl(generateSequence(type?.toJK()) { it.safeAs<JKJavaArrayType>()?.type }.last())
|
||||
).also {
|
||||
it.psi = this
|
||||
}
|
||||
@@ -447,14 +453,17 @@ class JavaToJKTreeBuilder constructor(
|
||||
val classSymbol =
|
||||
classOrAnonymousClassReference?.resolve()?.let {
|
||||
symbolProvider.provideDirectSymbol(it) as JKClassSymbol
|
||||
} ?: JKUnresolvedClassSymbol(classOrAnonymousClassReference?.referenceName ?: throwCanNotConvertError())
|
||||
} ?: JKUnresolvedClassSymbol(
|
||||
classOrAnonymousClassReference?.referenceName ?: throwCanNotConvertError(),
|
||||
typeFactory
|
||||
)
|
||||
val typeArgumentList =
|
||||
this.typeArgumentList.toJK()
|
||||
.takeIf { it.typeArguments.isNotEmpty() }
|
||||
?: classOrAnonymousClassReference
|
||||
?.typeParameters
|
||||
?.let { typeParameters ->
|
||||
JKTypeArgumentListImpl(typeParameters.map { JKTypeElementImpl(it.toJK(symbolProvider)) })
|
||||
JKTypeArgumentListImpl(typeParameters.map { JKTypeElementImpl(it.toJK()) })
|
||||
} ?: JKTypeArgumentListImpl()
|
||||
JKJavaNewExpressionImpl(
|
||||
classSymbol,
|
||||
@@ -469,7 +478,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
|
||||
fun PsiReferenceParameterList.toJK(): JKTypeArgumentList =
|
||||
JKTypeArgumentListImpl(this.typeArguments.map { JKTypeElementImpl(it.toJK(symbolProvider)) })
|
||||
JKTypeArgumentListImpl(this.typeArguments.map { JKTypeElementImpl(it.toJK()) })
|
||||
.also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
@@ -487,7 +496,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
fun PsiTypeCastExpression.toJK(): JKExpression {
|
||||
return JKTypeCastExpressionImpl(
|
||||
operand?.toJK() ?: throwCanNotConvertError(),
|
||||
castType?.type?.toJK(symbolProvider)?.asTypeElement() ?: throwCanNotConvertError()
|
||||
castType?.type?.toJK()?.asTypeElement() ?: throwCanNotConvertError()
|
||||
).also {
|
||||
it.assignNonCodeElements(this)
|
||||
}
|
||||
@@ -535,7 +544,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
fun PsiTypeParameter.toJK(): JKTypeParameter =
|
||||
JKTypeParameterImpl(
|
||||
nameIdentifier.toJK(),
|
||||
extendsListTypes.map { JKTypeElementImpl(it.toJK(symbolProvider, Nullability.Default)) }
|
||||
extendsListTypes.map { JKTypeElementImpl(it.toJK()) }
|
||||
).also {
|
||||
symbolProvider.provideUniverseSymbol(this, it)
|
||||
it.assignNonCodeElements(this)
|
||||
@@ -562,9 +571,9 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
fun PsiClass.inheritanceInfo(): JKInheritanceInfo {
|
||||
val implTypes =
|
||||
implementsList?.referencedTypes?.map { JKTypeElementImpl(it.toJK(symbolProvider, Nullability.Default)) }.orEmpty()
|
||||
implementsList?.referencedTypes?.map { JKTypeElementImpl(it.toJK()) }.orEmpty()
|
||||
val extensionType =
|
||||
extendsList?.referencedTypes?.map { JKTypeElementImpl(it.toJK(symbolProvider, Nullability.Default)) }.orEmpty()
|
||||
extendsList?.referencedTypes?.map { JKTypeElementImpl(it.toJK()) }.orEmpty()
|
||||
return JKInheritanceInfoImpl(extensionType, implTypes)
|
||||
.also {
|
||||
if (implementsList != null) {
|
||||
@@ -645,7 +654,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
fun PsiField.toJK(): JKJavaField {
|
||||
return JKJavaFieldImpl(
|
||||
JKTypeElementImpl(type.toJK(symbolProvider)).withAssignedNonCodeElements(typeElement),
|
||||
JKTypeElementImpl(type.toJK()).withAssignedNonCodeElements(typeElement),
|
||||
nameIdentifier.toJK(),
|
||||
with(expressionTreeMapper) { initializer.toJK() },
|
||||
annotationList(this),
|
||||
@@ -676,7 +685,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
symbolProvider.provideSymbolForReference<JKSymbol>(
|
||||
nameReferenceElement ?: throwCanNotConvertError()
|
||||
).safeAs<JKClassSymbol>()
|
||||
?: JKUnresolvedClassSymbol(nameReferenceElement?.text ?: throwCanNotConvertError()),
|
||||
?: JKUnresolvedClassSymbol(nameReferenceElement?.text ?: throwCanNotConvertError(), typeFactory),
|
||||
parameterList.attributes.map { parameter ->
|
||||
if (parameter.nameIdentifier != null) {
|
||||
JKAnnotationNameParameterImpl(
|
||||
@@ -698,7 +707,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
JKAnnotationImpl(
|
||||
symbolProvider.provideClassSymbol("kotlin.Deprecated"),
|
||||
listOf(
|
||||
JKAnnotationParameterImpl(stringLiteral(tag.content(), symbolProvider))
|
||||
JKAnnotationParameterImpl(stringLiteral(tag.content(), typeFactory))
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -718,7 +727,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
fun PsiAnnotationMethod.toJK(): JKJavaAnnotationMethod =
|
||||
JKJavaAnnotationMethodImpl(
|
||||
returnType?.toJK(symbolProvider)?.asTypeElement()
|
||||
returnType?.toJK()?.asTypeElement()
|
||||
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
|
||||
?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"),
|
||||
nameIdentifier.toJK(),
|
||||
@@ -733,7 +742,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
fun PsiMethod.toJK(): JKJavaMethod {
|
||||
return JKJavaMethodImpl(
|
||||
returnType?.toJK(symbolProvider)?.asTypeElement()
|
||||
returnType?.toJK()?.asTypeElement()
|
||||
?: JKTypeElementImpl(JKJavaVoidType).takeIf { isConstructor }
|
||||
?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"),
|
||||
nameIdentifier.toJK(),
|
||||
@@ -741,7 +750,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
body?.toJK() ?: JKBodyStubImpl,
|
||||
typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
|
||||
annotationList(this),
|
||||
throwsList.referencedTypes.map { JKTypeElementImpl(it.toJK(symbolProvider)) },
|
||||
throwsList.referencedTypes.map { JKTypeElementImpl(it.toJK()) },
|
||||
otherModifiers(),
|
||||
visibility(),
|
||||
modality()
|
||||
@@ -758,7 +767,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
}
|
||||
|
||||
fun PsiParameter.toJK(): JKParameter {
|
||||
val rawType = type.toJK(symbolProvider)
|
||||
val rawType = type.toJK()
|
||||
val type =
|
||||
if (isVarArgs && rawType is JKJavaArrayType) JKTypeElementImpl(rawType.type)
|
||||
else rawType.asTypeElement()
|
||||
@@ -786,7 +795,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
|
||||
fun PsiLocalVariable.toJK(): JKLocalVariable =
|
||||
JKLocalVariableImpl(
|
||||
JKTypeElementImpl(type.toJK(symbolProvider)).withAssignedNonCodeElements(typeElement),
|
||||
JKTypeElementImpl(type.toJK()).withAssignedNonCodeElements(typeElement),
|
||||
nameIdentifier.toJK(),
|
||||
with(expressionTreeMapper) { initializer.toJK() },
|
||||
JKMutabilityModifierElementImpl(
|
||||
@@ -944,7 +953,7 @@ class JavaToJKTreeBuilder constructor(
|
||||
if (psi.parent is PsiReferenceList) {
|
||||
val factory = JavaPsiFacade.getInstance(psi.project).elementFactory
|
||||
val type = factory.createType(psi)
|
||||
JKTypeElementImpl(type.toJK(symbolProvider).updateNullabilityRecursively(Nullability.NotNull))
|
||||
JKTypeElementImpl(type.toJK().updateNullabilityRecursively(Nullability.NotNull))
|
||||
} else null
|
||||
else -> null
|
||||
}?.let { JKTreeRootImpl(it) }
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.nj2k.symbols.getDisplayName
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitorWithCommentsPrinting
|
||||
import org.jetbrains.kotlin.nj2k.types.*
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
@@ -8,9 +8,11 @@ package org.jetbrains.kotlin.nj2k
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
|
||||
data class NewJ2kConverterContext(
|
||||
val symbolProvider: JKSymbolProvider,
|
||||
val typeFactory: JKTypeFactory,
|
||||
val converter: NewJavaToKotlinConverter,
|
||||
val inConversionContext: (PsiElement) -> Boolean,
|
||||
val importStorage: ImportStorage,
|
||||
|
||||
@@ -35,6 +35,7 @@ import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.jetbrains.kotlin.idea.core.util.EDT
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
|
||||
class NewJavaToKotlinConverter(
|
||||
@@ -106,9 +107,11 @@ class NewJavaToKotlinConverter(
|
||||
val module = targetModule ?: error("Module should not be null for new J2K")
|
||||
val contextElement = inputElements.firstOrNull() ?: return Result(emptyList(), null, null)
|
||||
val symbolProvider = JKSymbolProvider(project, module, contextElement)
|
||||
val typeFactory = JKTypeFactory(symbolProvider)
|
||||
symbolProvider.typeFactory = typeFactory
|
||||
symbolProvider.preBuildTree(inputElements)
|
||||
val importStorage = ImportStorage()
|
||||
val treeBuilder = JavaToJKTreeBuilder(symbolProvider, converterServices, importStorage)
|
||||
val treeBuilder = JavaToJKTreeBuilder(symbolProvider, typeFactory, converterServices, importStorage)
|
||||
val asts = processor.process {
|
||||
inputElements.mapIndexed { i, element ->
|
||||
processor.updateState(i, 1, phaseDescription)
|
||||
@@ -118,6 +121,7 @@ class NewJavaToKotlinConverter(
|
||||
|
||||
val context = NewJ2kConverterContext(
|
||||
symbolProvider,
|
||||
typeFactory,
|
||||
this,
|
||||
{ it.containingFile in inputElements },
|
||||
importStorage,
|
||||
|
||||
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.nj2k.symbols.JKUniverseMethodSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKCapturedType
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.psi
|
||||
import org.jetbrains.kotlin.nj2k.types.JKParametrizedType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKStarProjectionType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class AddElementsInfoConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.toExpression
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
||||
|
||||
class AnnotationClassConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.toArgumentList
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.CollectionLiteralResolver
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseFieldSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKFieldAccessExpressionImpl
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
@@ -32,7 +33,7 @@ class ArrayOperationsConversion(context: NewJ2kConverterContext) : RecursiveAppl
|
||||
}
|
||||
|
||||
private fun JKExpression.isArrayOrVarargTypeParameter(): Boolean {
|
||||
if (type(symbolProvider) is JKJavaArrayType) return true
|
||||
if (type(typeFactory) is JKJavaArrayType) return true
|
||||
val parameter =
|
||||
safeAs<JKFieldAccessExpression>()
|
||||
?.identifier
|
||||
|
||||
@@ -29,7 +29,7 @@ class AssertStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl
|
||||
kotlinAssert(
|
||||
element::condition.detached(),
|
||||
messageExpression,
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -267,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(symbolProvider)?.isStringType() == true }
|
||||
withByArgumentsFilter { it.singleOrNull()?.type(typeFactory)?.isStringType() == true }
|
||||
withArgumentsProvider { arguments ->
|
||||
val argument = arguments.arguments.single()::value.detached()
|
||||
val call = JKKtCallExpressionImpl(
|
||||
@@ -280,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(symbolProvider)?.isArrayType() == false },
|
||||
withByArgumentsFilter { it.isNotEmpty() && it.first().type(typeFactory)?.isArrayType() == false },
|
||||
|
||||
Method("java.lang.String.getChars")
|
||||
convertTo Method("kotlin.text.toCharArray")
|
||||
@@ -296,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(symbolProvider)?.isArrayType() == true },
|
||||
withByArgumentsFilter { it.isNotEmpty() && it.first().type(typeFactory)?.isArrayType() == true },
|
||||
|
||||
Method("java.lang.String.copyValueOf")
|
||||
convertTo Method("kotlin.String")
|
||||
withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER
|
||||
withByArgumentsFilter { it.isNotEmpty() && it.first().type(symbolProvider)?.isArrayType() == true },
|
||||
withByArgumentsFilter { it.isNotEmpty() && it.first().type(typeFactory)?.isArrayType() == true },
|
||||
|
||||
Method("java.lang.String.replaceAll")
|
||||
convertTo Method("kotlin.text.replace")
|
||||
@@ -370,7 +370,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
firstArgument,
|
||||
secondArgument,
|
||||
KtTokens.PLUS,
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
} withReplaceType ReplaceType.REPLACE_WITH_QUALIFIER,
|
||||
|
||||
@@ -397,7 +397,7 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
JKFieldAccessExpressionImpl(
|
||||
JKUnresolvedField(//TODO replace with `it` parameter
|
||||
"it",
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
).callOn(symbolProvider.provideMethodSymbol("kotlin.text.isEmpty"))
|
||||
.asStatement(),
|
||||
@@ -432,12 +432,12 @@ class BuiltinMembersConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
JKFieldAccessExpressionImpl(
|
||||
JKUnresolvedField(//TODO replace with `it` parameter
|
||||
"it",
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
),
|
||||
JKKtLiteralExpressionImpl("' '", JKLiteralExpression.LiteralType.CHAR),
|
||||
KtTokens.LTEQ,
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
),
|
||||
emptyList()
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.fqNameToImport
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class EqualsOperatorConversion(context: NewJ2kConverterContext) : RecursiveAppli
|
||||
equalsExpression(
|
||||
element::receiver.detached(),
|
||||
argument::value.detached(),
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.nj2k.*
|
||||
import org.jetbrains.kotlin.nj2k.symbols.deepestFqName
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
||||
import kotlin.math.abs
|
||||
|
||||
|
||||
@@ -185,7 +186,7 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
||||
start,
|
||||
convertBound(bound, if (inclusiveComparison) 0 else -1),
|
||||
JKKtSingleValueOperatorToken(KtTokens.RANGE),
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -203,7 +204,7 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
||||
bound,
|
||||
JKKtLiteralExpressionImpl(abs(correction).toString(), JKLiteralExpression.LiteralType.INT),
|
||||
JKKtSingleValueOperatorToken(sign),
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
}
|
||||
|
||||
@@ -255,7 +256,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(symbolProvider)
|
||||
val receiverType = javaSizeCall.receiver.type(typeFactory)
|
||||
if (methodCall.identifier.name == "length" && receiverType is JKJavaArrayType) {
|
||||
return toIndicesCall(javaSizeCall)
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.nj2k.symbols.isUnresolved
|
||||
import org.jetbrains.kotlin.nj2k.symbols.parameterTypesWithUnfoldedVarargs
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -30,8 +31,8 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
|
||||
|
||||
private fun convertBinaryExpression(binaryExpression: JKBinaryExpression): JKExpression {
|
||||
fun JKBinaryExpression.convertBinaryOperationWithChar(): JKBinaryExpression {
|
||||
val leftType = left.type(symbolProvider)?.asPrimitiveType() ?: return this
|
||||
val rightType = right.type(symbolProvider)?.asPrimitiveType() ?: return this
|
||||
val leftType = left.type(typeFactory)?.asPrimitiveType() ?: return this
|
||||
val rightType = right.type(typeFactory)?.asPrimitiveType() ?: return this
|
||||
|
||||
val leftOperandCastedCasted by lazy {
|
||||
JKBinaryExpressionImpl(
|
||||
@@ -72,7 +73,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
|
||||
}
|
||||
|
||||
private fun convertAssignmentStatement(statement: JKKtAssignmentStatement) {
|
||||
val expressionType = statement.field.type(symbolProvider) ?: return
|
||||
val expressionType = statement.field.type(typeFactory) ?: return
|
||||
statement.expression.castTo(expressionType)?.also {
|
||||
statement.expression = it
|
||||
}
|
||||
@@ -99,7 +100,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
|
||||
|
||||
private fun JKExpression.castStringToRegex(toType: JKType): JKExpression? {
|
||||
if (toType.safeAs<JKClassType>()?.classReference?.fqName != "java.util.regex.Pattern") return null
|
||||
val expressionType = type(symbolProvider) ?: return null
|
||||
val expressionType = type(typeFactory) ?: return null
|
||||
if (!expressionType.isStringType()) return null
|
||||
return JKQualifiedExpressionImpl(
|
||||
copyTreeAndDetach().parenthesizeIfBinaryExpression(),
|
||||
@@ -120,7 +121,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
|
||||
val casted = expression.castToAsPrimitiveTypes(toType, strict) ?: return null
|
||||
return JKPrefixExpressionImpl(casted, operator)
|
||||
}
|
||||
val expressionTypeAsPrimitive = type(symbolProvider)?.asPrimitiveType() ?: return null
|
||||
val expressionTypeAsPrimitive = type(typeFactory)?.asPrimitiveType() ?: return null
|
||||
val toTypeAsPrimitive = toType.asPrimitiveType() ?: return null
|
||||
if (toTypeAsPrimitive == expressionTypeAsPrimitive) return null
|
||||
|
||||
@@ -155,7 +156,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic
|
||||
|
||||
|
||||
private fun JKExpression.castTo(toType: JKType, strict: Boolean = false): JKExpression? {
|
||||
val expressionType = type(symbolProvider)
|
||||
val expressionType = type(typeFactory)
|
||||
if (expressionType == toType) return null
|
||||
castToAsPrimitiveTypes(toType, strict)?.also { return it }
|
||||
castStringToRegex(toType)?.also { return it }
|
||||
|
||||
@@ -13,6 +13,9 @@ import org.jetbrains.kotlin.nj2k.tree.impl.JKBooleanLiteral
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaLiteralExpressionImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaPrimitiveTypeImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKNullLiteral
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeParameterType
|
||||
|
||||
class ImplicitInitializerConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
|
||||
|
||||
class InsertDefaultPrimaryConstructorConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
|
||||
class JavaStandardMethodsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
@@ -31,7 +32,7 @@ class JavaStandardMethodsConversion(context: NewJ2kConverterContext) : Recursive
|
||||
element.inheritance.implements +=
|
||||
JKTypeElementImpl(
|
||||
JKClassTypeImpl(
|
||||
JKUnresolvedClassSymbol("Cloneable"),
|
||||
JKUnresolvedClassSymbol("Cloneable", typeFactory),
|
||||
emptyList(), Nullability.NotNull
|
||||
)
|
||||
)
|
||||
|
||||
@@ -11,6 +11,8 @@ import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaArrayTypeImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKTypeElementImpl
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
||||
|
||||
|
||||
//TODO temporary
|
||||
|
||||
@@ -6,12 +6,17 @@
|
||||
package org.jetbrains.kotlin.nj2k.conversions
|
||||
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import org.jetbrains.kotlin.codegen.kotlinType
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.nullIfStubExpression
|
||||
import org.jetbrains.kotlin.nj2k.qualified
|
||||
import org.jetbrains.kotlin.nj2k.symbols.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeParameterType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -111,12 +116,12 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur
|
||||
.firstOrNull { !it.hasModifier(JvmModifier.STATIC) }
|
||||
?.parameterList
|
||||
?.parameters
|
||||
?.map { it.type.toJK(symbolProvider).substituteTypeParameters(this) }
|
||||
?.map { typeFactory.fromPsiType(it.type).substituteTypeParameters(this) }
|
||||
is JKMultiverseKtClassSymbol -> reference.target.body
|
||||
?.functions
|
||||
?.singleOrNull()
|
||||
?.valueParameters
|
||||
?.map { it.typeReference?.toJK(symbolProvider)?.substituteTypeParameters(this) ?: return null }
|
||||
?.map { typeFactory.fromKotlinType(it.kotlinType(it.analyze()) ?: return null).substituteTypeParameters(this) }
|
||||
is JKUniverseClassSymbol -> reference.target.classBody.declarations.firstIsInstanceOrNull<JKMethod>()
|
||||
?.parameters
|
||||
?.map { it.type.type.substituteTypeParameters(this) }
|
||||
|
||||
@@ -34,7 +34,7 @@ class OperatorExpressionConversion(context: NewJ2kConverterContext) : RecursiveA
|
||||
is JKPostfixExpression -> {
|
||||
val operatorToken = operator.token.toKtToken()
|
||||
val operand = applyToElement(element::expression.detached()) as JKExpression
|
||||
recurse(kotlinPostfixExpression(operand, operatorToken, symbolProvider))
|
||||
recurse(kotlinPostfixExpression(operand, operatorToken, typeFactory))
|
||||
}
|
||||
else -> TODO(element.javaClass.toString())
|
||||
}.withNonCodeElementsFrom(element)
|
||||
@@ -43,7 +43,7 @@ class OperatorExpressionConversion(context: NewJ2kConverterContext) : RecursiveA
|
||||
|
||||
private fun convertPrefixExpression(operand: JKExpression, javaOperator: JKJavaOperatorImpl) =
|
||||
convertTildeExpression(operand, javaOperator)
|
||||
?: kotlinPrefixExpression(operand, javaOperator.token.toKtToken(), symbolProvider)
|
||||
?: kotlinPrefixExpression(operand, javaOperator.token.toKtToken(), typeFactory)
|
||||
|
||||
private fun convertTildeExpression(operand: JKExpression, javaOperator: JKJavaOperatorImpl): JKExpression? =
|
||||
if (javaOperator.token.psiToken == JavaTokenType.TILDE) {
|
||||
@@ -61,14 +61,14 @@ class OperatorExpressionConversion(context: NewJ2kConverterContext) : RecursiveA
|
||||
|
||||
private fun convertBinaryExpression(left: JKExpression, right: JKExpression, token: JKKtOperatorToken): JKBinaryExpression =
|
||||
convertStringImplicitConcatenation(left, right, token)
|
||||
?: kotlinBinaryExpression(left, right, token, symbolProvider)
|
||||
?: kotlinBinaryExpression(left, right, token, typeFactory)
|
||||
|
||||
|
||||
private fun convertStringImplicitConcatenation(left: JKExpression, right: JKExpression, token: JKKtOperatorToken): JKBinaryExpression? =
|
||||
if (token is JKKtSingleValueOperatorToken
|
||||
&& token.psiToken == KtTokens.PLUS
|
||||
&& right.type(symbolProvider)?.isStringType() == true
|
||||
&& left.type(symbolProvider)?.isStringType() == false
|
||||
&& right.type(typeFactory)?.isStringType() == true
|
||||
&& left.type(typeFactory)?.isStringType() == false
|
||||
) {
|
||||
val toStringCall =
|
||||
JKKtCallExpressionImpl(
|
||||
@@ -76,6 +76,6 @@ class OperatorExpressionConversion(context: NewJ2kConverterContext) : RecursiveA
|
||||
JKArgumentListImpl()
|
||||
)
|
||||
val qualifiedCall = JKQualifiedExpressionImpl(left, JKKtQualifierImpl.DOT, toStringCall)
|
||||
kotlinBinaryExpression(qualifiedCall, right, KtTokens.PLUS, symbolProvider)
|
||||
kotlinBinaryExpression(qualifiedCall, right, KtTokens.PLUS, typeFactory)
|
||||
} else null
|
||||
}
|
||||
+2
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.hasWritableUsages
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKVarianceTypeParameterType
|
||||
|
||||
|
||||
class ParameterModificationInMethodCallsConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.copyTreeAndDetach
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaDisjunctionType
|
||||
import org.jetbrains.kotlin.nj2k.useExpression
|
||||
|
||||
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.nj2k.conversions
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import com.intellij.psi.PsiClass
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.j2k.toKotlinMutableTypesMap
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.kotlinTypeByName
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.*
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
|
||||
class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicableConversionBase(context) {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
@@ -49,13 +50,7 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
return when (val typeParametersCount = classSymbol.expectedTypeParametersCount()) {
|
||||
0 -> this
|
||||
else -> JKTypeArgumentListImpl(List(typeParametersCount) {
|
||||
JKTypeElementImpl(
|
||||
kotlinTypeByName(
|
||||
KotlinBuiltIns.FQ_NAMES.any.toSafe().asString(),
|
||||
symbolProvider,
|
||||
Nullability.Nullable
|
||||
)
|
||||
)
|
||||
JKTypeElementImpl(typeFactory.types.nullableAny)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -65,26 +60,20 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
when (typeElement?.parent) {
|
||||
is JKClassLiteralExpression -> this
|
||||
is JKKtIsExpression ->
|
||||
addTypeParametersToRawProjectionType(JKStarProjectionTypeImpl())
|
||||
addTypeParametersToRawProjectionType(JKStarProjectionTypeImpl)
|
||||
.updateNullability(Nullability.NotNull)
|
||||
is JKTypeCastExpression ->
|
||||
addTypeParametersToRawProjectionType(JKStarProjectionTypeImpl())
|
||||
addTypeParametersToRawProjectionType(JKStarProjectionTypeImpl)
|
||||
else ->
|
||||
addTypeParametersToRawProjectionType(
|
||||
JKStarProjectionTypeImpl()
|
||||
)
|
||||
addTypeParametersToRawProjectionType(JKStarProjectionTypeImpl)
|
||||
}
|
||||
|
||||
private fun JKType.mapType(typeElement: JKTypeElement?): JKType =
|
||||
when (this) {
|
||||
is JKJavaPrimitiveType -> mapPrimitiveType()
|
||||
is JKClassType -> mapClassType(typeElement)
|
||||
is JKJavaVoidType ->
|
||||
kotlinTypeByName(
|
||||
KotlinBuiltIns.FQ_NAMES.unit.toSafe().asString(),
|
||||
symbolProvider,
|
||||
Nullability.NotNull
|
||||
)
|
||||
is JKJavaVoidType -> typeFactory.types.unit
|
||||
|
||||
is JKJavaArrayType ->
|
||||
JKClassTypeImpl(
|
||||
symbolProvider.provideClassSymbol(type.arrayFqName()),
|
||||
@@ -137,6 +126,25 @@ class TypeMappingConversion(context: NewJ2kConverterContext) : RecursiveApplicab
|
||||
)
|
||||
}
|
||||
|
||||
private inline fun <reified T : JKType> T.addTypeParametersToRawProjectionType(typeParameter: JKType): T =
|
||||
if (this is JKClassType && parameters.isEmpty()) {
|
||||
val parametersCount = classReference.expectedTypeParametersCount()
|
||||
val typeParameters = List(parametersCount) { typeParameter }
|
||||
JKClassTypeImpl(
|
||||
classReference,
|
||||
typeParameters,
|
||||
nullability
|
||||
) as T
|
||||
} else this
|
||||
|
||||
private fun JKClassSymbol.expectedTypeParametersCount(): Int =
|
||||
when (val resolvedClass = target) {
|
||||
is PsiClass -> resolvedClass.typeParameters.size
|
||||
is KtClass -> resolvedClass.typeParameters.size
|
||||
is JKClass -> resolvedClass.typeParameterList.typeParameters.size
|
||||
else -> 0
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ktFunctionRegex = "kotlin\\.jvm\\.functions\\.Function\\d+".toRegex()
|
||||
private fun isKtFunction(fqName: String) =
|
||||
|
||||
@@ -8,54 +8,48 @@ package org.jetbrains.kotlin.nj2k
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase
|
||||
import org.jetbrains.kotlin.nj2k.symbols.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.JKClassType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeParameterType
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
fun kotlinTypeByName(name: String, symbolProvider: JKSymbolProvider, nullability: Nullability = Nullability.Nullable): JKClassType =
|
||||
JKClassTypeImpl(
|
||||
symbolProvider.provideClassSymbol(name),
|
||||
emptyList(),
|
||||
nullability
|
||||
)
|
||||
|
||||
private fun JKType.classSymbol(symbolProvider: JKSymbolProvider) =
|
||||
when (this) {
|
||||
is JKClassType -> classReference
|
||||
is JKJavaPrimitiveType ->
|
||||
symbolProvider.provideClassSymbol(jvmPrimitiveType.primitiveType.typeFqName)
|
||||
|
||||
else -> null
|
||||
}
|
||||
private fun JKType.classSymbol(typeFactory: JKTypeFactory) = when (this) {
|
||||
is JKClassType -> classReference
|
||||
is JKJavaPrimitiveType -> typeFactory.fromPrimitiveType(this).classReference
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun JKKtOperatorToken.arithmeticMethodType(
|
||||
leftType: JKType,
|
||||
rightType: JKType,
|
||||
symbolProvider: JKSymbolProvider
|
||||
typeFactory: JKTypeFactory
|
||||
): JKType? {
|
||||
val symbolProvider = typeFactory.symbolProvider
|
||||
|
||||
fun PsiClass.methodReturnType() =
|
||||
allMethods
|
||||
.filter { it.name == operatorName }
|
||||
.firstOrNull {
|
||||
it.parameterList.parameters.singleOrNull()?.takeIf { parameter ->
|
||||
val type = parameter.type.toJK(symbolProvider)
|
||||
if (type !is JKTypeParameterType) rightType.isSubtypeOf(type, symbolProvider)
|
||||
val type = typeFactory.fromPsiType(parameter.type)
|
||||
if (type !is JKTypeParameterType) rightType.isSubtypeOf(type, typeFactory)
|
||||
else true//TODO check for type bounds
|
||||
} != null
|
||||
}?.let { it.returnType?.toJK(symbolProvider) }
|
||||
|
||||
}?.returnType?.let { typeFactory.fromPsiType(it) }
|
||||
|
||||
val classSymbol =
|
||||
if (leftType.isStringType()) symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.string.toSafe())
|
||||
else leftType.classSymbol(symbolProvider)
|
||||
else leftType.classSymbol(typeFactory)
|
||||
|
||||
return when (classSymbol) {
|
||||
is JKMultiverseKtClassSymbol ->
|
||||
@@ -64,7 +58,7 @@ private fun JKKtOperatorToken.arithmeticMethodType(
|
||||
.filterIsInstance<KtNamedFunction>()
|
||||
.filter { it.name == operatorName }
|
||||
.mapNotNull { symbolProvider.provideDirectSymbol(it) as? JKMethodSymbol }
|
||||
.firstOrNull { it.parameterTypes?.singleOrNull()?.takeIf { rightType.isSubtypeOf(it, symbolProvider) } != null }
|
||||
.firstOrNull { it.parameterTypes?.singleOrNull()?.takeIf { rightType.isSubtypeOf(it, typeFactory) } != null }
|
||||
?.returnType
|
||||
is JKUniverseClassSymbol -> classSymbol.target.psi<PsiClass>()?.methodReturnType()
|
||||
is JKMultiverseClassSymbol -> classSymbol.target.methodReturnType()
|
||||
@@ -114,7 +108,7 @@ private val arithmeticOperators = TokenSet.create(
|
||||
KtTokens.PERC
|
||||
)
|
||||
|
||||
private fun JKKtOperatorToken.defaultReturnType(leftType: JKType?, rightType: JKType?, symbolProvider: JKSymbolProvider): JKType? {
|
||||
private fun JKKtOperatorToken.defaultReturnType(leftType: JKType?): JKType? {
|
||||
if (this is JKKtSingleValueOperatorToken && psiToken in arithmeticOperators) return leftType
|
||||
return null
|
||||
}
|
||||
@@ -123,21 +117,22 @@ fun kotlinBinaryExpression(
|
||||
left: JKExpression,
|
||||
right: JKExpression,
|
||||
token: JKKtOperatorToken,
|
||||
symbolProvider: JKSymbolProvider
|
||||
typeFactory: JKTypeFactory
|
||||
): JKBinaryExpression {
|
||||
val symbolProvider = typeFactory.symbolProvider
|
||||
val returnType =
|
||||
when {
|
||||
token is JKKtSingleValueOperatorToken && token.psiToken in booleanOperators ->
|
||||
JKClassTypeImpl(symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES._boolean.toSafe()))
|
||||
else -> {
|
||||
val leftType = left.type(symbolProvider)
|
||||
val rightType = right.type(symbolProvider)
|
||||
val leftType = left.type(typeFactory)
|
||||
val rightType = right.type(typeFactory)
|
||||
leftType?.let { l ->
|
||||
rightType?.let { r ->
|
||||
token.arithmeticMethodType(l, r, symbolProvider)
|
||||
token.arithmeticMethodType(l, r, typeFactory)
|
||||
}
|
||||
} ?: token.defaultReturnType(leftType, rightType, symbolProvider)
|
||||
?: symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.nothing.toSafe()).asType()
|
||||
} ?: token.defaultReturnType(leftType)
|
||||
?: typeFactory.types.nothing
|
||||
}
|
||||
}
|
||||
return JKBinaryExpressionImpl(left, right, JKKtOperatorImpl(token, returnType))
|
||||
@@ -147,30 +142,30 @@ fun kotlinBinaryExpression(
|
||||
left: JKExpression,
|
||||
right: JKExpression,
|
||||
token: KtSingleValueToken,
|
||||
symbolProvider: JKSymbolProvider
|
||||
typeFactory: JKTypeFactory
|
||||
): JKBinaryExpression =
|
||||
kotlinBinaryExpression(
|
||||
left,
|
||||
right,
|
||||
JKKtSingleValueOperatorToken(token),
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
|
||||
fun kotlinPrefixExpression(
|
||||
operand: JKExpression,
|
||||
token: JKKtOperatorToken,
|
||||
symbolProvider: JKSymbolProvider
|
||||
typeFactory: JKTypeFactory
|
||||
): JKPrefixExpression {
|
||||
val operandType = operand.type(symbolProvider) ?: JKNoTypeImpl
|
||||
val operandType = operand.type(typeFactory) ?: JKNoTypeImpl
|
||||
return JKPrefixExpressionImpl(operand, JKKtOperatorImpl(token, operandType))
|
||||
}
|
||||
|
||||
fun kotlinPostfixExpression(
|
||||
operand: JKExpression,
|
||||
token: JKKtOperatorToken,
|
||||
symbolProvider: JKSymbolProvider
|
||||
typeFactory: JKTypeFactory
|
||||
): JKPostfixExpression {
|
||||
val operandType = operand.type(symbolProvider) ?: JKNoTypeImpl
|
||||
val operandType = operand.type(typeFactory) ?: JKNoTypeImpl
|
||||
return JKPostfixExpressionImpl(operand, JKKtOperatorImpl(token, operandType))
|
||||
}
|
||||
|
||||
@@ -248,11 +243,12 @@ fun useExpression(
|
||||
return JKQualifiedExpressionImpl(receiver, JKKtQualifierImpl.DOT, methodCall)
|
||||
}
|
||||
|
||||
fun kotlinAssert(assertion: JKExpression, message: JKExpression?, symbolProvider: JKSymbolProvider) =
|
||||
fun kotlinAssert(assertion: JKExpression, message: JKExpression?, typeFactory: JKTypeFactory) =
|
||||
JKKtCallExpressionImpl(
|
||||
JKUnresolvedMethod(//TODO resolve assert
|
||||
"assert",
|
||||
kotlinTypeByName(KotlinBuiltIns.FQ_NAMES.unit.asString(), symbolProvider)
|
||||
typeFactory,
|
||||
typeFactory.types.unit
|
||||
),
|
||||
(listOfNotNull(assertion, message)).toArgumentList()
|
||||
)
|
||||
@@ -275,20 +271,20 @@ fun throwAnnotation(throws: List<JKType>, symbolProvider: JKSymbolProvider) =
|
||||
fun JKAnnotationList.annotationByFqName(fqName: String): JKAnnotation? =
|
||||
annotations.firstOrNull { it.classSymbol.fqName == fqName }
|
||||
|
||||
fun stringLiteral(content: String, symbolProvider: JKSymbolProvider): JKExpression {
|
||||
fun stringLiteral(content: String, typeFactory: JKTypeFactory): JKExpression {
|
||||
val lines = content.split('\n')
|
||||
return lines.mapIndexed { i, line ->
|
||||
val newlineSeparator = if (i == lines.size - 1) "" else "\\n"
|
||||
JKKtLiteralExpressionImpl("\"$line$newlineSeparator\"", JKLiteralExpression.LiteralType.STRING)
|
||||
}.reduce { acc: JKExpression, literalExpression: JKKtLiteralExpression ->
|
||||
kotlinBinaryExpression(acc, literalExpression, JKKtSingleValueOperatorToken(KtTokens.PLUS), symbolProvider)
|
||||
kotlinBinaryExpression(acc, literalExpression, JKKtSingleValueOperatorToken(KtTokens.PLUS), typeFactory)
|
||||
}
|
||||
}
|
||||
|
||||
fun JKVariable.findUsages(scope: JKTreeElement, context: NewJ2kConverterContext): List<JKFieldAccessExpression> {
|
||||
val symbol = context.symbolProvider.provideUniverseSymbol(this)
|
||||
val usages = mutableListOf<JKFieldAccessExpression>()
|
||||
val searcher = object : RecursiveApplicableConversionBase() {
|
||||
val searcher = object : RecursiveApplicableConversionBase(context) {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element is JKExpression) {
|
||||
element.unboxFieldReference()?.also {
|
||||
@@ -323,12 +319,12 @@ fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: NewJ2kConverterC
|
||||
|| it.isInDecrementOrIncrement()
|
||||
}
|
||||
|
||||
fun equalsExpression(left: JKExpression, right: JKExpression, symbolProvider: JKSymbolProvider) =
|
||||
fun equalsExpression(left: JKExpression, right: JKExpression, typeFactory: JKTypeFactory) =
|
||||
kotlinBinaryExpression(
|
||||
left,
|
||||
right,
|
||||
KtTokens.EQEQ,
|
||||
symbolProvider
|
||||
typeFactory
|
||||
)
|
||||
|
||||
fun createCompanion(declarations: List<JKDeclaration>): JKClass =
|
||||
|
||||
@@ -8,12 +8,13 @@ package org.jetbrains.kotlin.nj2k.symbols
|
||||
import com.intellij.psi.PsiClass
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKClass
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
|
||||
|
||||
sealed class JKClassSymbol : JKSymbol
|
||||
|
||||
class JKUniverseClassSymbol(override val symbolProvider: JKSymbolProvider) : JKClassSymbol(), JKUniverseSymbol<JKClass> {
|
||||
class JKUniverseClassSymbol(override val typeFactory: JKTypeFactory) : JKClassSymbol(), JKUniverseSymbol<JKClass> {
|
||||
override lateinit var target: JKClass
|
||||
override val name: String
|
||||
get() = target.name.value
|
||||
@@ -21,12 +22,15 @@ class JKUniverseClassSymbol(override val symbolProvider: JKSymbolProvider) : JKC
|
||||
|
||||
class JKMultiverseClassSymbol(
|
||||
override val target: PsiClass,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKClassSymbol(), JKMultiverseSymbol<PsiClass>
|
||||
|
||||
class JKMultiverseKtClassSymbol(
|
||||
override val target: KtClassOrObject,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKClassSymbol(), JKMultiverseKtSymbol<KtClassOrObject>
|
||||
|
||||
class JKUnresolvedClassSymbol(override val target: String) : JKClassSymbol(), JKUnresolvedSymbol
|
||||
class JKUnresolvedClassSymbol(
|
||||
override val target: String,
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKClassSymbol(), JKUnresolvedSymbol
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.nj2k.tree.JKType
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKVariable
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassTypeImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.toJK
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||
@@ -22,7 +23,7 @@ sealed class JKFieldSymbol : JKSymbol {
|
||||
abstract val fieldType: JKType?
|
||||
}
|
||||
|
||||
class JKUniverseFieldSymbol(override val symbolProvider: JKSymbolProvider) : JKFieldSymbol(), JKUniverseSymbol<JKVariable> {
|
||||
class JKUniverseFieldSymbol( override val typeFactory: JKTypeFactory) : JKFieldSymbol(), JKUniverseSymbol<JKVariable> {
|
||||
override val fieldType: JKType
|
||||
get() = target.type.type
|
||||
|
||||
@@ -31,23 +32,23 @@ class JKUniverseFieldSymbol(override val symbolProvider: JKSymbolProvider) : JKF
|
||||
|
||||
class JKMultiverseFieldSymbol(
|
||||
override val target: PsiVariable,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKFieldSymbol(), JKMultiverseSymbol<PsiVariable> {
|
||||
override val fieldType: JKType
|
||||
get() = target.type.toJK(symbolProvider)
|
||||
get() = typeFactory.fromPsiType(target.type)
|
||||
}
|
||||
|
||||
class JKMultiversePropertySymbol(
|
||||
override val target: KtCallableDeclaration,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKFieldSymbol(), JKMultiverseKtSymbol<KtCallableDeclaration> {
|
||||
override val fieldType: JKType?
|
||||
get() = target.typeReference?.toJK(symbolProvider)
|
||||
get() = target.typeReference?.toJK(typeFactory)
|
||||
}
|
||||
|
||||
class JKMultiverseKtEnumEntrySymbol(
|
||||
override val target: KtEnumEntry,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKFieldSymbol(), JKMultiverseKtSymbol<KtEnumEntry> {
|
||||
override val fieldType: JKType?
|
||||
get() = JKClassTypeImpl(
|
||||
@@ -59,10 +60,9 @@ class JKMultiverseKtEnumEntrySymbol(
|
||||
|
||||
class JKUnresolvedField(
|
||||
override val target: String,
|
||||
private val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKFieldSymbol(), JKUnresolvedSymbol {
|
||||
override val fieldType: JKType
|
||||
get() =
|
||||
JKClassTypeImpl(symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.nothing.toSafe()), emptyList())
|
||||
get() = JKClassTypeImpl(symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.nothing.toSafe()), emptyList())
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKClassTypeImpl
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKNoTypeImpl
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -24,7 +25,7 @@ sealed class JKMethodSymbol : JKSymbol {
|
||||
abstract val returnType: JKType?
|
||||
}
|
||||
|
||||
class JKUniverseMethodSymbol(override val symbolProvider: JKSymbolProvider) : JKMethodSymbol(), JKUniverseSymbol<JKMethod> {
|
||||
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*/)
|
||||
@@ -39,16 +40,16 @@ class JKUniverseMethodSymbol(override val symbolProvider: JKSymbolProvider) : JK
|
||||
|
||||
class JKMultiverseMethodSymbol(
|
||||
override val target: PsiMethod,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKMethodSymbol(), JKMultiverseSymbol<PsiMethod> {
|
||||
override val receiverType: JKType?
|
||||
get() = target.containingClass?.let {
|
||||
JKClassTypeImpl(symbolProvider.provideDirectSymbol(it) as JKClassSymbol, emptyList()/*TODO*/)
|
||||
}
|
||||
override val parameterTypes: List<JKType>
|
||||
get() = target.parameterList.parameters.map { it.type.toJK(symbolProvider) }
|
||||
get() = target.parameterList.parameters.map { typeFactory.fromPsiType(it.type) }
|
||||
override val returnType: JKType
|
||||
get() = target.returnType?.toJK(symbolProvider) // null for constructor call
|
||||
get() = target.returnType?.let { typeFactory.fromPsiType(it) } // null for constructor call
|
||||
?: symbolProvider.provideClassSymbol(target.getKotlinFqName()!!).asType(Nullability.NotNull)
|
||||
|
||||
override val fqName: String
|
||||
@@ -60,15 +61,15 @@ class JKMultiverseMethodSymbol(
|
||||
|
||||
class JKMultiverseFunctionSymbol(
|
||||
override val target: KtFunction,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKMethodSymbol(), JKMultiverseKtSymbol<KtFunction> {
|
||||
override val receiverType: JKType?
|
||||
get() = target.receiverTypeReference?.toJK(symbolProvider)
|
||||
get() = target.receiverTypeReference?.toJK(typeFactory)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override val parameterTypes: List<JKType>?
|
||||
get() = target.valueParameters.map { parameter ->
|
||||
val type = parameter.typeReference?.toJK(symbolProvider)
|
||||
val type = parameter.typeReference?.toJK(typeFactory)
|
||||
type?.let {
|
||||
if (parameter.isVarArg) {
|
||||
JKClassTypeImpl(
|
||||
@@ -80,14 +81,15 @@ class JKMultiverseFunctionSymbol(
|
||||
}.takeIf { parameters -> parameters.all { it != null } } as? List<JKType>
|
||||
|
||||
override val returnType: JKType?
|
||||
get() = target.typeReference?.toJK(symbolProvider)
|
||||
get() = target.typeReference?.toJK(typeFactory)
|
||||
}
|
||||
|
||||
class JKUnresolvedMethod(
|
||||
override val target: String,
|
||||
override val typeFactory: JKTypeFactory,
|
||||
override val returnType: JKType = JKNoTypeImpl
|
||||
) : JKMethodSymbol(), JKUnresolvedSymbol {
|
||||
constructor(target: PsiReference) : this(target.canonicalText)
|
||||
constructor(target: PsiReference, typeFactory: JKTypeFactory) : this(target.canonicalText, typeFactory)
|
||||
|
||||
override val receiverType: JKType?
|
||||
get() = null
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.nj2k.symbols
|
||||
|
||||
import com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
|
||||
|
||||
sealed class JKPackageSymbol : JKSymbol {
|
||||
@@ -15,5 +16,5 @@ sealed class JKPackageSymbol : JKSymbol {
|
||||
|
||||
class JKMultiversePackageSymbol(
|
||||
override val target: PsiPackage,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKPackageSymbol(), JKMultiverseSymbol<PsiPackage>
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKDeclaration
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKFile
|
||||
import org.jetbrains.kotlin.nj2k.tree.parentOfType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
@@ -22,10 +23,14 @@ interface JKSymbol {
|
||||
val declaredIn: JKSymbol?
|
||||
val fqName: String
|
||||
val name: String
|
||||
|
||||
val typeFactory: JKTypeFactory
|
||||
val symbolProvider: JKSymbolProvider
|
||||
get() = typeFactory.symbolProvider
|
||||
}
|
||||
|
||||
|
||||
interface JKUniverseSymbol<T : JKDeclaration> : JKSymbol {
|
||||
val symbolProvider: JKSymbolProvider
|
||||
override var target: T
|
||||
override val fqName: String
|
||||
get() {
|
||||
@@ -47,8 +52,6 @@ interface JKUniverseSymbol<T : JKDeclaration> : JKSymbol {
|
||||
}
|
||||
|
||||
interface JKMultiverseSymbol<T> : JKSymbol where T : PsiNamedElement, T : PsiElement {
|
||||
val symbolProvider: JKSymbolProvider
|
||||
|
||||
override val target: T
|
||||
override val declaredIn: JKSymbol?
|
||||
get() = target.getStrictParentOfType<PsiMember>()?.let { symbolProvider.provideDirectSymbol(it) }
|
||||
@@ -59,8 +62,6 @@ interface JKMultiverseSymbol<T> : JKSymbol where T : PsiNamedElement, T : PsiEle
|
||||
}
|
||||
|
||||
interface JKMultiverseKtSymbol<T : KtNamedDeclaration> : JKSymbol {
|
||||
val symbolProvider: JKSymbolProvider
|
||||
|
||||
override val target: T
|
||||
override val name: String
|
||||
get() = target.name!!
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiTypeParameter
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKTypeParameter
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.nj2k.types.JKTypeFactory
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
@@ -20,14 +21,14 @@ sealed class JKTypeParameterSymbol : JKSymbol {
|
||||
|
||||
class JKMultiverseTypeParameterSymbol(
|
||||
override val target: PsiTypeParameter,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKTypeParameterSymbol(), JKMultiverseSymbol<PsiTypeParameter> {
|
||||
override val index: Int
|
||||
get() = target.index
|
||||
}
|
||||
|
||||
class JKUniverseTypeParameterSymbol(
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKTypeParameterSymbol(), JKUniverseSymbol<JKTypeParameter> {
|
||||
override val index: Int
|
||||
get() = declaredIn?.safeAs<JKTypeParameterListOwner>()?.typeParameterList?.typeParameters?.indexOf(target) ?: -1
|
||||
@@ -36,7 +37,7 @@ class JKUniverseTypeParameterSymbol(
|
||||
|
||||
class JKMultiverseKtTypeParameterSymbol(
|
||||
override val target: KtTypeParameter,
|
||||
override val symbolProvider: JKSymbolProvider
|
||||
override val typeFactory: JKTypeFactory
|
||||
) : JKTypeParameterSymbol(), JKMultiverseKtSymbol<KtTypeParameter> {
|
||||
override val index: Int
|
||||
get() = target.getParentOfType<KtTypeParameterListOwner>(strict = false)?.typeParameters?.indexOf(target) ?: -1
|
||||
|
||||
@@ -24,9 +24,8 @@ import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.symbols.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.BOOLEAN
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.NULL
|
||||
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
|
||||
import org.jetbrains.kotlin.nj2k.types.*
|
||||
|
||||
class JKTreeRootImpl(element: JKTreeElement) : JKTreeRoot, JKBranchElementBase() {
|
||||
override var element by child(element)
|
||||
@@ -211,7 +210,7 @@ object JKNoTypeImpl : JKNoType {
|
||||
override val nullability: Nullability = Nullability.NotNull
|
||||
}
|
||||
|
||||
class JKStarProjectionTypeImpl : JKStarProjectionType
|
||||
object JKStarProjectionTypeImpl : JKStarProjectionType
|
||||
|
||||
val JKType.fqName: String?
|
||||
get() = when (this) {
|
||||
@@ -224,7 +223,7 @@ class JKNullLiteral : JKLiteralExpression, JKElementBase(), PsiOwner by PsiOwner
|
||||
override val literal: String
|
||||
get() = "null"
|
||||
override val type: LiteralType
|
||||
get() = NULL
|
||||
get() = LiteralType.NULL
|
||||
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitLiteralExpression(this)
|
||||
}
|
||||
@@ -233,29 +232,20 @@ class JKBooleanLiteral(val value: Boolean) : JKLiteralExpression, JKElementBase(
|
||||
override val literal: String
|
||||
get() = value.toString()
|
||||
override val type: LiteralType
|
||||
get() = BOOLEAN
|
||||
get() = LiteralType.BOOLEAN
|
||||
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitLiteralExpression(this)
|
||||
}
|
||||
|
||||
fun JKLiteralExpression.LiteralType.toJkType(symbolProvider: JKSymbolProvider): JKType {
|
||||
fun defaultTypeByName(name: String) =
|
||||
JKClassTypeImpl(
|
||||
symbolProvider.provideClassSymbol("kotlin.$name"), emptyList(), Nullability.NotNull
|
||||
)
|
||||
|
||||
return when (this) {
|
||||
JKLiteralExpression.LiteralType.CHAR -> defaultTypeByName("Char")
|
||||
JKLiteralExpression.LiteralType.BOOLEAN -> defaultTypeByName("Boolean")
|
||||
JKLiteralExpression.LiteralType.INT -> defaultTypeByName("Int")
|
||||
JKLiteralExpression.LiteralType.LONG -> defaultTypeByName("Long")
|
||||
JKLiteralExpression.LiteralType.FLOAT -> defaultTypeByName("Float")
|
||||
JKLiteralExpression.LiteralType.DOUBLE -> defaultTypeByName("Double")
|
||||
JKLiteralExpression.LiteralType.NULL ->
|
||||
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.unit.toSafe()).toKtClassType(symbolProvider)
|
||||
JKLiteralExpression.LiteralType.STRING ->
|
||||
ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.string.toSafe()).toKtClassType(symbolProvider)
|
||||
}
|
||||
fun LiteralType.toJkType(typeFactory: JKTypeFactory): JKType = when (this) {
|
||||
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
|
||||
}
|
||||
|
||||
class JKLocalVariableImpl(
|
||||
@@ -553,7 +543,7 @@ class JKAnnotationImpl(
|
||||
|
||||
class JKTypeArgumentListImpl(typeArguments: List<JKTypeElement> = emptyList()) : JKTypeArgumentList, JKBranchElementBase(),
|
||||
PsiOwner by PsiOwnerImpl() {
|
||||
override val typeArguments: List<JKTypeElement> by children(typeArguments)
|
||||
override var typeArguments: List<JKTypeElement> by children(typeArguments)
|
||||
override fun accept(visitor: JKVisitor) = visitor.visitTypeArgumentList(this)
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
|
||||
import org.jetbrains.kotlin.nj2k.tree.visitors.JKVisitor
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaDisjunctionType
|
||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
|
||||
class JKJavaFieldImpl(
|
||||
@@ -288,7 +291,8 @@ object JKJavaVoidType : JKType {
|
||||
set(it) {}
|
||||
}
|
||||
|
||||
data class JKJavaArrayTypeImpl(override val type: JKType, override var nullability: Nullability = Nullability.Default) : JKJavaArrayType {
|
||||
data class JKJavaArrayTypeImpl(override val type: JKType, override var nullability: Nullability = Nullability.Default) :
|
||||
JKJavaArrayType {
|
||||
}
|
||||
|
||||
class JKJavaDisjunctionTypeImpl(
|
||||
|
||||
@@ -44,7 +44,7 @@ abstract class JKEmptyClassBody : JKClassBody() {
|
||||
}
|
||||
|
||||
interface JKJavaNewExpression : JKExpression, JKTypeArgumentListOwner, PsiOwner {
|
||||
val classSymbol: JKClassSymbol
|
||||
var classSymbol: JKClassSymbol
|
||||
var arguments: JKArgumentList
|
||||
var classBody: JKClassBody
|
||||
}
|
||||
|
||||
@@ -5,159 +5,88 @@
|
||||
|
||||
package org.jetbrains.kotlin.nj2k.tree
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.kotlinTypeByName
|
||||
import org.jetbrains.kotlin.nj2k.symbols.*
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKMultiverseClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKMultiverseKtClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKUniverseClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
||||
import org.jetbrains.kotlin.nj2k.types.*
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
fun JKExpression.type(symbolProvider: JKSymbolProvider): JKType? =
|
||||
fun JKExpression.type(typeFactory: JKTypeFactory): JKType? =
|
||||
when (this) {
|
||||
is JKLiteralExpression -> type.toJkType(symbolProvider)
|
||||
is JKLiteralExpression -> type.toJkType(typeFactory)
|
||||
is JKOperatorExpression -> {
|
||||
val operator = operator
|
||||
when (operator) {
|
||||
when (val operator = operator) {
|
||||
is JKKtOperatorImpl -> operator.returnType
|
||||
is JKKtSpreadOperator -> (this as JKPrefixExpression).expression.type(symbolProvider)//TODO ger real type
|
||||
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 JKMethodCallExpression -> identifier.returnType
|
||||
is JKFieldAccessExpressionImpl -> identifier.fieldType
|
||||
is JKQualifiedExpressionImpl -> selector.type(symbolProvider)
|
||||
is JKKtThrowExpression -> kotlinTypeByName(KotlinBuiltIns.FQ_NAMES.nothing.asString(), symbolProvider)
|
||||
is JKQualifiedExpressionImpl -> selector.type(typeFactory)
|
||||
is JKKtThrowExpression -> typeFactory.types.nothing
|
||||
is JKClassAccessExpression ->
|
||||
JKClassTypeImpl(identifier, emptyList(), Nullability.NotNull)
|
||||
is JKJavaNewExpression -> JKClassTypeImpl(classSymbol)
|
||||
is JKKtIsExpression -> kotlinTypeByName(KotlinBuiltIns.FQ_NAMES._boolean.asString(), symbolProvider)
|
||||
is JKParenthesizedExpression -> expression.type(symbolProvider)
|
||||
is JKKtIsExpression -> 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(symbolProvider)// TODO return actual type
|
||||
is JKIfElseExpression -> thenBranch.type(typeFactory)// TODO return actual type
|
||||
is JKArrayAccessExpression ->
|
||||
(expression.type(symbolProvider) as? JKParametrizedType)?.parameters?.lastOrNull()
|
||||
(expression.type(typeFactory) as? JKParametrizedType)?.parameters?.lastOrNull()
|
||||
is JKClassLiteralExpression -> {
|
||||
val symbol = when (literalType) {
|
||||
JKClassLiteralExpression.LiteralType.KOTLIN_CLASS ->
|
||||
symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.kClass.toSafe())
|
||||
typeFactory.symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.kClass.toSafe())
|
||||
JKClassLiteralExpression.LiteralType.JAVA_CLASS,
|
||||
JKClassLiteralExpression.LiteralType.JAVA_PRIMITIVE_CLASS, JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE ->
|
||||
symbolProvider.provideClassSymbol("java.lang.Class")
|
||||
typeFactory.symbolProvider.provideClassSymbol("java.lang.Class")
|
||||
}
|
||||
JKClassTypeImpl(symbol, listOf(classType.type), Nullability.NotNull)
|
||||
}
|
||||
is JKKtAnnotationArrayInitializerExpression -> JKNoTypeImpl //TODO
|
||||
is JKLambdaExpression -> returnType.type
|
||||
is JKLabeledStatement ->
|
||||
statement.safeAs<JKExpressionStatement>()?.expression?.type(symbolProvider)
|
||||
statement.safeAs<JKExpressionStatement>()?.expression?.type(typeFactory)
|
||||
is JKMethodReferenceExpression -> JKNoTypeImpl //TODO
|
||||
else -> TODO(this::class.java.toString())
|
||||
}
|
||||
|
||||
fun ClassId.toKtClassType(
|
||||
symbolProvider: JKSymbolProvider,
|
||||
nullability: Nullability = Nullability.Default
|
||||
): JKType =
|
||||
JKClassTypeImpl(symbolProvider.provideClassSymbol(asSingleFqName()), emptyList(), nullability)
|
||||
|
||||
|
||||
fun PsiType.toJK(symbolProvider: JKSymbolProvider, nullability: Nullability = Nullability.Default): JKType {
|
||||
return when (this) {
|
||||
is PsiClassType -> {
|
||||
val target = resolve()
|
||||
val parameters = parameters.map { it.toJK(symbolProvider, nullability) }
|
||||
when (target) {
|
||||
null ->
|
||||
JKClassTypeImpl(JKUnresolvedClassSymbol(rawType().canonicalText), parameters, nullability)
|
||||
is PsiTypeParameter ->
|
||||
JKTypeParameterTypeImpl(symbolProvider.provideDirectSymbol(target) as JKTypeParameterSymbol)
|
||||
else -> {
|
||||
JKClassTypeImpl(
|
||||
target.let { symbolProvider.provideDirectSymbol(it) as JKClassSymbol },
|
||||
parameters,
|
||||
nullability
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is PsiArrayType -> JKJavaArrayTypeImpl(componentType.toJK(symbolProvider, nullability), nullability)
|
||||
is PsiPrimitiveType -> JKJavaPrimitiveTypeImpl.KEYWORD_TO_INSTANCE[presentableText]
|
||||
?: error("Invalid primitive type $presentableText")
|
||||
is PsiDisjunctionType ->
|
||||
JKJavaDisjunctionTypeImpl(disjunctions.map { it.toJK(symbolProvider) })
|
||||
is PsiWildcardType ->
|
||||
when {
|
||||
isExtends ->
|
||||
JKVarianceTypeParameterTypeImpl(
|
||||
JKVarianceTypeParameterType.Variance.OUT,
|
||||
extendsBound.toJK(symbolProvider)
|
||||
)
|
||||
isSuper ->
|
||||
JKVarianceTypeParameterTypeImpl(
|
||||
JKVarianceTypeParameterType.Variance.IN,
|
||||
superBound.toJK(symbolProvider)
|
||||
)
|
||||
else -> JKStarProjectionTypeImpl()
|
||||
}
|
||||
is PsiCapturedWildcardType ->
|
||||
JKCapturedType(
|
||||
wildcard.toJK(symbolProvider, nullability) as JKWildCardType,
|
||||
nullability
|
||||
)
|
||||
else -> throw Exception("Invalid PSI ${this::class.java}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun JKType.asTypeElement() =
|
||||
JKTypeElementImpl(this)
|
||||
|
||||
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
|
||||
JKClassTypeImpl(this, emptyList(), nullability)
|
||||
|
||||
fun JKType.isSubtypeOf(other: JKType, symbolProvider: JKSymbolProvider): Boolean =
|
||||
other.toKtType(symbolProvider)
|
||||
?.let { otherType -> this.toKtType(symbolProvider)?.isSubtypeOf(otherType) } == true
|
||||
fun JKType.isSubtypeOf(other: JKType, typeFactory: JKTypeFactory): Boolean =
|
||||
other.toKtType(typeFactory)
|
||||
?.let { otherType -> this.toKtType(typeFactory)?.isSubtypeOf(otherType) } == true
|
||||
|
||||
|
||||
fun KotlinType.toJK(symbolProvider: JKSymbolProvider): JKType {
|
||||
return when (val descriptor = constructor.declarationDescriptor) {
|
||||
is TypeParameterDescriptor ->
|
||||
JKTypeParameterTypeImpl(
|
||||
symbolProvider.provideDirectSymbol(descriptor.findPsi() as? KtTypeParameter ?: return JKNoTypeImpl) as JKTypeParameterSymbol
|
||||
)
|
||||
|
||||
else -> JKClassTypeImpl(
|
||||
symbolProvider.provideClassSymbol(getJetTypeFqName(false)),
|
||||
arguments.map { it.type.toJK(symbolProvider) },
|
||||
if (isNullable()) Nullability.Nullable else Nullability.NotNull
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val PsiType.isKotlinFunctionalType: Boolean
|
||||
get() {
|
||||
val fqName = safeAs<PsiClassType>()?.resolve()?.getKotlinFqName() ?: return false
|
||||
@@ -168,22 +97,17 @@ val PsiType.isKotlinFunctionalType: Boolean
|
||||
private val functionalTypeRegex = """(kotlin\.jvm\.functions|kotlin)\.Function[\d+]""".toRegex()
|
||||
|
||||
|
||||
fun KtTypeReference.toJK(symbolProvider: JKSymbolProvider): JKType? =
|
||||
fun KtTypeReference.toJK(typeFactory: JKTypeFactory): JKType? =
|
||||
analyze(BodyResolveMode.PARTIAL)
|
||||
.get(BindingContext.TYPE, this)
|
||||
?.toJK(symbolProvider)
|
||||
?.let { typeFactory.fromKotlinType(it) }
|
||||
|
||||
|
||||
fun JKType.toKtType(symbolProvider: JKSymbolProvider): KotlinType? =
|
||||
when (this) {
|
||||
is JKClassType -> classReference.toKtType()
|
||||
is JKJavaPrimitiveType ->
|
||||
kotlinTypeByName(
|
||||
jvmPrimitiveType.primitiveType.typeFqName.asString(),
|
||||
symbolProvider
|
||||
).toKtType(symbolProvider)
|
||||
else -> null
|
||||
}
|
||||
fun JKType.toKtType(typeFactory: JKTypeFactory): KotlinType? = when (this) {
|
||||
is JKClassType -> classReference.toKtType()
|
||||
is JKJavaPrimitiveType -> typeFactory.fromPrimitiveType(this).toKtType(typeFactory)
|
||||
else -> null
|
||||
}
|
||||
|
||||
infix fun JKJavaPrimitiveType.isStrongerThan(other: JKJavaPrimitiveType) =
|
||||
jvmPrimitiveTypesPriority.getValue(this.jvmPrimitiveType.primitiveType) >
|
||||
@@ -274,27 +198,15 @@ fun JKClassSymbol.isStringType(): Boolean =
|
||||
fqName == CommonClassNames.JAVA_LANG_STRING
|
||||
|| fqName == KotlinBuiltIns.FQ_NAMES.string.asString()
|
||||
|
||||
fun JKLiteralExpression.LiteralType.toPrimitiveType(): JKJavaPrimitiveType? =
|
||||
when (this) {
|
||||
JKLiteralExpression.LiteralType.CHAR -> JKJavaPrimitiveTypeImpl.CHAR
|
||||
JKLiteralExpression.LiteralType.BOOLEAN -> JKJavaPrimitiveTypeImpl.BOOLEAN
|
||||
JKLiteralExpression.LiteralType.INT -> JKJavaPrimitiveTypeImpl.INT
|
||||
JKLiteralExpression.LiteralType.LONG -> JKJavaPrimitiveTypeImpl.LONG
|
||||
JKLiteralExpression.LiteralType.FLOAT -> JKJavaPrimitiveTypeImpl.FLOAT
|
||||
JKLiteralExpression.LiteralType.DOUBLE -> JKJavaPrimitiveTypeImpl.DOUBLE
|
||||
JKLiteralExpression.LiteralType.STRING -> null
|
||||
JKLiteralExpression.LiteralType.NULL -> null
|
||||
}
|
||||
|
||||
fun JKJavaPrimitiveType.toLiteralType(): JKLiteralExpression.LiteralType? =
|
||||
when (this) {
|
||||
JKJavaPrimitiveTypeImpl.CHAR -> JKLiteralExpression.LiteralType.CHAR
|
||||
JKJavaPrimitiveTypeImpl.BOOLEAN -> JKLiteralExpression.LiteralType.BOOLEAN
|
||||
JKJavaPrimitiveTypeImpl.INT -> JKLiteralExpression.LiteralType.INT
|
||||
JKJavaPrimitiveTypeImpl.LONG -> JKLiteralExpression.LiteralType.LONG
|
||||
JKJavaPrimitiveTypeImpl.CHAR -> JKLiteralExpression.LiteralType.CHAR
|
||||
JKJavaPrimitiveTypeImpl.DOUBLE -> JKLiteralExpression.LiteralType.DOUBLE
|
||||
JKJavaPrimitiveTypeImpl.FLOAT -> JKLiteralExpression.LiteralType.FLOAT
|
||||
JKJavaPrimitiveType.CHAR -> JKLiteralExpression.LiteralType.CHAR
|
||||
JKJavaPrimitiveType.BOOLEAN -> JKLiteralExpression.LiteralType.BOOLEAN
|
||||
JKJavaPrimitiveType.INT -> JKLiteralExpression.LiteralType.INT
|
||||
JKJavaPrimitiveType.LONG -> JKLiteralExpression.LiteralType.LONG
|
||||
JKJavaPrimitiveType.CHAR -> JKLiteralExpression.LiteralType.CHAR
|
||||
JKJavaPrimitiveType.DOUBLE -> JKLiteralExpression.LiteralType.DOUBLE
|
||||
JKJavaPrimitiveType.FLOAT -> JKLiteralExpression.LiteralType.FLOAT
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -314,29 +226,10 @@ fun JKType.asPrimitiveType(): JKJavaPrimitiveType? =
|
||||
}
|
||||
|
||||
fun JKJavaPrimitiveType.isNumberType() =
|
||||
this == JKJavaPrimitiveTypeImpl.INT ||
|
||||
this == JKJavaPrimitiveTypeImpl.LONG ||
|
||||
this == JKJavaPrimitiveTypeImpl.FLOAT ||
|
||||
this == JKJavaPrimitiveTypeImpl.DOUBLE
|
||||
|
||||
inline fun <reified T : JKType> T.addTypeParametersToRawProjectionType(typeParameter: JKType): T =
|
||||
if (this is JKClassType && parameters.isEmpty()) {
|
||||
val parametersCount = classReference.expectedTypeParametersCount()
|
||||
val typeParameters = List(parametersCount) { typeParameter }
|
||||
JKClassTypeImpl(
|
||||
classReference,
|
||||
typeParameters,
|
||||
nullability
|
||||
) as T
|
||||
} else this
|
||||
|
||||
fun JKClassSymbol.expectedTypeParametersCount(): Int =
|
||||
when (val resolvedClass = target) {
|
||||
is PsiClass -> resolvedClass.typeParameters.size
|
||||
is KtClass -> resolvedClass.typeParameters.size
|
||||
is JKClass -> resolvedClass.typeParameterList.typeParameters.size
|
||||
else -> 0
|
||||
}
|
||||
this == JKJavaPrimitiveType.INT ||
|
||||
this == JKJavaPrimitiveType.LONG ||
|
||||
this == JKJavaPrimitiveType.FLOAT ||
|
||||
this == JKJavaPrimitiveType.DOUBLE
|
||||
|
||||
|
||||
val primitiveTypes =
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.nj2k.types
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.nj2k.JKSymbolProvider
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedClassSymbol
|
||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
|
||||
class JKTypeFactory(val symbolProvider: JKSymbolProvider) {
|
||||
fun fromPsiType(type: PsiType): JKType = createPsiType(type)
|
||||
fun fromKotlinType(type: KotlinType): JKType = createKotlinType(type)
|
||||
|
||||
inner class DefaultTypes {
|
||||
private fun typeByFqName(
|
||||
fqName: FqNameUnsafe,
|
||||
typeArguments: List<JKType> = emptyList(),
|
||||
nullability: Nullability = Nullability.NotNull
|
||||
) = JKClassType(
|
||||
symbolProvider.provideClassSymbol(fqName),
|
||||
typeArguments,
|
||||
nullability
|
||||
)
|
||||
|
||||
val boolean = typeByFqName(KotlinBuiltIns.FQ_NAMES._boolean)
|
||||
val char = typeByFqName(KotlinBuiltIns.FQ_NAMES._char)
|
||||
val byte = typeByFqName(KotlinBuiltIns.FQ_NAMES._byte)
|
||||
val short = typeByFqName(KotlinBuiltIns.FQ_NAMES._short)
|
||||
val int = typeByFqName(KotlinBuiltIns.FQ_NAMES._int)
|
||||
val float = typeByFqName(KotlinBuiltIns.FQ_NAMES._float)
|
||||
val long = typeByFqName(KotlinBuiltIns.FQ_NAMES._long)
|
||||
val double = typeByFqName(KotlinBuiltIns.FQ_NAMES._double)
|
||||
|
||||
val string = typeByFqName(KotlinBuiltIns.FQ_NAMES.string)
|
||||
val possiblyNullString = typeByFqName(KotlinBuiltIns.FQ_NAMES.string, nullability = Nullability.Default)
|
||||
|
||||
val unit = typeByFqName(KotlinBuiltIns.FQ_NAMES.unit)
|
||||
val nothing = typeByFqName(KotlinBuiltIns.FQ_NAMES.nothing)
|
||||
val nullableAny = typeByFqName(KotlinBuiltIns.FQ_NAMES.any, nullability = Nullability.Nullable)
|
||||
}
|
||||
|
||||
fun fromPrimitiveType(primitiveType: JKJavaPrimitiveType) = when (primitiveType.jvmPrimitiveType) {
|
||||
JvmPrimitiveType.BOOLEAN -> types.boolean
|
||||
JvmPrimitiveType.CHAR -> types.char
|
||||
JvmPrimitiveType.BYTE -> types.byte
|
||||
JvmPrimitiveType.SHORT -> types.short
|
||||
JvmPrimitiveType.INT -> types.int
|
||||
JvmPrimitiveType.FLOAT -> types.float
|
||||
JvmPrimitiveType.LONG -> types.long
|
||||
JvmPrimitiveType.DOUBLE -> types.double
|
||||
}
|
||||
|
||||
val types by lazy(LazyThreadSafetyMode.NONE) { DefaultTypes() }
|
||||
|
||||
private fun createPsiType(type: PsiType): JKType = when (type) {
|
||||
is PsiClassType -> {
|
||||
val target = type.resolve()
|
||||
val parameters = type.parameters.map { fromPsiType(it) }
|
||||
when (target) {
|
||||
null ->
|
||||
JKClassType(JKUnresolvedClassSymbol(type.rawType().canonicalText, this), parameters)
|
||||
is PsiTypeParameter ->
|
||||
JKTypeParameterType(symbolProvider.provideDirectSymbol(target) as JKTypeParameterSymbol)
|
||||
else -> {
|
||||
JKClassType(
|
||||
target.let { symbolProvider.provideDirectSymbol(it) as JKClassSymbol },
|
||||
parameters
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is PsiArrayType -> JKJavaArrayType(fromPsiType(type.componentType))
|
||||
is PsiPrimitiveType -> JKJavaPrimitiveType.KEYWORD_TO_INSTANCE[type.presentableText]
|
||||
?: error("Invalid primitive type ${type.presentableText}")
|
||||
is PsiDisjunctionType ->
|
||||
JKJavaDisjunctionType(type.disjunctions.map { fromPsiType(it) })
|
||||
is PsiWildcardType ->
|
||||
when {
|
||||
type.isExtends ->
|
||||
JKVarianceTypeParameterType(
|
||||
JKVarianceTypeParameterType.Variance.OUT,
|
||||
fromPsiType(type.extendsBound)
|
||||
)
|
||||
type.isSuper ->
|
||||
JKVarianceTypeParameterType(
|
||||
JKVarianceTypeParameterType.Variance.IN,
|
||||
fromPsiType(type.superBound)
|
||||
)
|
||||
else -> JKStarProjectionTypeImpl
|
||||
}
|
||||
is PsiCapturedWildcardType ->
|
||||
JKCapturedType(fromPsiType(type.wildcard) as JKWildCardType)
|
||||
else -> throw Exception("Invalid PSI ${this::class.java}")
|
||||
}
|
||||
|
||||
private fun createKotlinType(type: KotlinType): JKType {
|
||||
return when (val descriptor = type.constructor.declarationDescriptor) {
|
||||
is TypeParameterDescriptor ->
|
||||
JKTypeParameterType(
|
||||
symbolProvider.provideDirectSymbol(
|
||||
descriptor.findPsi() as? KtTypeParameter ?: return JKNoType
|
||||
) as JKTypeParameterSymbol
|
||||
)
|
||||
|
||||
else -> JKClassType(
|
||||
symbolProvider.provideClassSymbol(type.getJetTypeFqName(false)),//TODO constructor fqName
|
||||
type.arguments.map { fromKotlinType(it.type) },
|
||||
if (type.isNullable()) Nullability.Nullable else Nullability.NotNull
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -3,11 +3,12 @@
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.nj2k.tree
|
||||
package org.jetbrains.kotlin.nj2k.types
|
||||
|
||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKClassSymbol
|
||||
import org.jetbrains.kotlin.nj2k.symbols.JKTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.nj2k.tree.JKType
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
|
||||
interface JKWildCardType : JKType
|
||||
Reference in New Issue
Block a user