diff --git a/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/J2KUtils.kt b/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/J2KUtils.kt index 061397f13b6..7da7e0c3370 100644 --- a/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/J2KUtils.kt +++ b/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/J2KUtils.kt @@ -9,6 +9,7 @@ import com.intellij.lang.java.JavaLanguage import com.intellij.psi.PsiElement import com.intellij.psi.PsiExpression import com.intellij.psi.PsiMember +import org.jetbrains.kotlin.idea.util.module import org.jetbrains.kotlin.j2k.ConverterSettings import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtNamedDeclaration @@ -23,6 +24,7 @@ fun PsiElement.convertToKotlin(): org.jetbrains.kotlin.j2k.Result? { val j2kConverter = JavaToKotlinConverterFactory.createJavaToKotlinConverter( project, + module, ConverterSettings.defaultSettings, IdeaJavaToKotlinServices ) diff --git a/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/JavaToKotlinConverterFactory.kt b/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/JavaToKotlinConverterFactory.kt index 244d7a3cfb7..66a2d919d67 100644 --- a/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/JavaToKotlinConverterFactory.kt +++ b/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/JavaToKotlinConverterFactory.kt @@ -14,10 +14,11 @@ import org.jetbrains.kotlin.j2k.* object JavaToKotlinConverterFactory { fun createJavaToKotlinConverter( project: Project, + targetModule: Module?, settings: ConverterSettings, services: JavaToKotlinConverterServices ): JavaToKotlinConverter = - J2kConverterExtension.extension.createJavaToKotlinConverter(project, settings, services) + J2kConverterExtension.extension.createJavaToKotlinConverter(project, targetModule, settings, services) fun createPostProcessor(formatCode: Boolean): PostProcessor = J2kConverterExtension.extension.createPostProcessor(formatCode) diff --git a/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/OldJ2kConverterExtension.kt b/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/OldJ2kConverterExtension.kt index 9ccbfb4213a..b6fcf082e96 100644 --- a/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/OldJ2kConverterExtension.kt +++ b/idea/idea-j2k/src/org/jetbrains/kotlin/idea/j2k/OldJ2kConverterExtension.kt @@ -1,5 +1,6 @@ package org.jetbrains.kotlin.idea.j2k +import com.intellij.openapi.module.Module import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.project.Project import com.intellij.psi.PsiJavaFile @@ -10,6 +11,7 @@ class OldJ2kConverterExtension : J2kConverterExtension() { override fun createJavaToKotlinConverter( project: Project, + targetModule: Module?, settings: ConverterSettings, services: JavaToKotlinConverterServices ): JavaToKotlinConverter = diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt index a0095f61cdb..e69dc77260c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt +++ b/idea/src/org/jetbrains/kotlin/idea/actions/JavaToKotlinAction.kt @@ -21,10 +21,14 @@ import com.intellij.ide.highlighter.ArchiveFileType import com.intellij.ide.highlighter.JavaFileType import com.intellij.ide.scratch.ScratchFileService import com.intellij.ide.scratch.ScratchRootType -import com.intellij.openapi.actionSystem.* +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.actionSystem.LangDataKeys import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.fileEditor.FileDocumentManager import com.intellij.openapi.fileEditor.FileEditorManager +import com.intellij.openapi.module.Module import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.openapi.ui.MessageType @@ -103,7 +107,9 @@ class JavaToKotlinAction : AnAction() { } fun convertFiles( - javaFiles: List, project: Project, + javaFiles: List, + project: Project, + module: Module, enableExternalCodeProcessing: Boolean = true, askExternalCodeProcessing: Boolean = true ): List { @@ -112,6 +118,7 @@ class JavaToKotlinAction : AnAction() { val converter = JavaToKotlinConverterFactory.createJavaToKotlinConverter( project, + module, ConverterSettings.defaultSettings, IdeaJavaToKotlinServices ) @@ -217,7 +224,7 @@ class JavaToKotlinAction : AnAction() { } } - convertFiles(javaFiles, project) + convertFiles(javaFiles, project, module) } override fun update(e: AnActionEvent) { diff --git a/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPasteProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPasteProcessor.kt index e6a79531e56..30266e6dbf5 100644 --- a/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPasteProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/conversion/copy/ConvertJavaCopyPasteProcessor.kt @@ -21,6 +21,7 @@ import com.intellij.codeInsight.editorActions.TextBlockTransferableData import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.RangeMarker +import com.intellij.openapi.module.Module import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.Project @@ -41,6 +42,7 @@ import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory import org.jetbrains.kotlin.idea.util.ImportInsertHelper import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.idea.util.module import org.jetbrains.kotlin.j2k.AfterConversionPass import org.jetbrains.kotlin.j2k.ConverterContext import org.jetbrains.kotlin.j2k.ConverterSettings @@ -85,6 +87,7 @@ class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor? get() = getLabel()?.let { label -> - converterContext.elementsInfoStorage.getInfoForLabel(label) + converterContext?.elementsInfoStorage?.getInfoForLabel(label) } private inline val KtExpression.boundType diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/context.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/context.kt index efd0fd66c10..fb56b32bb0e 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/context.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/context.kt @@ -21,10 +21,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.addToStdlib.safeAs -internal class ContextCreator( - private val conversionContext: NewJ2kConverterContext, - private val getNullability: (KtTypeElement, NewJ2kConverterContext) -> Nullability -) { +internal class ContextCreator(private val getNullability: (KtTypeElement) -> Nullability) { private fun KtCallableDeclaration.typeElement(): KtTypeElement? = typeReference?.typeElement @@ -80,7 +77,7 @@ internal class ContextCreator( } private fun KtTypeElement.asTypeVariable(): TypeVariable { - val nullability = getNullability(this, conversionContext) + val nullability = getNullability(this) val classReference: ClassReference = classReference() val typeParameters: List = typeArgumentsAsTypes.mapIndexed { index, typeRef -> @@ -142,7 +139,7 @@ fun prepareTypeElementByMakingAllTypesNullableConsideringNullabilityComment(type } } -fun prepareTypeElementByMakingAllTypesNullable(typeElement: KtTypeElement, conversionContext: NewJ2kConverterContext) { +fun prepareTypeElementByMakingAllTypesNullable(typeElement: KtTypeElement) { typeElement.changeNullability(toNullable = true) } diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/nullabilityAnalysis.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/nullabilityAnalysis.kt index 5b0643fdf21..a6516a04304 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/nullabilityAnalysis.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/nullabilityAnalysis/nullabilityAnalysis.kt @@ -76,16 +76,16 @@ internal fun KtTypeElement.classReference(): ClassReference { } class NullabilityAnalysisFacade( - private val conversionContext: NewJ2kConverterContext, - private val getTypeElementNullability: (KtTypeElement, NewJ2kConverterContext) -> Nullability, - private val prepareTypeElement: (KtTypeElement, NewJ2kConverterContext) -> Unit, + private val conversionContext: NewJ2kConverterContext?, + private val getTypeElementNullability: (KtTypeElement) -> Nullability, + private val prepareTypeElement: (KtTypeElement) -> Unit, private val debugPrint: Boolean ) { fun fixNullability(analysisScope: AnalysisScope) { CommandProcessor.getInstance().runUndoTransparentAction { runWriteAction { - analysisScope.prepareTypeElements(prepareTypeElement, conversionContext) - val context = ContextCreator(conversionContext, getTypeElementNullability).createContext(analysisScope) + analysisScope.prepareTypeElements(prepareTypeElement) + val context = ContextCreator(getTypeElementNullability).createContext(analysisScope) if (debugPrint) { with(Printer(context)) { analysisScope.forEach { it.addTypeVariablesNames() } @@ -101,15 +101,12 @@ class NullabilityAnalysisFacade( } } -private fun AnalysisScope.prepareTypeElements( - prepareTypeElement: (KtTypeElement, NewJ2kConverterContext) -> Unit, - conversionContext: NewJ2kConverterContext -) { +private fun AnalysisScope.prepareTypeElements(prepareTypeElement: (KtTypeElement) -> Unit) { val typeElements = flatMap { it.collectDescendantsOfType() } typeElements.forEach { typeReference -> val typeElement = typeReference.typeElement ?: return@forEach if (typeElement.parentOfType() == null) { - prepareTypeElement(typeElement, conversionContext) + prepareTypeElement(typeElement) } } } diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/processings.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/processings.kt index c098cbdc26f..c24fdceb09e 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/processings.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/processings.kt @@ -38,8 +38,8 @@ val nullabilityProcessing = postProcessing("Inferring declarations nullability") { file, rangeMarker, converterContext -> NullabilityAnalysisFacade( converterContext, - getTypeElementNullability = ::nullabilityByUndefinedNullabilityComment, - prepareTypeElement = ::prepareTypeElementByMakingAllTypesNullableConsideringNullabilityComment, + getTypeElementNullability = { nullabilityByUndefinedNullabilityComment(it, converterContext) }, + prepareTypeElement = { prepareTypeElementByMakingAllTypesNullableConsideringNullabilityComment(it, converterContext) }, debugPrint = false ).fixNullability(AnalysisScope(file, rangeMarker)) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt index 611731d280b..cf07c6f8dc0 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JKSymbolProvider.kt @@ -5,23 +5,22 @@ package org.jetbrains.kotlin.nj2k +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project import com.intellij.psi.* import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.FqNameUnsafe -import org.jetbrains.kotlin.nj2k.conversions.multiResolveFqName -import org.jetbrains.kotlin.nj2k.conversions.resolveFqName +import org.jetbrains.kotlin.nj2k.conversions.JKResolver import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.tree.impl.* import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.utils.addToStdlib.safeAs -class JKSymbolProvider { - val symbolsByFqName = mutableMapOf() +class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElement) { + private val symbolsByFqName = mutableMapOf() val symbolsByPsi = mutableMapOf() val symbolsByJK = mutableMapOf() + private val resolver = JKResolver(project, module, contextElement) private val elementVisitor = ElementVisitor() @@ -102,50 +101,36 @@ class JKSymbolProvider { JKUniverseMethodSymbol(this).also { it.target = jk } } as JKMethodSymbol - internal inline fun provideByFqName( - classId: ClassId, - multiResolve: Boolean = false, - context: PsiElement = symbolsByPsi.keys.first() - ): T { - val fqName = classId.asSingleFqName().asString().replace('/', '.') - if (fqName in symbolsByFqName) { - return symbolsByFqName[fqName] as T - } - val resolved = - if (multiResolve) multiResolveFqName(classId, context).firstOrNull() - else resolveFqName(classId, context) - val symbol = resolved?.let(::provideDirectSymbol).safeAs() - return symbol ?: when { - isAssignable() -> JKUnresolvedMethod(fqName) - isAssignable() -> JKUnresolvedField(fqName, this) - else -> JKUnresolvedClassSymbol(fqName) - } as T - } - @Deprecated("", ReplaceWith("provideByFqName(fqName, true, context)")) - internal inline fun provideByFqNameMulti(fqName: String, context: PsiElement = symbolsByPsi.keys.first()): T = - provideByFqName(ClassId.fromString(fqName), true, context) + fun provideClassSymbol(fqName: FqName): JKClassSymbol = + symbolsByFqName.getOrPutIfNotNull(fqName.asString()) { + resolver.resolveClass(fqName)?.let { + provideDirectSymbol(it) as? JKClassSymbol + } + } as? JKClassSymbol ?: JKUnresolvedClassSymbol(fqName.asString()) - internal inline fun provideByFqName( - fqName: String, - multiResolve: Boolean = false, - context: PsiElement = symbolsByPsi.keys.first() - ): T = - provideByFqName(ClassId.fromString(fqName), multiResolve, context) + fun provideClassSymbol(fqName: String): JKClassSymbol = + provideClassSymbol(FqName(fqName.asSafeFqNameString())) - internal inline fun provideByFqName( - fqName: FqName, - multiResolve: Boolean = false, - context: PsiElement = symbolsByPsi.keys.first() - ): T = - provideByFqName(fqName.asString(), multiResolve, context) + fun provideMethodSymbol(fqName: FqName): JKMethodSymbol = + symbolsByFqName.getOrPutIfNotNull(fqName.asString()) { + resolver.resolveMethod(fqName)?.let { + provideDirectSymbol(it) as? JKMethodSymbol + } + } as? JKMethodSymbol ?: JKUnresolvedMethod(fqName.asString()) - internal inline fun provideByFqName( - fqName: FqNameUnsafe, - multiResolve: Boolean = false, - context: PsiElement = symbolsByPsi.keys.first() - ): T = - provideByFqName(fqName.asString(), multiResolve, context) + fun provideMethodSymbol(fqName: String): JKMethodSymbol = + provideMethodSymbol(FqName(fqName.asSafeFqNameString())) + + fun provideFieldSymbol(fqName: FqName): JKFieldSymbol = + symbolsByFqName.getOrPutIfNotNull(fqName.asString()) { + resolver.resolveField(fqName)?.let { + provideDirectSymbol(it) as? JKFieldSymbol + } + } as? JKFieldSymbol ?: JKUnresolvedField(fqName.asString(), this) + + fun provideFieldSymbol(fqName: String): JKFieldSymbol = + provideFieldSymbol(FqName(fqName.asSafeFqNameString())) private inner class ElementVisitor : JavaElementVisitor() { @@ -182,4 +167,18 @@ class JKSymbolProvider { } internal inline fun isAssignable(): Boolean = A::class.java.isAssignableFrom(B::class.java) -} \ No newline at end of file +} + +private inline fun MutableMap.getOrPutIfNotNull(key: K, defaultValue: () -> V?): V? { + val value = get(key) + return if (value == null) { + val answer = defaultValue() ?: return null + put(key, answer) + answer + } else { + value + } +} + +private fun String.asSafeFqNameString() = + replace('/', '.') \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt index 329b6b58fec..ece290caebd 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.nj2k -import com.intellij.codeInsight.daemon.impl.quickfix.AddTypeArgumentsFix import com.intellij.lang.jvm.JvmAnnotatedElement import com.intellij.lang.jvm.JvmModifier import com.intellij.psi.* @@ -673,7 +672,7 @@ class JavaToJKTreeBuilder constructor( fun PsiDocComment.deprecatedAnnotation(): JKAnnotation? = findTagByName("deprecated")?.let { tag -> JKAnnotationImpl( - symbolProvider.provideByFqName("kotlin.Deprecated"), + symbolProvider.provideClassSymbol("kotlin.Deprecated"), listOf( JKAnnotationParameterImpl(stringLiteral(tag.content(), symbolProvider)) ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt index 220eeb89c23..4cf2d6fe939 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJ2kConverterContext.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.nj2k -import com.intellij.openapi.command.impl.DummyProject import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import org.jetbrains.kotlin.j2k.* @@ -28,21 +27,5 @@ data class NewJ2kConverterContext( override fun inConversionScope(element: PsiElement): Boolean = inConversionContext(element) }) - - companion object { - val DUMMY = - NewJ2kConverterContext( - JKSymbolProvider(), - NewJavaToKotlinConverter( - DummyProject.getInstance(), - ConverterSettings.defaultSettings, - EmptyJavaToKotlinServices - ), - { false }, - ImportStorage(), - JKElementInfoStorage() - ) - } - } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt index 5890abc5c9a..58790944765 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverter.kt @@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ModalityState import com.intellij.openapi.command.CommandProcessor import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.module.Module import com.intellij.openapi.progress.EmptyProgressIndicator import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProgressIndicator @@ -38,6 +39,7 @@ import org.jetbrains.kotlin.psi.KtPsiFactory class NewJavaToKotlinConverter( val project: Project, + private val targetModule: Module?, val settings: ConverterSettings, val oldConverterServices: JavaToKotlinConverterServices ) : JavaToKotlinConverter() { @@ -101,7 +103,9 @@ class NewJavaToKotlinConverter( val processor = processor as NewJ2kWithProgressProcessor val phaseDescription = "Converting Java code to Kotlin code" - val symbolProvider = JKSymbolProvider() + 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) symbolProvider.preBuildTree(inputElements) val importStorage = ImportStorage() val treeBuilder = JavaToJKTreeBuilder(symbolProvider, converterServices, importStorage) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt index 65d8b9316b0..54957028f7d 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayInitializerConversion.kt @@ -29,7 +29,7 @@ class ArrayInitializerConversion(private val context: NewJ2kConverterContext) : if (primitiveArrayType == null) JKTypeArgumentListImpl(listOf(element::type.detached())) else JKTypeArgumentListImpl() newElement = JKJavaMethodCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.$arrayConstructorName"), + context.symbolProvider.provideMethodSymbol("kotlin.$arrayConstructorName"), element.initializer.also { element.initializer = emptyList() }.toArgumentList(), typeArguments ) @@ -46,13 +46,13 @@ class ArrayInitializerConversion(private val context: NewJ2kConverterContext) : if (dimensions.size == 1) { return if (type !is JKJavaPrimitiveType) { JKJavaMethodCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin/arrayOfNulls"), + context.symbolProvider.provideMethodSymbol("kotlin.arrayOfNulls"), JKArgumentListImpl(dimensions[0]), JKTypeArgumentListImpl(listOf(JKTypeElementImpl(type))) ) } else { JKJavaNewExpressionImpl( - context.symbolProvider.provideByFqName(type.arrayFqName()), + context.symbolProvider.provideClassSymbol(type.arrayFqName()), JKArgumentListImpl(dimensions[0]), JKTypeArgumentListImpl(emptyList()) ) @@ -62,8 +62,8 @@ class ArrayInitializerConversion(private val context: NewJ2kConverterContext) : val arrayType = dimensions.drop(1).fold(type) { currentType, _ -> JKJavaArrayTypeImpl(currentType) } - return JKJavaMethodCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.Array"), + return JKJavaNewExpressionImpl( + context.symbolProvider.provideClassSymbol("kotlin.Array"), JKArgumentListImpl( dimensions[0], JKLambdaExpressionImpl( @@ -75,19 +75,19 @@ class ArrayInitializerConversion(private val context: NewJ2kConverterContext) : ) } var resultType = JKClassTypeImpl( - context.symbolProvider.provideByFqName(type.arrayFqName()), + context.symbolProvider.provideClassSymbol(type.arrayFqName()), if (type is JKJavaPrimitiveType) emptyList() else listOf(type), Nullability.Default ) for (i in 0 until dimensions.size - 2) { resultType = JKClassTypeImpl( - context.symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES.array.asString()), + context.symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.array.toSafe()), listOf(resultType), Nullability.Default ) } return JKJavaMethodCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin/arrayOfNulls"), + context.symbolProvider.provideMethodSymbol("kotlin.arrayOfNulls"), JKArgumentListImpl(dimensions[0]), JKTypeArgumentListImpl(listOf(JKTypeElementImpl(resultType))) ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt index 7bdb6182076..2af9aa840b2 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ArrayOperationsConversion.kt @@ -22,9 +22,9 @@ class ArrayOperationsConversion(private val context: NewJ2kConverterContext) : R if (element.receiver.type(context.symbolProvider) !is JKJavaArrayType) return recurse(element) if (selector.identifier.name == "length") { val sizeCall = - JKFieldAccessExpressionImpl( - context.symbolProvider.provideByFqName("kotlin/Array.size") - ) + JKFieldAccessExpressionImpl( + context.symbolProvider.provideFieldSymbol("kotlin.Array.size") + ) element.selector = sizeCall } return recurse(element) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssignmentAsExpressionToAlsoConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssignmentAsExpressionToAlsoConversion.kt index 3c0e3e3f0c8..a68abf50a62 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssignmentAsExpressionToAlsoConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AssignmentAsExpressionToAlsoConversion.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.nj2k.conversions import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext -import org.jetbrains.kotlin.nj2k.tree.* +import org.jetbrains.kotlin.nj2k.tree.JKBlockStatement +import org.jetbrains.kotlin.nj2k.tree.JKJavaAssignmentExpression +import org.jetbrains.kotlin.nj2k.tree.JKKtAssignmentStatement +import org.jetbrains.kotlin.nj2k.tree.JKTreeElement import org.jetbrains.kotlin.nj2k.tree.impl.* import org.jetbrains.kotlin.utils.addToStdlib.cast @@ -18,7 +21,7 @@ class AssignmentAsExpressionToAlsoConversion(val context: NewJ2kConverterContext val alsoExpression = JKKtAlsoCallExpressionImpl( JKBlockStatementImpl( JKBlockImpl(listOf(JKKtAssignmentStatementImpl(element.field, JKStubExpressionImpl(), element.operator))) - ), context.symbolProvider.provideByFqName("kotlin/also") + ), context.symbolProvider.provideMethodSymbol("kotlin.also") ).also { it.statement.cast().block.statements.first().cast().expression = JKFieldAccessExpressionImpl( diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BlockToRunConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BlockToRunConversion.kt index a85a8d3efe9..9d01171fc70 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BlockToRunConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BlockToRunConversion.kt @@ -23,7 +23,10 @@ class BlockToRunConversion(private val context: NewJ2kConverterContext) : Recurs JKBlockStatementImpl(element.block), emptyList() ) - val call = JKKtCallExpressionImpl(context.symbolProvider.provideByFqName("kotlin.run", true), JKArgumentListImpl(lambda)) + val call = JKKtCallExpressionImpl( + context.symbolProvider.provideMethodSymbol("kotlin.run"), + JKArgumentListImpl(lambda) + ) return recurse(JKExpressionStatementImpl(call).withNonCodeElementsFrom(element)) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BoxedTypeOperationsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BoxedTypeOperationsConversion.kt index b80317be887..987f21dc60a 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BoxedTypeOperationsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BoxedTypeOperationsConversion.kt @@ -39,7 +39,7 @@ class BoxedTypeOperationsConversion(private val context: NewJ2kConverterContext) val primitiveTypeName = boxedTypeToPrimitiveType[boxedJavaType] ?: return null if (operationType !in primitiveTypeNames) return null return JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName( + context.symbolProvider.provideMethodSymbol( "kotlin.${primitiveTypeName.capitalize()}.to${operationType.capitalize()}" ), JKArgumentListImpl() diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt index 1064ccdd34d..36d927add70 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/BuiltinMembersConversion.kt @@ -78,13 +78,13 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re when (from) { is JKMethodCallExpression -> JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName(fqName, true), + context.symbolProvider.provideMethodSymbol(fqName), argumentsProvider(from::arguments.detached()), from::typeArgumentList.detached() ).withNonCodeElementsFrom(from) is JKFieldAccessExpression -> JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName(fqName, true), + context.symbolProvider.provideMethodSymbol(fqName), JKArgumentListImpl(), JKTypeArgumentListImpl() ).withNonCodeElementsFrom(from) @@ -99,11 +99,11 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re when (from) { is JKMethodCallExpression -> JKFieldAccessExpressionImpl( - context.symbolProvider.provideByFqName(fqName, true) + context.symbolProvider.provideFieldSymbol(fqName) ).withNonCodeElementsFrom(from) is JKFieldAccessExpression -> JKFieldAccessExpressionImpl( - context.symbolProvider.provideByFqName(fqName, true) + context.symbolProvider.provideFieldSymbol(fqName) ).withNonCodeElementsFrom(from) else -> error("Bad conversion") } @@ -120,7 +120,7 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re arguments.first()::value.detached().parenthesizeIfBinaryExpression(), JKKtQualifierImpl.DOT, JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName(fqName, true), + context.symbolProvider.provideMethodSymbol(fqName), JKArgumentListImpl(arguments.drop(1)), from::typeArgumentList.detached() ) @@ -240,7 +240,7 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re withArgumentsProvider { arguments -> val argument = arguments.arguments.single()::value.detached() val call = JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.text.charset"), + context.symbolProvider.provideMethodSymbol("kotlin.text.charset"), JKArgumentListImpl(argument) ) JKArgumentListImpl(call) @@ -278,10 +278,7 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re val detachedArguments = arguments::arguments.detached() val first = detachedArguments.first()::value.detached().callOn( - context.symbolProvider.provideByFqName( - "kotlin.text.toRegex", - multiResolve = true - ) + context.symbolProvider.provideMethodSymbol("kotlin.text.toRegex") ) JKArgumentListImpl(listOf(JKArgumentImpl(first)) + detachedArguments.drop(1)) }, @@ -291,10 +288,8 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re val detachedArguments = arguments::arguments.detached() val first = detachedArguments.first()::value.detached().callOn( - context.symbolProvider.provideByFqName( - "kotlin.text.toRegex", - multiResolve = true - ) + context.symbolProvider.provideMethodSymbol("kotlin.text.toRegex") + ) JKArgumentListImpl(listOf(JKArgumentImpl(first)) + detachedArguments.drop(1)) }, @@ -366,19 +361,15 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re arguments.arguments = arguments.arguments.dropLast(1) }.let { it.callOn( - context.symbolProvider.provideByFqName("kotlin.collections.dropLastWhile", multiResolve = true), + context.symbolProvider.provideMethodSymbol("kotlin.collections.dropLastWhile"), JKLambdaExpressionImpl( JKFieldAccessExpressionImpl( JKUnresolvedField(//TODO replace with `it` parameter "it", context.symbolProvider ) - ).callOn( - context.symbolProvider.provideByFqName( - "kotlin.text.isEmpty", - multiResolve = true - ) - ).asStatement(), + ).callOn(context.symbolProvider.provideMethodSymbol("kotlin.text.isEmpty")) + .asStatement(), emptyList() ) ) @@ -387,7 +378,7 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re else -> expression.also { val lastArgument = arguments.arguments.last().value.copyTreeAndDetach() .callOn( - context.symbolProvider.provideByFqName("kotlin.ranges.coerceAtLeast"), + context.symbolProvider.provideMethodSymbol("kotlin.ranges.coerceAtLeast"), JKKtLiteralExpressionImpl("0", JKLiteralExpression.LiteralType.INT) ) arguments.arguments = arguments.arguments.dropLast(1) + JKArgumentImpl(lastArgument) @@ -469,5 +460,5 @@ class BuiltinMembersConversion(private val context: NewJ2kConverterContext) : Re private fun JKExpression.castToTypedArray() = - callOn(context.symbolProvider.provideByFqName("kotlin.collections.toTypedArray", multiResolve = true)) + callOn(context.symbolProvider.provideMethodSymbol("kotlin.collections.toTypedArray")) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt index 483c1b10b6d..0c33cce9098 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt @@ -237,10 +237,7 @@ class ForConversion(private val context: NewJ2kConverterContext) : RecursiveAppl indices, JKKtQualifierImpl.DOT, JKJavaMethodCallExpressionImpl( - context.symbolProvider.provideByFqName( - "kotlin/collections/reversed", - multiResolve = true - ), + context.symbolProvider.provideMethodSymbol("kotlin.collections.reversed"), JKArgumentListImpl() ) ) @@ -267,10 +264,7 @@ class ForConversion(private val context: NewJ2kConverterContext) : RecursiveAppl private fun toIndicesCall(javaSizeCall: JKQualifiedExpression): JKQualifiedExpression? { if (javaSizeCall.psi == null) return null val selector = JKFieldAccessExpressionImpl( - context.symbolProvider.provideByFqName( - "kotlin/collections/indices", - multiResolve = true - ) + context.symbolProvider.provideFieldSymbol("kotlin.collections.indices") ) return JKQualifiedExpressionImpl(javaSizeCall::receiver.detached(), javaSizeCall.operator, selector) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt index 1ffd359e1a9..6469752b845 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt @@ -5,7 +5,10 @@ package org.jetbrains.kotlin.nj2k.conversions -import org.jetbrains.kotlin.nj2k.* +import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext +import org.jetbrains.kotlin.nj2k.copyTreeAndDetach +import org.jetbrains.kotlin.nj2k.isEquals +import org.jetbrains.kotlin.nj2k.parenthesizeIfBinaryExpression import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.tree.impl.* import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType @@ -100,7 +103,7 @@ class ImplicitCastsConversion(private val context: NewJ2kConverterContext) : Rec copyTreeAndDetach().parenthesizeIfBinaryExpression(), JKKtQualifierImpl.DOT, JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.text.toRegex", multiResolve = true), + context.symbolProvider.provideMethodSymbol("kotlin.text.toRegex"), JKArgumentListImpl(), JKTypeArgumentListImpl() ) @@ -142,7 +145,7 @@ class ImplicitCastsConversion(private val context: NewJ2kConverterContext) : Rec this.copyTreeAndDetach(), JKKtQualifierImpl.DOT, JKJavaMethodCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.$initialTypeName.$conversionFunctionName"), + context.symbolProvider.provideMethodSymbol("kotlin.$initialTypeName.$conversionFunctionName"), JKArgumentListImpl() ) ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaAnnotationsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaAnnotationsConversion.kt index 692b26b1277..96adcffb297 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaAnnotationsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/JavaAnnotationsConversion.kt @@ -29,14 +29,14 @@ class JavaAnnotationsConversion(private val context: NewJ2kConverterContext) : R private fun processAnnotation(annotation: JKAnnotation) { if (annotation.classSymbol.fqName == "java.lang.Deprecated") { - annotation.classSymbol = context.symbolProvider.provideByFqName("kotlin.Deprecated") + annotation.classSymbol = context.symbolProvider.provideClassSymbol("kotlin.Deprecated") if (annotation.arguments.isEmpty()) { annotation.arguments += JKAnnotationParameterImpl(JKKtLiteralExpressionImpl("\"\"", JKLiteralExpression.LiteralType.STRING)) } } if (annotation.classSymbol.fqName == "java.lang.annotation.Target") { - annotation.classSymbol = context.symbolProvider.provideByFqName("kotlin.annotation.Target") + annotation.classSymbol = context.symbolProvider.provideClassSymbol("kotlin.annotation.Target") val arguments = annotation.arguments.singleOrNull()?.let { parameter -> val value = parameter.value @@ -51,7 +51,7 @@ class JavaAnnotationsConversion(private val context: NewJ2kConverterContext) : R value.fieldAccessFqName() ?.let { targetMappings[it] } ?.map { fqName -> - JKFieldAccessExpressionImpl(context.symbolProvider.provideByFqName(fqName)) + JKFieldAccessExpressionImpl(context.symbolProvider.provideFieldSymbol(fqName)) } ?: listOf(value.copyTreeAndDetach()) } annotation.arguments = newArguments.map { JKAnnotationParameterImpl(it) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt index 2559917d77c..d3f3c897455 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MainFunctionConversion.kt @@ -5,10 +5,12 @@ package org.jetbrains.kotlin.nj2k.conversions -import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext import org.jetbrains.kotlin.j2k.ast.Nullability +import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext import org.jetbrains.kotlin.nj2k.tree.* -import org.jetbrains.kotlin.nj2k.tree.impl.* +import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationImpl +import org.jetbrains.kotlin.nj2k.tree.impl.JKJavaArrayTypeImpl +import org.jetbrains.kotlin.nj2k.tree.impl.JKTypeElementImpl //TODO temporary @@ -28,7 +30,7 @@ class MainFunctionConversion(private val context: NewJ2kConverterContext) : Recu } element.annotationList.annotations += JKAnnotationImpl( - context.symbolProvider.provideByFqName("kotlin.jvm.JvmStatic"), + context.symbolProvider.provideClassSymbol("kotlin.jvm.JvmStatic"), emptyList() ) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt index e6d7aa27a92..519c961d7b3 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt @@ -49,7 +49,7 @@ class OperatorExpressionConversion(private val context: NewJ2kConverterContext) if (javaOperator.token.psiToken == JavaTokenType.TILDE) { val invCall = JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.Int.inv"),//TODO check if Long + context.symbolProvider.provideMethodSymbol("kotlin.Int.inv"),//TODO check if Long JKArgumentListImpl() ) JKQualifiedExpressionImpl( @@ -72,7 +72,7 @@ class OperatorExpressionConversion(private val context: NewJ2kConverterContext) ) { val toStringCall = JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.Any.toString"), + context.symbolProvider.provideMethodSymbol("kotlin.Any.toString"), JKArgumentListImpl() ) val qualifiedCall = JKQualifiedExpressionImpl(left, JKKtQualifierImpl.DOT, toStringCall) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt index 09986e73b84..5469a801e76 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ParameterModificationInMethodCallsConversion.kt @@ -21,7 +21,7 @@ class ParameterModificationInMethodCallsConversion(private val context: NewJ2kCo val parameterType = if (parameter.isVarArgs) { JKClassTypeImpl( - context.symbolProvider.provideByFqName(parameter.type.type.arrayFqName()), + context.symbolProvider.provideClassSymbol(parameter.type.type.arrayFqName()), if (parameter.type.type is JKJavaPrimitiveType) emptyList() else listOf( JKVarianceTypeParameterTypeImpl( diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SynchronizedStatementConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SynchronizedStatementConversion.kt index d0ea7bd0117..5449b9f77fb 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SynchronizedStatementConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SynchronizedStatementConversion.kt @@ -22,7 +22,7 @@ class SynchronizedStatementConversion(private val context: NewJ2kConverterContex ) val synchronizedCall = JKKtCallExpressionImpl( - context.symbolProvider.provideByFqName("kotlin.synchronized", true), + context.symbolProvider.provideMethodSymbol("kotlin.synchronized"), JKArgumentListImpl( element.lockExpression, lambdaBody diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt index bcece98da97..aa39ee99f5a 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/TypeMappingConversion.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.j2k.* import org.jetbrains.kotlin.j2k.ast.Mutability import org.jetbrains.kotlin.j2k.ast.Nullability -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext import org.jetbrains.kotlin.nj2k.kotlinTypeByName @@ -35,9 +34,7 @@ class TypeMappingConversion(val context: NewJ2kConverterContext) : RecursiveAppl override fun applyToElement(element: JKTreeElement): JKTreeElement { return when (element) { is JKTypeElement -> { - val newType = element.type - .fixRawType(element) - .mapType(element) + val newType = element.type.mapType(element) JKTypeElementImpl(newType).withNonCodeElementsFrom(element) } is JKJavaNewExpression -> { @@ -79,8 +76,8 @@ class TypeMappingConversion(val context: NewJ2kConverterContext) : RecursiveAppl } - private fun JKType.fixRawType(typeElement: JKTypeElement) = - when (typeElement.parent) { + private fun JKType.fixRawType(typeElement: JKTypeElement?) = + when (typeElement?.parent) { is JKClassLiteralExpression -> this is JKKtIsExpression -> addTypeParametersToRawProjectionType(JKStarProjectionTypeImpl()) @@ -105,7 +102,7 @@ class TypeMappingConversion(val context: NewJ2kConverterContext) : RecursiveAppl ) is JKJavaArrayType -> JKClassTypeImpl( - context.symbolProvider.provideByFqName(type.arrayFqName()), + context.symbolProvider.provideClassSymbol(type.arrayFqName()), if (type is JKJavaPrimitiveType) emptyList() else listOf(type.mapType(typeElement)), nullability ) @@ -115,14 +112,14 @@ class TypeMappingConversion(val context: NewJ2kConverterContext) : RecursiveAppl boundType.mapType(null) ) else -> this - } + }.fixRawType(typeElement) private fun JKClassSymbol.mapClassSymbol(typeElement: JKTypeElement?): JKClassSymbol { if (this is JKUniverseClassSymbol) return this val newFqName = typeElement?.let { kotlinCollectionClassName(it) } ?: kotlinStandardType() ?: fqName - return context.symbolProvider.provideByFqName(newFqName) + return context.symbolProvider.provideClassSymbol(newFqName) } private fun JKClassType.mapClassType(typeElement: JKTypeElement?): JKClassType = @@ -149,7 +146,7 @@ class TypeMappingConversion(val context: NewJ2kConverterContext) : RecursiveAppl private fun JKJavaPrimitiveType.mapPrimitiveType(): JKClassType { val fqName = jvmPrimitiveType.primitiveType.typeFqName return JKClassTypeImpl( - context.symbolProvider.provideByFqName(ClassId.topLevel(fqName)), + context.symbolProvider.provideClassSymbol(fqName), nullability = Nullability.NotNull ) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/resolveUtil.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/resolveUtil.kt index 2b7add8c47d..d15d62387a9 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/resolveUtil.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/resolveUtil.kt @@ -5,45 +5,105 @@ package org.jetbrains.kotlin.nj2k.conversions +import com.intellij.openapi.module.Module +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiPolyVariantReference -import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext -import org.jetbrains.kotlin.nj2k.tree.JKTreeElement -import org.jetbrains.kotlin.nj2k.tree.impl.psi -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -import org.jetbrains.kotlin.psi.KtImportDirective -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.analysisContext +import com.intellij.psi.impl.java.stubs.index.JavaFullClassNameIndex +import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex +import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex +import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelPropertyFqnNameIndex +import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelTypeAliasFqNameIndex +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getChildOfType import org.jetbrains.kotlin.resolve.ImportPath -internal fun resolveFqName(classId: ClassId, contextElement: JKTreeElement, context: NewJ2kConverterContext): PsiElement? { - val element = contextElement.psi ?: return null - return resolveFqName(classId, element) -} +class JKResolver(private val project: Project, module: Module, private val contextElement: PsiElement) { + private val scope = GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) -fun resolveFqName(classId: ClassId, element: PsiElement): PsiElement? { - return constructImportDirectiveWithContext(classId, element) - .getChildOfType() - ?.selectorExpression - ?.let { - it.references.mapNotNull { it.resolve() }.firstOrNull() + fun resolveDeclaration(fqName: FqName): PsiElement? = + resolveFqNameOfKtClassByIndex(fqName) + ?: resolveFqNameOfJavaClassByIndex(fqName) + ?: resolveFqNameOfKtFunctionByIndex(fqName) + ?: resolveFqNameOfKtPropertyByIndex(fqName) + ?: resolveFqName(fqName) + + fun resolveClass(fqName: FqName): PsiElement? = + resolveFqNameOfKtClassByIndex(fqName) + ?: resolveFqNameOfJavaClassByIndex(fqName) + ?: resolveFqName(fqName) + + fun resolveMethod(fqName: FqName): PsiElement? = + resolveFqNameOfKtFunctionByIndex(fqName) + ?: resolveFqName(fqName) + + fun resolveField(fqName: FqName): PsiElement? = + resolveFqNameOfKtPropertyByIndex(fqName) + ?: resolveFqName(fqName) + + private fun resolveFqNameOfKtClassByIndex(fqName: FqName): KtDeclaration? { + val fqNameString = fqName.asString() + val classesPsi = KotlinFullClassNameIndex.getInstance()[fqNameString, project, scope] + val typeAliasesPsi = KotlinTopLevelTypeAliasFqNameIndex.getInstance()[fqNameString, project, scope] + + return selectNearest(classesPsi, typeAliasesPsi) + } + + private fun resolveFqNameOfJavaClassByIndex(fqName: FqName): PsiClass? { + val fqNameString = fqName.asString() + return JavaFullClassNameIndex.getInstance()[fqNameString.hashCode(), project, scope] + .firstOrNull { + it.qualifiedName == fqNameString + } + } + + + private fun resolveFqNameOfKtFunctionByIndex(fqName: FqName): KtNamedFunction? = + KotlinTopLevelFunctionFqnNameIndex.getInstance()[fqName.asString(), project, scope].firstOrNull() + + private fun resolveFqNameOfKtPropertyByIndex(fqName: FqName): KtProperty? = + KotlinTopLevelPropertyFqnNameIndex.getInstance()[fqName.asString(), project, scope].firstOrNull() + + + private fun resolveFqName(fqName: FqName): PsiElement? = + constructImportDirectiveWithContext(fqName) + .getChildOfType() + ?.selectorExpression + ?.let { + it.references.mapNotNull { it.resolve() }.firstOrNull() + } + + + private fun constructImportDirectiveWithContext(fqName: FqName): KtImportDirective { + val importDirective = KtPsiFactory(contextElement).createImportDirective(ImportPath(fqName, false)) + importDirective.containingKtFile.analysisContext = contextElement.containingFile + return importDirective + } + + private fun selectNearest(classesPsi: Collection, typeAliasesPsi: Collection): KtDeclaration? = + when { + typeAliasesPsi.isEmpty() -> classesPsi.firstOrNull() + classesPsi.isEmpty() -> typeAliasesPsi.firstOrNull() + else -> (classesPsi.asSequence() + typeAliasesPsi.asSequence()).minWith(Comparator { o1, o2 -> + scope.compare(o1.containingFile.virtualFile, o2.containingFile.virtualFile) + }) } -} -private fun constructImportDirectiveWithContext(classId: ClassId, element: PsiElement): KtImportDirective { - val importDirective = KtPsiFactory(element).createImportDirective(ImportPath(classId.asSingleFqName(), false)) - importDirective.containingKtFile.analysisContext = element.containingFile - return importDirective + fun multiResolveFqName(fqName: FqName): List { + return constructImportDirectiveWithContext(fqName) + .getChildOfType() + ?.selectorExpression + ?.let { selector -> + selector.references.filterIsInstance() + .flatMap { polyVariantReference -> + polyVariantReference + .multiResolve(false) + .mapNotNull { it.element } + } + }.orEmpty() + } } - -internal fun multiResolveFqName(classId: ClassId, elementForContext: PsiElement): List { - return constructImportDirectiveWithContext(classId, elementForContext) - .getChildOfType() - ?.selectorExpression - ?.let { - it.references.filterIsInstance().flatMap { it.multiResolve(false).mapNotNull { it.element } } - }.orEmpty() -} \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt index 7fbad281cea..8427422560e 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.nj2k -import com.intellij.psi.PsiArrayType import com.intellij.psi.PsiClass import com.intellij.psi.tree.TokenSet import org.jetbrains.kotlin.builtins.KotlinBuiltIns @@ -22,7 +21,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs fun kotlinTypeByName(name: String, symbolProvider: JKSymbolProvider, nullability: Nullability = Nullability.Nullable): JKClassType = JKClassTypeImpl( - symbolProvider.provideByFqName(name), + symbolProvider.provideClassSymbol(name), emptyList(), nullability ) @@ -31,7 +30,7 @@ private fun JKType.classSymbol(symbolProvider: JKSymbolProvider) = when (this) { is JKClassType -> classReference is JKJavaPrimitiveType -> - symbolProvider.provideByFqName(jvmPrimitiveType.primitiveType.typeFqName.asString()) + symbolProvider.provideClassSymbol(jvmPrimitiveType.primitiveType.typeFqName) else -> null } @@ -54,7 +53,7 @@ private fun JKKtOperatorToken.arithmeticMethodType( val classSymbol = - if (leftType.isStringType()) symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES.string.toSafe()) + if (leftType.isStringType()) symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.string.toSafe()) else leftType.classSymbol(symbolProvider) return when (classSymbol) { @@ -83,7 +82,7 @@ private fun JKKtOperatorToken.unaryExpressionMethodType( return operandType!! } if (this == KtTokens.EXCL) { - return symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES._boolean).asType() + return symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES._boolean.toSafe()).asType() } if (this == KtTokens.MINUS || this == KtTokens.PLUS) { return operandType!! @@ -169,7 +168,7 @@ fun kotlinBinaryExpression( val returnType = when { token is JKKtSingleValueOperatorToken && token.psiToken in booleanOperators -> - JKClassTypeImpl(symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES._boolean)) + JKClassTypeImpl(symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES._boolean.toSafe())) else -> { val leftType = left.type(symbolProvider) val rightType = right.type(symbolProvider) @@ -178,7 +177,7 @@ fun kotlinBinaryExpression( token.arithmeticMethodType(l, r, symbolProvider) } } ?: token.defaultReturnType(leftType, rightType, symbolProvider) - ?: symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES.nothing).asType() + ?: symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.nothing.toSafe()).asType() } } return JKBinaryExpressionImpl(left, right, JKKtOperatorImpl(token, returnType)) @@ -261,7 +260,7 @@ fun rangeExpression( to, JKKtOperatorImpl( JKKtWordOperatorToken(operatorName), - conversionContext.symbolProvider.provideByFqName("kotlin.ranges.$operatorName").returnType!! + conversionContext.symbolProvider.provideMethodSymbol("kotlin.ranges.$operatorName").returnType!! ) ) @@ -278,7 +277,7 @@ fun useExpression( body: JKStatement, symbolProvider: JKSymbolProvider ): JKExpression { - val useSymbol = symbolProvider.provideByFqName("kotlin.io.use") + val useSymbol = symbolProvider.provideMethodSymbol("kotlin.io.use") val lambdaParameter = JKParameterImpl(JKTypeElementImpl(JKNoTypeImpl), variableIdentifier) @@ -305,12 +304,12 @@ fun kotlinAssert(assertion: JKExpression, message: JKExpression?, symbolProvider fun jvmAnnotation(name: String, symbolProvider: JKSymbolProvider) = JKAnnotationImpl( - symbolProvider.provideByFqName("kotlin.jvm.$name") + symbolProvider.provideClassSymbol("kotlin.jvm.$name") ) fun throwAnnotation(throws: List, symbolProvider: JKSymbolProvider) = JKAnnotationImpl( - symbolProvider.provideByFqName("kotlin.jvm.Throws"), + symbolProvider.provideClassSymbol("kotlin.jvm.Throws"), throws.map { JKAnnotationParameterImpl( JKClassLiteralExpressionImpl(JKTypeElementImpl(it), JKClassLiteralExpression.LiteralType.KOTLIN_CLASS) @@ -419,7 +418,7 @@ fun runExpression(body: JKStatement, symbolProvider: JKSymbolProvider): JKExpres emptyList() ) return JKKtCallExpressionImpl( - symbolProvider.provideByFqName("kotlin.run", true), + symbolProvider.provideMethodSymbol("kotlin.run"), (listOf(lambda)).toArgumentList() ) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/jk.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/jk.kt index 5614e8b6437..11647ad3ac5 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/jk.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/jk.kt @@ -248,7 +248,7 @@ class JKBooleanLiteral(val value: Boolean) : JKLiteralExpression, JKElementBase( fun JKLiteralExpression.LiteralType.toJkType(symbolProvider: JKSymbolProvider): JKType { fun defaultTypeByName(name: String) = JKClassTypeImpl( - symbolProvider.provideByFqName("kotlin.$name"), emptyList(), Nullability.NotNull + symbolProvider.provideClassSymbol("kotlin.$name"), emptyList(), Nullability.NotNull ) return when (this) { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/symbols.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/symbols.kt index e550542da12..40d10f2374a 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/symbols.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/impl/symbols.kt @@ -185,7 +185,7 @@ class JKMultiverseFunctionSymbol(override val target: KtFunction, private val sy type?.let { if (parameter.isVarArg) { JKClassTypeImpl( - symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES.array), + symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.array.toSafe()), listOf(it) ) } else it @@ -252,12 +252,13 @@ class JKUnresolvedField(override val target: String, private val symbolProvider: get() { val resolvedType = (target as? PsiReferenceExpressionImpl)?.type if (resolvedType != null) return resolvedType.toJK(symbolProvider) - return JKClassTypeImpl(symbolProvider.provideByFqName("kotlin.Nothing"), emptyList()) + return JKClassTypeImpl(symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.nothing.toSafe()), emptyList()) } override val declaredIn: JKSymbol get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates. override val fqName: String = target - override val name: String = target + override val name: String + get() = target.substringAfterLast('.') } class JKUnresolvedMethod( @@ -274,7 +275,7 @@ class JKUnresolvedMethod( override val parameterTypes: List get() = TODO(target) //To change initializer of created properties use File | Settings | File Templates. override val name: String - get() = target + get() = target.substringAfterLast('.') } class JKUnresolvedClassSymbol(override val target: String) : JKClassSymbol, JKUnresolvedSymbol { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/types.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/types.kt index bd334eb9f98..ef8580ecc07 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/types.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/types.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.psi.KtClass 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 @@ -57,10 +58,10 @@ fun JKExpression.type(symbolProvider: JKSymbolProvider): JKType? = is JKClassLiteralExpression -> { val symbol = when (literalType) { JKClassLiteralExpression.LiteralType.KOTLIN_CLASS -> - symbolProvider.provideByFqName("kotlin.reflect.KClass") + symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.kClass.toSafe()) JKClassLiteralExpression.LiteralType.JAVA_CLASS, JKClassLiteralExpression.LiteralType.JAVA_PRIMITIVE_CLASS, JKClassLiteralExpression.LiteralType.JAVA_VOID_TYPE -> - symbolProvider.provideByFqName("java.lang.Class") + symbolProvider.provideClassSymbol("java.lang.Class") } JKClassTypeImpl(symbol, listOf(classType.type), Nullability.NotNull) } @@ -76,7 +77,7 @@ fun ClassId.toKtClassType( symbolProvider: JKSymbolProvider, nullability: Nullability = Nullability.Default ): JKType = - JKClassTypeImpl(symbolProvider.provideByFqName(this), emptyList(), nullability) + JKClassTypeImpl(symbolProvider.provideClassSymbol(asSingleFqName()), emptyList(), nullability) fun PsiType.toJK(symbolProvider: JKSymbolProvider, nullability: Nullability = Nullability.Default): JKType { @@ -136,14 +137,14 @@ fun JKType.isSubtypeOf(other: JKType, symbolProvider: JKSymbolProvider): Boolean fun KotlinType.toJK(symbolProvider: JKSymbolProvider): JKClassTypeImpl = JKClassTypeImpl( - symbolProvider.provideByFqName(getJetTypeFqName(false)), + symbolProvider.provideClassSymbol(getJetTypeFqName(false)), arguments.map { it.type.toJK(symbolProvider) }, if (isNullable()) Nullability.Nullable else Nullability.NotNull ) fun KtTypeReference.toJK(symbolProvider: JKSymbolProvider): JKType? = - analyze() + analyze(BodyResolveMode.PARTIAL) .get(BindingContext.TYPE, this) ?.toJK(symbolProvider) @@ -247,7 +248,7 @@ fun JKJavaMethod.returnTypeNullability(context: NewJ2kConverterContext): Nullabi fun JKType.isCollectionType(symbolProvider: JKSymbolProvider): Boolean { if (this !is JKClassType) return false - val collectionType = JKClassTypeImpl(symbolProvider.provideByFqName("java.util.Collection"), emptyList()) + val collectionType = JKClassTypeImpl(symbolProvider.provideClassSymbol("java.util.Collection"), emptyList()) return this.isSubtypeOf(collectionType, symbolProvider) } @@ -382,7 +383,7 @@ fun JKType.replaceJavaClassWithKotlinClassType(symbolProvider: JKSymbolProvider) applyRecursive { type -> if (type is JKClassType && type.classReference.fqName == "java.lang.Class") { JKClassTypeImpl( - symbolProvider.provideByFqName(KotlinBuiltIns.FQ_NAMES.kClass), + symbolProvider.provideClassSymbol(KotlinBuiltIns.FQ_NAMES.kClass.toSafe()), type.parameters.map { it.replaceJavaClassWithKotlinClassType(symbolProvider) }, Nullability.NotNull ) diff --git a/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNewJavaToKotlinConverterSingleFileTest.kt b/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNewJavaToKotlinConverterSingleFileTest.kt index 2f88829a036..fb7e89c5413 100644 --- a/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNewJavaToKotlinConverterSingleFileTest.kt +++ b/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNewJavaToKotlinConverterSingleFileTest.kt @@ -50,7 +50,7 @@ abstract class AbstractNewJavaToKotlinConverterSingleFileTest : AbstractJavaToKo override fun fileToKotlin(text: String, settings: ConverterSettings, project: Project): String { val file = createJavaFile(text) - return NewJavaToKotlinConverter(project, settings, IdeaJavaToKotlinServices) + return NewJavaToKotlinConverter(project, module, settings, IdeaJavaToKotlinServices) .filesToKotlin(listOf(file), NewJ2kPostProcessor()).results.single() } diff --git a/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNullabilityAnalysisTest.kt b/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNullabilityAnalysisTest.kt index 56200bffa17..842065956e4 100644 --- a/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNullabilityAnalysisTest.kt +++ b/nj2k/tests/org/jetbrains/kotlin/nj2k/AbstractNullabilityAnalysisTest.kt @@ -23,8 +23,8 @@ abstract class AbstractNullabilityAnalysisTest : KotlinLightCodeInsightFixtureTe val text = FileUtil.loadFile(file, true) val ktFile = myFixture.configureByText("converterTestFile.kt", text) as KtFile NullabilityAnalysisFacade( - NewJ2kConverterContext.DUMMY, - getTypeElementNullability = { _, _ -> Nullability.UNKNOWN }, + conversionContext = null, + getTypeElementNullability = { Nullability.UNKNOWN }, prepareTypeElement = ::prepareTypeElementByMakingAllTypesNullable, debugPrint = false )