New J2K: use IDEA indexes for resolving
Related to #KT-31848
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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<PsiJavaFile>, project: Project,
|
||||
javaFiles: List<PsiJavaFile>,
|
||||
project: Project,
|
||||
module: Module,
|
||||
enableExternalCodeProcessing: Boolean = true,
|
||||
askExternalCodeProcessing: Boolean = true
|
||||
): List<KtFile> {
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<TextBlockTransferab
|
||||
|
||||
val document = editor.document
|
||||
val targetFile = PsiDocumentManager.getInstance(project).getPsiFile(document) as? KtFile ?: return
|
||||
val targetModule = targetFile.module
|
||||
|
||||
if (isNoConversionPosition(targetFile, bounds.startOffset)) return
|
||||
|
||||
@@ -97,7 +100,7 @@ class ConvertJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransferab
|
||||
|
||||
fun doConversion(): Result {
|
||||
val dataForConversion = DataForConversion.prepare(data, project)
|
||||
val result = dataForConversion.elementsAndTexts.convertCodeToKotlin(project)
|
||||
val result = dataForConversion.elementsAndTexts.convertCodeToKotlin(project, targetModule)
|
||||
val referenceData = buildReferenceData(result.text, result.parseContext, dataForConversion.importsAndPackage, targetFile)
|
||||
val text = if (result.textChanged) result.text else null
|
||||
return Result(text, referenceData, result.importsToAdd, result.converterContext)
|
||||
@@ -214,10 +217,11 @@ internal class ConversionResult(
|
||||
val converterContext: ConverterContext?
|
||||
)
|
||||
|
||||
internal fun ElementAndTextList.convertCodeToKotlin(project: Project): ConversionResult {
|
||||
internal fun ElementAndTextList.convertCodeToKotlin(project: Project, targetModule: Module?): ConversionResult {
|
||||
val converter =
|
||||
JavaToKotlinConverterFactory.createJavaToKotlinConverter(
|
||||
project,
|
||||
targetModule,
|
||||
ConverterSettings.defaultSettings,
|
||||
IdeaJavaToKotlinServices
|
||||
)
|
||||
|
||||
+7
-4
@@ -23,6 +23,7 @@ import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Ref
|
||||
@@ -37,6 +38,7 @@ import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.editor.KotlinEditorOptions
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
@@ -94,6 +96,7 @@ class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransf
|
||||
val psiDocumentManager = PsiDocumentManager.getInstance(project)
|
||||
psiDocumentManager.commitDocument(editor.document)
|
||||
val targetFile = psiDocumentManager.getPsiFile(editor.document) as? KtFile ?: return
|
||||
val targetModule = targetFile.module
|
||||
|
||||
val pasteTarget = detectPasteTarget(targetFile, bounds.startOffset, bounds.endOffset) ?: return
|
||||
|
||||
@@ -105,9 +108,9 @@ class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransf
|
||||
val dataForConversion = DataForConversion.prepare(copiedJavaCode, project)
|
||||
|
||||
val additionalImports = dataForConversion.tryResolveImports(targetFile)
|
||||
var convertedImportsText = additionalImports.convertCodeToKotlin(project).text
|
||||
var convertedImportsText = additionalImports.convertCodeToKotlin(project, targetModule).text
|
||||
|
||||
val convertedResult = dataForConversion.convertCodeToKotlin(project)
|
||||
val convertedResult = dataForConversion.convertCodeToKotlin(project, targetModule)
|
||||
val convertedText = convertedResult.text
|
||||
|
||||
val newBounds = runWriteAction {
|
||||
@@ -133,8 +136,8 @@ class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransf
|
||||
conversionPerformed = true
|
||||
}
|
||||
|
||||
private fun DataForConversion.convertCodeToKotlin(project: Project): ConversionResult {
|
||||
return elementsAndTexts.convertCodeToKotlin(project)
|
||||
private fun DataForConversion.convertCodeToKotlin(project: Project, targetModule: Module?): ConversionResult {
|
||||
return elementsAndTexts.convertCodeToKotlin(project, targetModule)
|
||||
}
|
||||
|
||||
private val KtElement.pasteContext: KotlinContext
|
||||
|
||||
@@ -188,7 +188,7 @@ class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtNamedDeclaration
|
||||
getDocument(generatedFile)?.let { doPostponedOperationsAndUnblockDocument(it) }
|
||||
}
|
||||
|
||||
JavaToKotlinAction.convertFiles(listOf(generatedFile), project, false).singleOrNull()
|
||||
JavaToKotlinAction.convertFiles(listOf(generatedFile), project, srcModule, false).singleOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ abstract class J2kConverterExtension : AbstractExtensionPointBean() {
|
||||
|
||||
abstract fun createJavaToKotlinConverter(
|
||||
project: Project,
|
||||
targetModule: Module?,
|
||||
settings: ConverterSettings,
|
||||
services: JavaToKotlinConverterServices
|
||||
): JavaToKotlinConverter
|
||||
|
||||
@@ -18,10 +18,11 @@ class NewJ2kConverterExtension : J2kConverterExtension() {
|
||||
|
||||
override fun createJavaToKotlinConverter(
|
||||
project: Project,
|
||||
targetModule: Module?,
|
||||
settings: ConverterSettings,
|
||||
services: JavaToKotlinConverterServices
|
||||
): JavaToKotlinConverter =
|
||||
NewJavaToKotlinConverter(project, settings, services)
|
||||
NewJavaToKotlinConverter(project, targetModule, settings, services)
|
||||
|
||||
override fun createPostProcessor(formatCode: Boolean): PostProcessor =
|
||||
NewJ2kPostProcessor()
|
||||
|
||||
+2
-2
@@ -42,7 +42,7 @@ internal class LabelToFunctionTypeVariableMapper(analysisContext: AnalysisContex
|
||||
|
||||
internal class ConstraintsCollector(
|
||||
private val analysisContext: AnalysisContext,
|
||||
private val converterContext: NewJ2kConverterContext,
|
||||
private val converterContext: NewJ2kConverterContext?,
|
||||
printConstraints: Boolean
|
||||
) {
|
||||
private val boundTypeStorage = BoundTypeStorage(analysisContext, printConstraints)
|
||||
@@ -51,7 +51,7 @@ internal class ConstraintsCollector(
|
||||
|
||||
private val PsiElement.elementInfo: List<JKElementInfo>?
|
||||
get() = getLabel()?.let { label ->
|
||||
converterContext.elementsInfoStorage.getInfoForLabel(label)
|
||||
converterContext?.elementsInfoStorage?.getInfoForLabel(label)
|
||||
}
|
||||
|
||||
private inline val KtExpression.boundType
|
||||
|
||||
@@ -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<TypeVariableTypeParameter> =
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
+7
-10
@@ -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<KtTypeReference>() }
|
||||
typeElements.forEach { typeReference ->
|
||||
val typeElement = typeReference.typeElement ?: return@forEach
|
||||
if (typeElement.parentOfType<KtSuperTypeCallEntry>() == null) {
|
||||
prepareTypeElement(typeElement, conversionContext)
|
||||
prepareTypeElement(typeElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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<String, JKSymbol>()
|
||||
class JKSymbolProvider(project: Project, module: Module, contextElement: PsiElement) {
|
||||
private val symbolsByFqName = mutableMapOf<String, JKSymbol>()
|
||||
val symbolsByPsi = mutableMapOf<PsiElement, JKSymbol>()
|
||||
val symbolsByJK = mutableMapOf<JKDeclaration, JKSymbol>()
|
||||
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 <reified T : JKSymbol> 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<T>()
|
||||
return symbol ?: when {
|
||||
isAssignable<T, JKUnresolvedMethod>() -> JKUnresolvedMethod(fqName)
|
||||
isAssignable<T, JKUnresolvedField>() -> JKUnresolvedField(fqName, this)
|
||||
else -> JKUnresolvedClassSymbol(fqName)
|
||||
} as T
|
||||
}
|
||||
|
||||
@Deprecated("", ReplaceWith("provideByFqName(fqName, true, context)"))
|
||||
internal inline fun <reified T : JKSymbol> 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 <reified T : JKSymbol> 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 <reified T : JKSymbol> 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 <reified T : JKSymbol> 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 <reified A, reified B> isAssignable(): Boolean = A::class.java.isAssignableFrom(B::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <K, V : Any> MutableMap<K, V>.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('/', '.')
|
||||
@@ -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))
|
||||
)
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)))
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+5
-2
@@ -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<JKBlockStatement>().block.statements.first().cast<JKKtAssignmentStatement>().expression =
|
||||
JKFieldAccessExpressionImpl(
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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<KtDotQualifiedExpression>()
|
||||
?.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<KtDotQualifiedExpression>()
|
||||
?.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<KtDeclaration>, typeAliasesPsi: Collection<KtTypeAlias>): 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<PsiElement> {
|
||||
return constructImportDirectiveWithContext(fqName)
|
||||
.getChildOfType<KtDotQualifiedExpression>()
|
||||
?.selectorExpression
|
||||
?.let { selector ->
|
||||
selector.references.filterIsInstance<PsiPolyVariantReference>()
|
||||
.flatMap { polyVariantReference ->
|
||||
polyVariantReference
|
||||
.multiResolve(false)
|
||||
.mapNotNull { it.element }
|
||||
}
|
||||
}.orEmpty()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun multiResolveFqName(classId: ClassId, elementForContext: PsiElement): List<PsiElement> {
|
||||
return constructImportDirectiveWithContext(classId, elementForContext)
|
||||
.getChildOfType<KtDotQualifiedExpression>()
|
||||
?.selectorExpression
|
||||
?.let {
|
||||
it.references.filterIsInstance<PsiPolyVariantReference>().flatMap { it.multiResolve(false).mapNotNull { it.element } }
|
||||
}.orEmpty()
|
||||
}
|
||||
@@ -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<JKClassSymbol>(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<JKClassSymbol>(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<JKMethodSymbol>("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<JKMethodSymbol>("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<JKType>, 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()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<JKType>
|
||||
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 {
|
||||
|
||||
@@ -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<JKClassSymbol>("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
|
||||
)
|
||||
|
||||
+1
-1
@@ -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()
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user