diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/BaseConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/BaseConversion.kt index 232a50efe2b..a1f4bd9f053 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/BaseConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/BaseConversion.kt @@ -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, context: NewJ2kConverterContext): Boolean } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt index 7ca93c4d6ba..7ba199ae3ac 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt @@ -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) { 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()) 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())) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt index 6b7025ed582..84bf03679c9 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt @@ -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()?.parameters?.any { it is PsiCapturedWildcardType } == true }?.takeUnless { type -> type.isKotlinFunctionalType - }?.toJK(symbolProvider) + }?.toJK() ?.asTypeElement() ?: JKTypeElementImpl(JKNoTypeImpl) fun PsiMethodReferenceExpression.toJK(): JKMethodReferenceExpression { val symbol = symbolProvider.provideSymbolForReference(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()?.type ?: JKContextType) + JKTypeElementImpl(type?.toJK().safeAs()?.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()?.type }.last()) + JKTypeElementImpl(generateSequence(type?.toJK()) { it.safeAs()?.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( nameReferenceElement ?: throwCanNotConvertError() ).safeAs() - ?: 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) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt index 3e12be0e564..d24ff1b6373 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/NewCodeBuilder.kt @@ -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 diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt index 61fcc67104e..c457fa762d0 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt @@ -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, diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt index 58790944765..062417ba5b1 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt @@ -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, diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AddElementsInfoConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AddElementsInfoConversion.kt index c41dc75bfc4..b85e50bcda0 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AddElementsInfoConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AddElementsInfoConversion.kt @@ -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) { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationClassConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationClassConversion.kt index 2956213280a..3a5b8ef55f5 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationClassConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationClassConversion.kt @@ -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 { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt index e6900498e9c..e1f0aa962d7 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt @@ -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 diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt index 8147f5a63bb..ed03a3903f4 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt @@ -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() ?.identifier diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssertStatementConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssertStatementConversion.kt index d79e7aa3857..b965efa0b1e 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssertStatementConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssertStatementConversion.kt @@ -29,7 +29,7 @@ class AssertStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl kotlinAssert( element::condition.detached(), messageExpression, - symbolProvider + typeFactory ) ) ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt index bc83dd02cca..2e43588c0ad 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt @@ -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() diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt index 3f17f39dc44..98f0baf2596 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/CollectImportsConversion.kt @@ -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 diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EqualsOperatorConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EqualsOperatorConversion.kt index 06315838377..2f7e64e49ea 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EqualsOperatorConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EqualsOperatorConversion.kt @@ -23,7 +23,7 @@ class EqualsOperatorConversion(context: NewJ2kConverterContext) : RecursiveAppli equalsExpression( element::receiver.detached(), argument::value.detached(), - symbolProvider + typeFactory ) ) ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt index d5f4d6bcd26..2b4d5e2c6bd 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt @@ -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) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt index f35038a8a28..517805fcb4c 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt @@ -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()?.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 } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt index b0e5e9d38c0..cf5fa6bf5ef 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt @@ -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) { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/InsertDefaultPrimaryConstructorConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/InsertDefaultPrimaryConstructorConversion.kt index d863508da94..fcac9cda406 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/InsertDefaultPrimaryConstructorConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/InsertDefaultPrimaryConstructorConversion.kt @@ -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) { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt index f764bb234b9..0f26c922eed 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaStandardMethodsConversion.kt @@ -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 ) ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt index daf418a0569..8318fe7a87e 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt @@ -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 diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt index 07764034d05..4da00bb483f 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt @@ -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() ?.parameters ?.map { it.type.type.substituteTypeParameters(this) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt index 304ff4c3cc1..e4748b99ecf 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt @@ -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 } \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt index 3ab2533d71b..b20476c31ad 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt @@ -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) { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TryStatementConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TryStatementConversion.kt index 6c3c2dcf6cb..7837544903b 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TryStatementConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TryStatementConversion.kt @@ -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 diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt index 32213dca3ed..245e8e862b5 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt @@ -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 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) = diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt index d4cc522e313..d758bda6285 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt @@ -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() .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()?.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, 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 { val symbol = context.symbolProvider.provideUniverseSymbol(this) val usages = mutableListOf() - 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): JKClass = diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKClassSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKClassSymbol.kt index 62c734b26cd..f6728058e84 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKClassSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKClassSymbol.kt @@ -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 { +class JKUniverseClassSymbol(override val typeFactory: JKTypeFactory) : JKClassSymbol(), JKUniverseSymbol { 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 class JKMultiverseKtClassSymbol( override val target: KtClassOrObject, - override val symbolProvider: JKSymbolProvider + override val typeFactory: JKTypeFactory ) : JKClassSymbol(), JKMultiverseKtSymbol -class JKUnresolvedClassSymbol(override val target: String) : JKClassSymbol(), JKUnresolvedSymbol \ No newline at end of file +class JKUnresolvedClassSymbol( + override val target: String, + override val typeFactory: JKTypeFactory +) : JKClassSymbol(), JKUnresolvedSymbol \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt index 84b67c13c48..acebffb8f1b 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt @@ -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 { +class JKUniverseFieldSymbol( override val typeFactory: JKTypeFactory) : JKFieldSymbol(), JKUniverseSymbol { 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 { 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 { 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 { 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()) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt index a2836170298..a1c522f86af 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKMethodSymbol.kt @@ -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 { +class JKUniverseMethodSymbol(override val typeFactory: JKTypeFactory) : JKMethodSymbol(), JKUniverseSymbol { override val receiverType: JKType? get() = target.parent.safeAs()?.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 { override val receiverType: JKType? get() = target.containingClass?.let { JKClassTypeImpl(symbolProvider.provideDirectSymbol(it) as JKClassSymbol, emptyList()/*TODO*/) } override val parameterTypes: List - 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 { override val receiverType: JKType? - get() = target.receiverTypeReference?.toJK(symbolProvider) + get() = target.receiverTypeReference?.toJK(typeFactory) @Suppress("UNCHECKED_CAST") override val parameterTypes: List? 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 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 diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKPackageSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKPackageSymbol.kt index e9942f14919..35bf6f946d8 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKPackageSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKPackageSymbol.kt @@ -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 \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKSymbol.kt index 37705ce5e02..d854597a850 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKSymbol.kt @@ -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 : JKSymbol { - val symbolProvider: JKSymbolProvider override var target: T override val fqName: String get() { @@ -47,8 +52,6 @@ interface JKUniverseSymbol : JKSymbol { } interface JKMultiverseSymbol : JKSymbol where T : PsiNamedElement, T : PsiElement { - val symbolProvider: JKSymbolProvider - override val target: T override val declaredIn: JKSymbol? get() = target.getStrictParentOfType()?.let { symbolProvider.provideDirectSymbol(it) } @@ -59,8 +62,6 @@ interface JKMultiverseSymbol : JKSymbol where T : PsiNamedElement, T : PsiEle } interface JKMultiverseKtSymbol : JKSymbol { - val symbolProvider: JKSymbolProvider - override val target: T override val name: String get() = target.name!! diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKTypeParameterSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKTypeParameterSymbol.kt index 29c21907a35..28bc286bbb0 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKTypeParameterSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKTypeParameterSymbol.kt @@ -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 { override val index: Int get() = target.index } class JKUniverseTypeParameterSymbol( - override val symbolProvider: JKSymbolProvider + override val typeFactory: JKTypeFactory ) : JKTypeParameterSymbol(), JKUniverseSymbol { override val index: Int get() = declaredIn?.safeAs()?.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 { override val index: Int get() = target.getParentOfType(strict = false)?.typeParameters?.indexOf(target) ?: -1 diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaAndKotlinElements.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaAndKotlinElements.kt index 64d28687add..a5cea6eaa8b 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaAndKotlinElements.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaAndKotlinElements.kt @@ -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 = emptyList()) : JKTypeArgumentList, JKBranchElementBase(), PsiOwner by PsiOwnerImpl() { - override val typeArguments: List by children(typeArguments) + override var typeArguments: List by children(typeArguments) override fun accept(visitor: JKVisitor) = visitor.visitTypeArgumentList(this) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaElements.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaElements.kt index f1320fd67b5..3e3d9ed3549 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaElements.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/javaElements.kt @@ -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( diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/javaElements.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/javaElements.kt index 1779f351bfa..ab5f15456ed 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/javaElements.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/javaElements.kt @@ -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 } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/typesUtils.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/typesUtils.kt index f0e4c99001d..f7a20c67494 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/typesUtils.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/typesUtils.kt @@ -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()?.expression?.type(symbolProvider) + statement.safeAs()?.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()?.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 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 = diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt new file mode 100644 index 00000000000..41ad9fc1e44 --- /dev/null +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt @@ -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 = 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 + ) + } + } +} \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/types.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/types.kt similarity index 94% rename from nj2k/src/org/jetbrains/kotlin/nj2k/tree/types.kt rename to nj2k/src/org/jetbrains/kotlin/nj2k/types/types.kt index fc8a3b3d0eb..870b4a81c87 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/types.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/types.kt @@ -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