New J2K: make post-processing aware of other files which are being converted
Before post-processing was able to handle only one converting file at once So, some conversions (like (field, getter, setter) to Kotlin property) was not able to work when converting class hierarchy was split into multiple files. Also, inferring nullability for a set of files was broken #KT-19569 fixed #KT-34266 fixed #KT-32518 fixed
This commit is contained in:
@@ -32,8 +32,7 @@ import org.jetbrains.kotlin.idea.core.util.range
|
||||
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.j2k.ConverterContext
|
||||
import org.jetbrains.kotlin.j2k.PostProcessor
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -61,11 +60,15 @@ class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
||||
}
|
||||
|
||||
override fun doAdditionalProcessing(
|
||||
file: KtFile,
|
||||
target: JKPostProcessingTarget,
|
||||
converterContext: ConverterContext?,
|
||||
rangeMarker: RangeMarker?,
|
||||
onPhaseChanged: ((Int, String) -> Unit)?
|
||||
) =
|
||||
) {
|
||||
val (file, rangeMarker) = when (target) {
|
||||
is JKPieceOfCodePostProcessingTarget -> target.file to target.rangeMarker
|
||||
is JKMultipleFilesPostProcessingTarget -> target.files.single() to null
|
||||
}
|
||||
|
||||
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
|
||||
do {
|
||||
var modificationStamp: Long? = file.modificationStamp
|
||||
@@ -109,7 +112,7 @@ class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private data class ActionData(val element: KtElement, val action: () -> Unit, val priority: Int, val writeActionNeeded: Boolean)
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ import org.jetbrains.kotlin.idea.util.isRunningInCidrIde
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.j2k
|
||||
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
@@ -29,14 +30,19 @@ class AfterConversionPass(val project: Project, val postProcessor: PostProcessor
|
||||
range: TextRange?,
|
||||
onPhaseChanged: ((Int, String) -> Unit)? = null
|
||||
) {
|
||||
val rangeMarker = if (range != null) {
|
||||
val document = kotlinFile.viewProvider.document!!
|
||||
val marker = runReadAction { document.createRangeMarker(range.startOffset, range.endOffset) }
|
||||
marker.isGreedyToLeft = true
|
||||
marker.isGreedyToRight = true
|
||||
marker
|
||||
} else null
|
||||
|
||||
postProcessor.doAdditionalProcessing(kotlinFile, converterContext, rangeMarker, onPhaseChanged)
|
||||
postProcessor.doAdditionalProcessing(
|
||||
when {
|
||||
range != null -> JKPieceOfCodePostProcessingTarget(kotlinFile, range.toRangeMarker(kotlinFile))
|
||||
else -> JKMultipleFilesPostProcessingTarget(listOf(kotlinFile))
|
||||
},
|
||||
converterContext,
|
||||
onPhaseChanged
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun TextRange.toRangeMarker(file: KtFile): RangeMarker =
|
||||
runReadAction { file.viewProvider.document!!.createRangeMarker(startOffset, endOffset) }.apply {
|
||||
isGreedyToLeft = true
|
||||
isGreedyToRight = true
|
||||
}
|
||||
@@ -26,12 +26,15 @@ import com.intellij.openapi.util.Computable
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.DummyHolder
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.core.util.range
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.j2k.ast.Element
|
||||
import org.jetbrains.kotlin.j2k.usageProcessing.ExternalCodeProcessor
|
||||
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import java.util.*
|
||||
@@ -43,13 +46,37 @@ interface PostProcessor {
|
||||
val phasesCount: Int
|
||||
|
||||
fun doAdditionalProcessing(
|
||||
file: KtFile,
|
||||
target: JKPostProcessingTarget,
|
||||
converterContext: ConverterContext?,
|
||||
rangeMarker: RangeMarker?,
|
||||
onPhaseChanged: ((Int, String) -> Unit)?
|
||||
)
|
||||
}
|
||||
|
||||
sealed class JKPostProcessingTarget
|
||||
|
||||
data class JKPieceOfCodePostProcessingTarget(
|
||||
val file: KtFile,
|
||||
val rangeMarker: RangeMarker
|
||||
) : JKPostProcessingTarget()
|
||||
|
||||
|
||||
data class JKMultipleFilesPostProcessingTarget(
|
||||
val files: List<KtFile>
|
||||
) : JKPostProcessingTarget()
|
||||
|
||||
fun JKPostProcessingTarget.elements() = when (this) {
|
||||
is JKPieceOfCodePostProcessingTarget -> runReadAction {
|
||||
val range = rangeMarker.range ?: return@runReadAction emptyList()
|
||||
file.elementsInRange(range)
|
||||
}
|
||||
is JKMultipleFilesPostProcessingTarget -> files
|
||||
}
|
||||
|
||||
fun JKPostProcessingTarget.files() = when (this) {
|
||||
is JKPieceOfCodePostProcessingTarget -> listOf(file)
|
||||
is JKMultipleFilesPostProcessingTarget -> files
|
||||
}
|
||||
|
||||
enum class ParseContext {
|
||||
TOP_LEVEL,
|
||||
CODE_BLOCK
|
||||
@@ -270,7 +297,7 @@ interface WithProgressProcessor {
|
||||
processItem: (TInputItem) -> TOutputItem
|
||||
): List<TOutputItem>
|
||||
|
||||
fun updateState(fileIndex: Int, phase: Int, description: String)
|
||||
fun updateState(fileIndex: Int?, phase: Int, description: String)
|
||||
fun <T> process(action: () -> T): T
|
||||
}
|
||||
|
||||
@@ -318,7 +345,7 @@ class OldWithProgressProcessor(private val progress: ProgressIndicator?, private
|
||||
throw AbstractMethodError("Should not be called for old J2K")
|
||||
}
|
||||
|
||||
override fun updateState(fileIndex: Int, phase: Int, description: String) {
|
||||
override fun updateState(fileIndex: Int?, phase: Int, description: String) {
|
||||
throw AbstractMethodError("Should not be called for old J2K")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isTrivialSta
|
||||
import org.jetbrains.kotlin.idea.quickfix.*
|
||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||
import org.jetbrains.kotlin.j2k.ConverterContext
|
||||
import org.jetbrains.kotlin.j2k.JKPostProcessingTarget
|
||||
import org.jetbrains.kotlin.j2k.PostProcessor
|
||||
import org.jetbrains.kotlin.j2k.files
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
@@ -42,23 +44,23 @@ class NewJ2kPostProcessor : PostProcessor {
|
||||
|
||||
override val phasesCount = processings.size
|
||||
|
||||
|
||||
override fun doAdditionalProcessing(
|
||||
file: KtFile,
|
||||
target: JKPostProcessingTarget,
|
||||
converterContext: ConverterContext?,
|
||||
rangeMarker: RangeMarker?,
|
||||
onPhaseChanged: ((Int, String) -> Unit)?
|
||||
) {
|
||||
for ((i, group) in processings.withIndex()) {
|
||||
onPhaseChanged?.invoke(i + 1, group.description)
|
||||
for (processing in group.processings) {
|
||||
try {
|
||||
processing.runProcessing(file, rangeMarker, converterContext as NewJ2kConverterContext)
|
||||
processing.runProcessing(target, converterContext as NewJ2kConverterContext)
|
||||
} catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
} catch (t: Throwable) {
|
||||
LOG.error(t)
|
||||
} finally {
|
||||
commitFile(file)
|
||||
target.files().forEach(::commitFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.nj2k.postProcessing
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
|
||||
internal abstract class JKInMemoryFilesSearcher {
|
||||
abstract fun search(element: KtElement): Iterable<PsiReference>
|
||||
|
||||
companion object {
|
||||
fun create(files: List<PsiElement>) = when {
|
||||
files.size == 1 -> JKSingleFileInMemoryFilesSearcher(files.single())
|
||||
else -> JKMultipleFilesInMemoryFilesSearcher(files)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class JKSingleFileInMemoryFilesSearcher(private val scopeElement: PsiElement) : JKInMemoryFilesSearcher() {
|
||||
override fun search(element: KtElement): Iterable<PsiReference> =
|
||||
ReferencesSearch.search(element, LocalSearchScope(scopeElement))
|
||||
}
|
||||
|
||||
|
||||
// it does not cover all cases e.g, just-changed reference
|
||||
// maybe the solution is to do searching manually
|
||||
// firstly by-text and then resolving
|
||||
internal class JKMultipleFilesInMemoryFilesSearcher(private val scopeElements: List<PsiElement>) : JKInMemoryFilesSearcher() {
|
||||
override fun search(element: KtElement): Iterable<PsiReference> {
|
||||
val result = mutableListOf<PsiReference>()
|
||||
for (scopeElement in scopeElements) {
|
||||
result += ReferencesSearch.search(element, LocalSearchScope(scopeElement))
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
+8
-5
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.nj2k.postProcessing
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
@@ -15,6 +16,7 @@ import org.jetbrains.kotlin.idea.core.util.range
|
||||
import org.jetbrains.kotlin.idea.quickfix.AddExclExclCallFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
@@ -23,7 +25,7 @@ import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<DiagnosticBasedProcessing>) : ProcessingGroup {
|
||||
class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<DiagnosticBasedProcessing>) : FileBasedPostProcessing() {
|
||||
constructor(vararg diagnosticBasedProcessings: DiagnosticBasedProcessing) : this(diagnosticBasedProcessings.toList())
|
||||
|
||||
private val diagnosticToFix =
|
||||
@@ -33,8 +35,9 @@ class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<Diagno
|
||||
list.map { it.second }
|
||||
}
|
||||
|
||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
val diagnostics = runReadAction { analyzeFileRange(file, rangeMarker).all() }
|
||||
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
val resolutionFacade = runReadAction { KotlinCacheService.getInstance(converterContext.project).getResolutionFacade(allFiles) }
|
||||
val diagnostics = runReadAction { analyzeFileRange(file, rangeMarker, resolutionFacade).all() }
|
||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||
for (diagnostic in diagnostics) {
|
||||
val range = rangeMarker?.range ?: file.textRange
|
||||
@@ -49,7 +52,7 @@ class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<Diagno
|
||||
}
|
||||
}
|
||||
|
||||
private fun analyzeFileRange(file: KtFile, rangeMarker: RangeMarker?): Diagnostics {
|
||||
private fun analyzeFileRange(file: KtFile, rangeMarker: RangeMarker?, resolutionFacade: ResolutionFacade): Diagnostics {
|
||||
val elements = when {
|
||||
rangeMarker == null -> listOf(file)
|
||||
rangeMarker.isValid -> file.elementsInRange(rangeMarker.range!!).filterIsInstance<KtElement>()
|
||||
@@ -57,7 +60,7 @@ class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<Diagno
|
||||
}
|
||||
|
||||
return if (elements.isNotEmpty())
|
||||
file.getResolutionFacade().analyzeWithAllCompilerChecks(elements).bindingContext.diagnostics
|
||||
resolutionFacade.analyzeWithAllCompilerChecks(elements).bindingContext.diagnostics
|
||||
else Diagnostics.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -18,15 +18,13 @@ import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.utils.mapToIndex
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.isSubclassOf
|
||||
|
||||
|
||||
class InspectionLikeProcessingGroup(
|
||||
private val runSingleTime: Boolean = false,
|
||||
private val acceptNonKtElements: Boolean = false,
|
||||
private val processings: List<InspectionLikeProcessing>
|
||||
) : ProcessingGroup {
|
||||
) : FileBasedPostProcessing() {
|
||||
constructor(vararg processings: InspectionLikeProcessing) : this(
|
||||
runSingleTime = false,
|
||||
acceptNonKtElements = false,
|
||||
@@ -35,8 +33,7 @@ class InspectionLikeProcessingGroup(
|
||||
|
||||
private val processingsToPriorityMap = processings.mapToIndex()
|
||||
fun priority(processing: InspectionLikeProcessing): Int = processingsToPriorityMap.getValue(processing)
|
||||
|
||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
do {
|
||||
var modificationStamp: Long? = file.modificationStamp
|
||||
val elementToActions = runReadAction {
|
||||
|
||||
+20
-12
@@ -7,27 +7,35 @@ package org.jetbrains.kotlin.nj2k.postProcessing
|
||||
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.core.util.range
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.j2k.JKMultipleFilesPostProcessingTarget
|
||||
import org.jetbrains.kotlin.j2k.JKPieceOfCodePostProcessingTarget
|
||||
import org.jetbrains.kotlin.j2k.JKPostProcessingTarget
|
||||
import org.jetbrains.kotlin.j2k.elements
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
|
||||
|
||||
interface GeneralPostProcessing {
|
||||
fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext)
|
||||
fun runProcessing(target: JKPostProcessingTarget, converterContext: NewJ2kConverterContext)
|
||||
}
|
||||
|
||||
|
||||
abstract class FileBasedPostProcessing : GeneralPostProcessing {
|
||||
final override fun runProcessing(target: JKPostProcessingTarget, converterContext: NewJ2kConverterContext) = when (target) {
|
||||
is JKPieceOfCodePostProcessingTarget ->
|
||||
runProcessing(target.file, listOf(target.file), target.rangeMarker, converterContext)
|
||||
is JKMultipleFilesPostProcessingTarget ->
|
||||
target.files.forEach { file ->
|
||||
runProcessing(file, target.files, rangeMarker = null, converterContext = converterContext)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext)
|
||||
}
|
||||
|
||||
abstract class ElementsBasedPostProcessing : GeneralPostProcessing {
|
||||
final override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
val elements = runReadAction {
|
||||
rangeMarker?.let { marker ->
|
||||
val range = marker.range ?: return@let emptyList()
|
||||
file.elementsInRange(range)
|
||||
} ?: listOf(file)
|
||||
}
|
||||
runProcessing(elements, converterContext)
|
||||
final override fun runProcessing(target: JKPostProcessingTarget, converterContext: NewJ2kConverterContext) {
|
||||
runProcessing(target.elements(), converterContext)
|
||||
}
|
||||
|
||||
abstract fun runProcessing(elements: List<PsiElement>, converterContext: NewJ2kConverterContext)
|
||||
|
||||
+63
-52
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.nj2k.postProcessing.processings
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.refactoring.rename.RenamePsiElementProcessor
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
@@ -22,17 +22,21 @@ import org.jetbrains.kotlin.idea.refactoring.isInterfaceClass
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.nj2k.*
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.asGetterName
|
||||
import org.jetbrains.kotlin.nj2k.asSetterName
|
||||
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKFakeFieldData
|
||||
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKFieldData
|
||||
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKMethodData
|
||||
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.NewExternalCodeProcessing
|
||||
import org.jetbrains.kotlin.nj2k.fqNameWithoutCompanions
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
@@ -51,16 +55,59 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.mapToIndex
|
||||
|
||||
class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing() {
|
||||
override fun runProcessing(elements: List<PsiElement>, converterContext: NewJ2kConverterContext) {
|
||||
val ktElements = elements.filterIsInstance<KtElement>()
|
||||
val resolutionFacade = runReadAction {
|
||||
KotlinCacheService.getInstance(converterContext.project).getResolutionFacade(ktElements)
|
||||
}
|
||||
ConvertGettersAndSettersToPropertyStatefulProcessing(
|
||||
resolutionFacade,
|
||||
ktElements,
|
||||
converterContext.externalCodeProcessor
|
||||
).runProcessing()
|
||||
}
|
||||
}
|
||||
|
||||
private class ConvertGettersAndSettersToPropertyStatefulProcessing(
|
||||
private val resolutionFacade: ResolutionFacade,
|
||||
private val elements: List<KtElement>,
|
||||
private val externalCodeUpdater: NewExternalCodeProcessing
|
||||
) {
|
||||
private val searcher = JKInMemoryFilesSearcher.create(elements)
|
||||
|
||||
|
||||
fun runProcessing() {
|
||||
val collectingState = CollectingState()
|
||||
val classesWithPropertiesData = runReadAction {
|
||||
elements
|
||||
.descendantsOfType<KtClassOrObject>()
|
||||
.sortedByInheritance()
|
||||
.map { klass ->
|
||||
klass to klass.collectPropertiesData(collectingState)
|
||||
}
|
||||
}
|
||||
if (classesWithPropertiesData.isEmpty()) return
|
||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||
for ((klass, propertiesData) in classesWithPropertiesData) {
|
||||
convertClass(klass, propertiesData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtNamedFunction.hasOverrides(): Boolean =
|
||||
toLightMethods().singleOrNull()?.let { lightMethod ->
|
||||
OverridingMethodsSearch.search(lightMethod).findFirst()
|
||||
} != null
|
||||
if (OverridingMethodsSearch.search(lightMethod).findFirst() != null) return@let true
|
||||
if (elements.size == 1) return@let false
|
||||
elements.any { element ->
|
||||
OverridingMethodsSearch.search(lightMethod, LocalSearchScope(element), true).findFirst() != null
|
||||
}
|
||||
} == true
|
||||
|
||||
private fun KtNamedFunction.hasSuperFunction(): Boolean =
|
||||
resolveToDescriptorIfAny()?.original?.overriddenDescriptors?.isNotEmpty() == true
|
||||
resolveToDescriptorIfAny(resolutionFacade)?.original?.overriddenDescriptors?.isNotEmpty() == true
|
||||
|
||||
private fun KtNamedFunction.hasInvalidSuperDescriptors(): Boolean =
|
||||
resolveToDescriptorIfAny()
|
||||
resolveToDescriptorIfAny(resolutionFacade)
|
||||
?.original
|
||||
?.overriddenDescriptors
|
||||
?.any { it.isJavaDescriptor || it is FunctionDescriptor } == true
|
||||
@@ -216,7 +263,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
}
|
||||
|
||||
private fun KtElement.usages() =
|
||||
ReferencesSearch.search(this, LocalSearchScope(containingKtFile))
|
||||
searcher.search(this)
|
||||
|
||||
private fun <T : KtExpression> T.withReplacedExpressionInBody(
|
||||
from: KtElement,
|
||||
@@ -249,7 +296,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
|
||||
val sorted = mutableListOf<KtClassOrObject>()
|
||||
val visited = Array(size) { false }
|
||||
val descriptors = map { it.resolveToDescriptorIfAny()!! }
|
||||
val descriptors = map { it.resolveToDescriptorIfAny(resolutionFacade)!! }
|
||||
val descriptorToIndex = descriptors.mapToIndex()
|
||||
val outers = descriptors.map { descriptor ->
|
||||
descriptor.superClassAndSuperInterfaces().mapNotNull { descriptorToIndex[it] }
|
||||
@@ -273,25 +320,6 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
return sorted
|
||||
}
|
||||
|
||||
|
||||
override fun runProcessing(elements: List<PsiElement>, converterContext: NewJ2kConverterContext) {
|
||||
val collectingState = CollectingState()
|
||||
val classesWithPropertiesData = runReadAction {
|
||||
elements
|
||||
.descendantsOfType<KtClassOrObject>()
|
||||
.sortedByInheritance()
|
||||
.map { klass ->
|
||||
klass to klass.collectPropertiesData(collectingState)
|
||||
}
|
||||
}
|
||||
if (classesWithPropertiesData.isEmpty()) return
|
||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||
for ((klass, propertiesData) in classesWithPropertiesData) {
|
||||
convertClass(klass, propertiesData, converterContext.externalCodeProcessor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun causesNameConflictInCurrentDeclarationAndItsParents(name: String, declaration: DeclarationDescriptor?): Boolean =
|
||||
when (declaration) {
|
||||
is ClassDescriptor -> {
|
||||
@@ -310,27 +338,11 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
}
|
||||
|
||||
private fun calculatePropertyType(getter: KtNamedFunction?, setter: KtNamedFunction?): KotlinType? {
|
||||
val getterType = getter?.resolveToDescriptorIfAny()?.returnType
|
||||
val setterType = setter?.resolveToDescriptorIfAny()?.valueParameters?.singleOrNull()?.type
|
||||
val getterType = getter?.resolveToDescriptorIfAny(resolutionFacade)?.returnType
|
||||
val setterType = setter?.resolveToDescriptorIfAny(resolutionFacade)?.valueParameters?.singleOrNull()?.type
|
||||
return calculatePropertyType(getterType, setterType)
|
||||
}
|
||||
|
||||
private fun calculatePropertyTypeBasedOnSuperDescriptors(getter: KtNamedFunction?, setter: KtNamedFunction?): KotlinType? {
|
||||
val superGetterType = getter
|
||||
?.resolveToDescriptorIfAny()
|
||||
?.overriddenDescriptors
|
||||
?.firstOrNull()
|
||||
?.returnType
|
||||
val superSetterType = setter
|
||||
?.resolveToDescriptorIfAny()
|
||||
?.overriddenDescriptors
|
||||
?.firstOrNull()
|
||||
?.valueParameters
|
||||
?.singleOrNull()
|
||||
?.type
|
||||
return calculatePropertyType(superGetterType, superSetterType)
|
||||
}
|
||||
|
||||
private fun KtClassOrObject.collectPropertiesData(collectingState: CollectingState): List<PropertyData> {
|
||||
return declarations
|
||||
.asSequence()
|
||||
@@ -356,7 +368,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
val name = realGetter?.name ?: realSetter?.name!!
|
||||
|
||||
val superDeclarationOwner = (realGetter?.function ?: realSetter?.function)
|
||||
?.resolveToDescriptorIfAny()
|
||||
?.resolveToDescriptorIfAny(resolutionFacade)
|
||||
?.overriddenDescriptors
|
||||
?.firstOrNull()
|
||||
?.findPsi()
|
||||
@@ -378,7 +390,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
klass: KtClassOrObject,
|
||||
factory: KtPsiFactory
|
||||
): List<PropertyWithAccessors> {
|
||||
val classDescriptor = klass.resolveToDescriptorIfAny() ?: return emptyList()
|
||||
val classDescriptor = klass.resolveToDescriptorIfAny(resolutionFacade) ?: return emptyList()
|
||||
|
||||
val variablesDescriptorsMap =
|
||||
(listOfNotNull(classDescriptor.getSuperClassNotAny()) + classDescriptor.getSuperInterfaces())
|
||||
@@ -462,7 +474,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
|
||||
|
||||
val getter = realGetter ?: when {
|
||||
realProperty?.property?.resolveToDescriptorIfAny()?.overriddenDescriptors?.any {
|
||||
realProperty?.property?.resolveToDescriptorIfAny(resolutionFacade)?.overriddenDescriptors?.any {
|
||||
it.safeAs<VariableDescriptor>()?.isVar == true
|
||||
} == true -> FakeGetter(name, null, "")
|
||||
|
||||
@@ -487,7 +499,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
realProperty?.property?.isVar == true ->
|
||||
FakeSetter(name, null, "")
|
||||
|
||||
realProperty?.property?.resolveToDescriptorIfAny()?.overriddenDescriptors?.any {
|
||||
realProperty?.property?.resolveToDescriptorIfAny(resolutionFacade)?.overriddenDescriptors?.any {
|
||||
it.safeAs<VariableDescriptor>()?.isVar == true
|
||||
} == true
|
||||
|| variablesDescriptorsMap[name]?.isVar == true ->
|
||||
@@ -523,7 +535,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
}
|
||||
|
||||
private fun KtProperty.renameTo(newName: String, factory: KtPsiFactory) {
|
||||
for (usage in usages().toList()) {
|
||||
for (usage in usages()) {
|
||||
val element = usage.element
|
||||
val isBackingField = element is KtNameReferenceExpression
|
||||
&& element.text == KtTokens.FIELD_KEYWORD.value
|
||||
@@ -540,8 +552,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
||||
|
||||
private fun convertClass(
|
||||
klass: KtClassOrObject,
|
||||
propertiesData: List<PropertyData>,
|
||||
externalCodeUpdater: NewExternalCodeProcessing
|
||||
propertiesData: List<PropertyData>
|
||||
) {
|
||||
val factory = KtPsiFactory(klass)
|
||||
val accessors = propertiesData.filterGettersAndSetters(klass, factory)
|
||||
|
||||
+10
-14
@@ -5,9 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.nj2k.postProcessing.processings
|
||||
|
||||
import com.intellij.openapi.editor.RangeMarker
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.core.util.range
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
@@ -20,19 +19,16 @@ import org.jetbrains.kotlin.nj2k.inference.common.collectors.CommonConstraintsCo
|
||||
import org.jetbrains.kotlin.nj2k.inference.common.collectors.FunctionConstraintsCollector
|
||||
import org.jetbrains.kotlin.nj2k.inference.mutability.*
|
||||
import org.jetbrains.kotlin.nj2k.inference.nullability.*
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.GeneralPostProcessing
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.ElementsBasedPostProcessing
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
|
||||
abstract class InferenceProcessing : GeneralPostProcessing {
|
||||
final override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
val elements = if (rangeMarker != null) {
|
||||
val range = rangeMarker.range ?: return
|
||||
runReadAction { file.elementsInRange(range) }.filterIsInstance<KtElement>()
|
||||
} else listOf(file)
|
||||
val resolutionFacade = runReadAction { file.getResolutionFacade() }
|
||||
createInferenceFacade(resolutionFacade, converterContext).runOn(elements)
|
||||
abstract class InferenceProcessing : ElementsBasedPostProcessing() {
|
||||
override fun runProcessing(elements: List<PsiElement>, converterContext: NewJ2kConverterContext) {
|
||||
val kotlinElements = elements.filterIsInstance<KtElement>()
|
||||
val resolutionFacade = runReadAction {
|
||||
KotlinCacheService.getInstance(converterContext.project).getResolutionFacade(kotlinElements)
|
||||
}
|
||||
createInferenceFacade(resolutionFacade, converterContext).runOn(kotlinElements)
|
||||
}
|
||||
|
||||
abstract fun createInferenceFacade(
|
||||
|
||||
+3
-2
@@ -10,12 +10,13 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.nj2k.JKImportStorage
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.FileBasedPostProcessing
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.GeneralPostProcessing
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.runUndoTransparentActionInEdt
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||
|
||||
class ShortenReferenceProcessing : GeneralPostProcessing {
|
||||
class ShortenReferenceProcessing : FileBasedPostProcessing() {
|
||||
private val filter = filter@{ element: PsiElement ->
|
||||
when (element) {
|
||||
is KtQualifiedExpression -> when {
|
||||
@@ -26,7 +27,7 @@ class ShortenReferenceProcessing : GeneralPostProcessing {
|
||||
}
|
||||
}
|
||||
|
||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
runUndoTransparentActionInEdt(inWriteAction = false) {
|
||||
if (rangeMarker != null) {
|
||||
if (rangeMarker.isValid) {
|
||||
|
||||
+20
-15
@@ -13,16 +13,19 @@ import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import org.jetbrains.kotlin.idea.core.util.range
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.j2k.JKPostProcessingTarget
|
||||
import org.jetbrains.kotlin.j2k.elements
|
||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||
import org.jetbrains.kotlin.nj2k.asLabel
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.FileBasedPostProcessing
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.GeneralPostProcessing
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.runUndoTransparentActionInEdt
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
|
||||
|
||||
class FormatCodeProcessing : GeneralPostProcessing {
|
||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
class FormatCodeProcessing : FileBasedPostProcessing() {
|
||||
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
val codeStyleManager = CodeStyleManager.getInstance(file.project)
|
||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||
if (rangeMarker != null) {
|
||||
@@ -38,28 +41,30 @@ class FormatCodeProcessing : GeneralPostProcessing {
|
||||
|
||||
|
||||
class ClearUnknownLabelsProcessing : GeneralPostProcessing {
|
||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
override fun runProcessing(target: JKPostProcessingTarget, converterContext: NewJ2kConverterContext) {
|
||||
val comments = mutableListOf<PsiComment>()
|
||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||
file.accept(object : PsiElementVisitor() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
|
||||
override fun visitComment(comment: PsiComment) {
|
||||
if (comment.text.asLabel() != null) {
|
||||
comments += comment
|
||||
target.elements().forEach { element ->
|
||||
element.accept(object : PsiElementVisitor() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
element.acceptChildren(this)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
override fun visitComment(comment: PsiComment) {
|
||||
if (comment.text.asLabel() != null) {
|
||||
comments += comment
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
comments.forEach { it.delete() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class OptimizeImportsProcessing : GeneralPostProcessing {
|
||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
class OptimizeImportsProcessing : FileBasedPostProcessing() {
|
||||
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||
val elements = runReadAction {
|
||||
when {
|
||||
rangeMarker != null && rangeMarker.isValid -> file.elementsInRange(rangeMarker.range!!)
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
package org.jetbrains.kotlin.nj2k
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -28,7 +26,6 @@ import com.intellij.openapi.util.Computable
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.j2k.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.nj2k.conversions.JKResolver
|
||||
@@ -68,36 +65,27 @@ class NewJavaToKotlinConverter(
|
||||
elementsToKotlin(files, withProgressProcessor)
|
||||
})
|
||||
|
||||
val texts = results.mapIndexed { i, result ->
|
||||
try {
|
||||
val kotlinFile = ApplicationManager.getApplication().runReadAction(Computable {
|
||||
KtPsiFactory(project).createFileWithLightClassSupport("dummy.kt", result!!.text, files[i])
|
||||
})
|
||||
|
||||
ApplicationManager.getApplication().invokeAndWait {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
runWriteAction {
|
||||
kotlinFile.addImports(result!!.importsToAdd)
|
||||
}
|
||||
}
|
||||
val kotlinFiles = results.mapIndexed { i, result ->
|
||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||
val javaFile = files[i]
|
||||
KtPsiFactory(project).createFileWithLightClassSupport(
|
||||
javaFile.name.replace(".java", ".kt"),
|
||||
result!!.text,
|
||||
files[i]
|
||||
).apply {
|
||||
addImports(result.importsToAdd)
|
||||
}
|
||||
AfterConversionPass(project, postProcessor).run(
|
||||
kotlinFile,
|
||||
context,
|
||||
range = null,
|
||||
onPhaseChanged = { phase, description ->
|
||||
withProgressProcessor.updateState(i, phase + 1, description)
|
||||
}
|
||||
)
|
||||
kotlinFile.text
|
||||
} catch (e: ProcessCanceledException) {
|
||||
throw e
|
||||
} catch (t: Throwable) {
|
||||
LOG.error(t)
|
||||
result!!.text
|
||||
}
|
||||
|
||||
}
|
||||
FilesResult(texts, externalCodeProcessing)
|
||||
|
||||
postProcessor.doAdditionalProcessing(
|
||||
JKMultipleFilesPostProcessingTarget(kotlinFiles),
|
||||
context
|
||||
) { phase, description ->
|
||||
withProgressProcessor.updateState(fileIndex = null, phase = phase + 1, description = description)
|
||||
}
|
||||
FilesResult(kotlinFiles.map { it.text }, externalCodeProcessing)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,12 +205,13 @@ class NewJ2kWithProgressProcessor(
|
||||
val DEFAULT = NewJ2kWithProgressProcessor(null, null, 0)
|
||||
}
|
||||
|
||||
override fun updateState(fileIndex: Int, phase: Int, description: String) {
|
||||
override fun updateState(fileIndex: Int?, phase: Int, description: String) {
|
||||
progress?.checkCanceled()
|
||||
progress?.fraction = phase / phasesCount.toDouble()
|
||||
progress?.text = "$description - phase $phase of $phasesCount"
|
||||
if (files != null && files.isNotEmpty()) {
|
||||
progress?.text2 = files[fileIndex].virtualFile.presentableUrl
|
||||
progress?.text2 = when {
|
||||
files != null && files.isNotEmpty() && fileIndex != null -> files[fileIndex].virtualFile.presentableUrl
|
||||
else -> ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,14 @@ package org.jetbrains.kotlin.nj2k
|
||||
|
||||
import com.intellij.codeInsight.generation.GenerateEqualsHelper.getEqualsSignature
|
||||
import com.intellij.lang.jvm.JvmClassKind
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.InheritanceUtil
|
||||
import com.intellij.psi.util.MethodSignatureUtil
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.j2k.ClassKind
|
||||
import org.jetbrains.kotlin.j2k.ReferenceSearcher
|
||||
import org.jetbrains.kotlin.j2k.isNullLiteral
|
||||
@@ -141,3 +144,16 @@ val KtDeclaration.fqNameWithoutCompanions
|
||||
.filter { it.safeAs<KtObjectDeclaration>()?.isCompanion() != true && it.name != null }
|
||||
.toList()
|
||||
.foldRight(containingKtFile.packageFqName) { container, acc -> acc.child(Name.identifier(container.name!!)) }
|
||||
|
||||
internal fun <T> runUndoTransparentActionInEdt(inWriteAction: Boolean, action: () -> T): T {
|
||||
var result: T? = null
|
||||
ApplicationManager.getApplication().invokeAndWait {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
result = when {
|
||||
inWriteAction -> runWriteAction(action)
|
||||
else -> action()
|
||||
}
|
||||
}
|
||||
}
|
||||
return result!!
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package test;
|
||||
|
||||
public class B {
|
||||
public String getFromB1() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getFromB2() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void setFromB2(String value) {
|
||||
}
|
||||
|
||||
public String getFromB3() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void setFromB3(String value) {
|
||||
}
|
||||
|
||||
public String getFromB4() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public void setFromB4(String value) {
|
||||
}
|
||||
|
||||
public void setFromB5(String value) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package test
|
||||
|
||||
open class B {
|
||||
val fromB1: String
|
||||
get() = ""
|
||||
|
||||
var fromB2: String?
|
||||
get() = ""
|
||||
set(value) {}
|
||||
|
||||
var fromB3: String?
|
||||
get() = ""
|
||||
set(value) {}
|
||||
|
||||
var fromB4: String?
|
||||
get() = ""
|
||||
set(value) {}
|
||||
|
||||
open fun setFromB5(value: String?) {}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package test;
|
||||
|
||||
public abstract class C extends B implements I {
|
||||
private final int mySomething1;
|
||||
private int mySomething6;
|
||||
|
||||
C(int something1) {
|
||||
mySomething1 = something1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSomething1() {
|
||||
return mySomething1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSomething2() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSomething3() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSomething3(int value) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSomething4() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSomething5(int value) {
|
||||
|
||||
}
|
||||
|
||||
public int getSomething6() {
|
||||
return mySomething6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSomething6(int value) {
|
||||
mySomething6 = value;
|
||||
}
|
||||
|
||||
public String getFromB5() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFromB5(String value) {
|
||||
super.setFromB5(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package test
|
||||
|
||||
abstract class C internal constructor(override val something1: Int) : B(), I {
|
||||
private var mySomething6 = 0
|
||||
|
||||
override val something2: Int
|
||||
get() = 0
|
||||
|
||||
override var something3: Int
|
||||
get() = 0
|
||||
set(value) {}
|
||||
|
||||
override fun getSomething4(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun setSomething5(value: Int) {}
|
||||
fun getSomething6(): Int {
|
||||
return mySomething6
|
||||
}
|
||||
|
||||
override fun setSomething6(value: Int) {
|
||||
mySomething6 = value
|
||||
}
|
||||
|
||||
fun getFromB5(): String {
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun setFromB5(value: String?) {
|
||||
super.setFromB5(value)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package test;
|
||||
|
||||
public interface I {
|
||||
int getSomething1();
|
||||
|
||||
int getSomething2();
|
||||
|
||||
int getSomething3();
|
||||
|
||||
void setSomething3(int value);
|
||||
|
||||
int getSomething4();
|
||||
|
||||
void setSomething4(int value);
|
||||
|
||||
int getSomething5();
|
||||
|
||||
void setSomething5(int value);
|
||||
|
||||
void setSomething6(int value);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package test
|
||||
|
||||
interface I {
|
||||
val something1: Int
|
||||
val something2: Int
|
||||
var something3: Int
|
||||
|
||||
fun getSomething4(): Int
|
||||
fun setSomething4(value: Int)
|
||||
fun getSomething5(): Int
|
||||
fun setSomething5(value: Int)
|
||||
fun setSomething6(value: Int)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package test;
|
||||
|
||||
public interface I1 extends I {
|
||||
void setSomething1(int value);
|
||||
|
||||
int getSomething6();
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package test
|
||||
|
||||
interface I1 : I {
|
||||
fun setSomething1(value: Int)
|
||||
val something6: Int
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test;
|
||||
|
||||
public interface IUser {
|
||||
String getName();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
interface IUser {
|
||||
val name: String
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package test;
|
||||
|
||||
public class UserImpl implements IUser {
|
||||
private final String name;
|
||||
|
||||
public UserImpl(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
class UserImpl(override val name: String) : IUser
|
||||
+5
-3
@@ -28,9 +28,11 @@ abstract class AbstractNewJavaToKotlinConverterMultiFileTest : AbstractJavaToKot
|
||||
psiManager.findFile(virtualFile) as PsiJavaFile
|
||||
}
|
||||
|
||||
val externalFiles = File(dirPath + File.separator + "external").listFiles { _, name ->
|
||||
name.endsWith(".java") || name.endsWith(".kt")
|
||||
}!!
|
||||
val externalFiles = File(dirPath + File.separator + "external")
|
||||
.takeIf { it.exists() }
|
||||
?.listFiles { _, name ->
|
||||
name.endsWith(".java") || name.endsWith(".kt")
|
||||
}.orEmpty()
|
||||
|
||||
val externalPsiFiles = externalFiles.map { file ->
|
||||
val virtualFile = addFile(file, "test")
|
||||
|
||||
+10
@@ -34,6 +34,11 @@ public class NewJavaToKotlinConverterMultiFileTestGenerated extends AbstractNewJ
|
||||
runTest("nj2k/testData/multiFile/AnnotationWithArrayParameter/");
|
||||
}
|
||||
|
||||
@TestMetadata("DetectPropertiesMultipleFiles")
|
||||
public void testDetectPropertiesMultipleFiles() throws Exception {
|
||||
runTest("nj2k/testData/multiFile/DetectPropertiesMultipleFiles/");
|
||||
}
|
||||
|
||||
@TestMetadata("FieldToProperty")
|
||||
public void testFieldToProperty() throws Exception {
|
||||
runTest("nj2k/testData/multiFile/FieldToProperty/");
|
||||
@@ -49,6 +54,11 @@ public class NewJavaToKotlinConverterMultiFileTestGenerated extends AbstractNewJ
|
||||
runTest("nj2k/testData/multiFile/GetterAndSetterUsages/");
|
||||
}
|
||||
|
||||
@TestMetadata("InterfaceWithGetterInOtherFile")
|
||||
public void testInterfaceWithGetterInOtherFile() throws Exception {
|
||||
runTest("nj2k/testData/multiFile/InterfaceWithGetterInOtherFile/");
|
||||
}
|
||||
|
||||
@TestMetadata("KT11952")
|
||||
public void testKT11952() throws Exception {
|
||||
runTest("nj2k/testData/multiFile/KT11952/");
|
||||
|
||||
Reference in New Issue
Block a user