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.ImportInsertHelper
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.j2k.ConverterContext
|
import org.jetbrains.kotlin.j2k.*
|
||||||
import org.jetbrains.kotlin.j2k.PostProcessor
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
@@ -61,11 +60,15 @@ class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun doAdditionalProcessing(
|
override fun doAdditionalProcessing(
|
||||||
file: KtFile,
|
target: JKPostProcessingTarget,
|
||||||
converterContext: ConverterContext?,
|
converterContext: ConverterContext?,
|
||||||
rangeMarker: RangeMarker?,
|
|
||||||
onPhaseChanged: ((Int, String) -> Unit)?
|
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())) {
|
runBlocking(EDT.ModalityStateElement(ModalityState.defaultModalityState())) {
|
||||||
do {
|
do {
|
||||||
var modificationStamp: Long? = file.modificationStamp
|
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)
|
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.j2k.*
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.UserDataProperty
|
import org.jetbrains.kotlin.psi.UserDataProperty
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.j2k
|
package org.jetbrains.kotlin.j2k
|
||||||
|
|
||||||
|
import com.intellij.openapi.editor.RangeMarker
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
@@ -29,14 +30,19 @@ class AfterConversionPass(val project: Project, val postProcessor: PostProcessor
|
|||||||
range: TextRange?,
|
range: TextRange?,
|
||||||
onPhaseChanged: ((Int, String) -> Unit)? = null
|
onPhaseChanged: ((Int, String) -> Unit)? = null
|
||||||
) {
|
) {
|
||||||
val rangeMarker = if (range != null) {
|
postProcessor.doAdditionalProcessing(
|
||||||
val document = kotlinFile.viewProvider.document!!
|
when {
|
||||||
val marker = runReadAction { document.createRangeMarker(range.startOffset, range.endOffset) }
|
range != null -> JKPieceOfCodePostProcessingTarget(kotlinFile, range.toRangeMarker(kotlinFile))
|
||||||
marker.isGreedyToLeft = true
|
else -> JKMultipleFilesPostProcessingTarget(listOf(kotlinFile))
|
||||||
marker.isGreedyToRight = true
|
},
|
||||||
marker
|
converterContext,
|
||||||
} else null
|
onPhaseChanged
|
||||||
|
)
|
||||||
postProcessor.doAdditionalProcessing(kotlinFile, converterContext, rangeMarker, 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.*
|
||||||
import com.intellij.psi.impl.source.DummyHolder
|
import com.intellij.psi.impl.source.DummyHolder
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
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.ast.Element
|
||||||
import org.jetbrains.kotlin.j2k.usageProcessing.ExternalCodeProcessor
|
import org.jetbrains.kotlin.j2k.usageProcessing.ExternalCodeProcessor
|
||||||
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing
|
import org.jetbrains.kotlin.j2k.usageProcessing.UsageProcessing
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
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.isAncestor
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -43,13 +46,37 @@ interface PostProcessor {
|
|||||||
val phasesCount: Int
|
val phasesCount: Int
|
||||||
|
|
||||||
fun doAdditionalProcessing(
|
fun doAdditionalProcessing(
|
||||||
file: KtFile,
|
target: JKPostProcessingTarget,
|
||||||
converterContext: ConverterContext?,
|
converterContext: ConverterContext?,
|
||||||
rangeMarker: RangeMarker?,
|
|
||||||
onPhaseChanged: ((Int, String) -> Unit)?
|
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 {
|
enum class ParseContext {
|
||||||
TOP_LEVEL,
|
TOP_LEVEL,
|
||||||
CODE_BLOCK
|
CODE_BLOCK
|
||||||
@@ -270,7 +297,7 @@ interface WithProgressProcessor {
|
|||||||
processItem: (TInputItem) -> TOutputItem
|
processItem: (TInputItem) -> TOutputItem
|
||||||
): List<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
|
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")
|
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")
|
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.quickfix.*
|
||||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||||
import org.jetbrains.kotlin.j2k.ConverterContext
|
import org.jetbrains.kotlin.j2k.ConverterContext
|
||||||
|
import org.jetbrains.kotlin.j2k.JKPostProcessingTarget
|
||||||
import org.jetbrains.kotlin.j2k.PostProcessor
|
import org.jetbrains.kotlin.j2k.PostProcessor
|
||||||
|
import org.jetbrains.kotlin.j2k.files
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
@@ -42,23 +44,23 @@ class NewJ2kPostProcessor : PostProcessor {
|
|||||||
|
|
||||||
override val phasesCount = processings.size
|
override val phasesCount = processings.size
|
||||||
|
|
||||||
|
|
||||||
override fun doAdditionalProcessing(
|
override fun doAdditionalProcessing(
|
||||||
file: KtFile,
|
target: JKPostProcessingTarget,
|
||||||
converterContext: ConverterContext?,
|
converterContext: ConverterContext?,
|
||||||
rangeMarker: RangeMarker?,
|
|
||||||
onPhaseChanged: ((Int, String) -> Unit)?
|
onPhaseChanged: ((Int, String) -> Unit)?
|
||||||
) {
|
) {
|
||||||
for ((i, group) in processings.withIndex()) {
|
for ((i, group) in processings.withIndex()) {
|
||||||
onPhaseChanged?.invoke(i + 1, group.description)
|
onPhaseChanged?.invoke(i + 1, group.description)
|
||||||
for (processing in group.processings) {
|
for (processing in group.processings) {
|
||||||
try {
|
try {
|
||||||
processing.runProcessing(file, rangeMarker, converterContext as NewJ2kConverterContext)
|
processing.runProcessing(target, converterContext as NewJ2kConverterContext)
|
||||||
} catch (e: ProcessCanceledException) {
|
} catch (e: ProcessCanceledException) {
|
||||||
throw e
|
throw e
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
LOG.error(t)
|
LOG.error(t)
|
||||||
} finally {
|
} 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.codeInsight.intention.IntentionAction
|
||||||
import com.intellij.openapi.editor.RangeMarker
|
import com.intellij.openapi.editor.RangeMarker
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
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.AddExclExclCallFix
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
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.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
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.resolve.diagnostics.Diagnostics
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
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())
|
constructor(vararg diagnosticBasedProcessings: DiagnosticBasedProcessing) : this(diagnosticBasedProcessings.toList())
|
||||||
|
|
||||||
private val diagnosticToFix =
|
private val diagnosticToFix =
|
||||||
@@ -33,8 +35,9 @@ class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<Diagno
|
|||||||
list.map { it.second }
|
list.map { it.second }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||||
val diagnostics = runReadAction { analyzeFileRange(file, rangeMarker).all() }
|
val resolutionFacade = runReadAction { KotlinCacheService.getInstance(converterContext.project).getResolutionFacade(allFiles) }
|
||||||
|
val diagnostics = runReadAction { analyzeFileRange(file, rangeMarker, resolutionFacade).all() }
|
||||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||||
for (diagnostic in diagnostics) {
|
for (diagnostic in diagnostics) {
|
||||||
val range = rangeMarker?.range ?: file.textRange
|
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 {
|
val elements = when {
|
||||||
rangeMarker == null -> listOf(file)
|
rangeMarker == null -> listOf(file)
|
||||||
rangeMarker.isValid -> file.elementsInRange(rangeMarker.range!!).filterIsInstance<KtElement>()
|
rangeMarker.isValid -> file.elementsInRange(rangeMarker.range!!).filterIsInstance<KtElement>()
|
||||||
@@ -57,7 +60,7 @@ class DiagnosticBasedPostProcessingGroup(diagnosticBasedProcessings: List<Diagno
|
|||||||
}
|
}
|
||||||
|
|
||||||
return if (elements.isNotEmpty())
|
return if (elements.isNotEmpty())
|
||||||
file.getResolutionFacade().analyzeWithAllCompilerChecks(elements).bindingContext.diagnostics
|
resolutionFacade.analyzeWithAllCompilerChecks(elements).bindingContext.diagnostics
|
||||||
else Diagnostics.EMPTY
|
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.psi.KtFile
|
||||||
import org.jetbrains.kotlin.utils.mapToIndex
|
import org.jetbrains.kotlin.utils.mapToIndex
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.reflect.KClass
|
|
||||||
import kotlin.reflect.full.isSubclassOf
|
|
||||||
|
|
||||||
|
|
||||||
class InspectionLikeProcessingGroup(
|
class InspectionLikeProcessingGroup(
|
||||||
private val runSingleTime: Boolean = false,
|
private val runSingleTime: Boolean = false,
|
||||||
private val acceptNonKtElements: Boolean = false,
|
private val acceptNonKtElements: Boolean = false,
|
||||||
private val processings: List<InspectionLikeProcessing>
|
private val processings: List<InspectionLikeProcessing>
|
||||||
) : ProcessingGroup {
|
) : FileBasedPostProcessing() {
|
||||||
constructor(vararg processings: InspectionLikeProcessing) : this(
|
constructor(vararg processings: InspectionLikeProcessing) : this(
|
||||||
runSingleTime = false,
|
runSingleTime = false,
|
||||||
acceptNonKtElements = false,
|
acceptNonKtElements = false,
|
||||||
@@ -35,8 +33,7 @@ class InspectionLikeProcessingGroup(
|
|||||||
|
|
||||||
private val processingsToPriorityMap = processings.mapToIndex()
|
private val processingsToPriorityMap = processings.mapToIndex()
|
||||||
fun priority(processing: InspectionLikeProcessing): Int = processingsToPriorityMap.getValue(processing)
|
fun priority(processing: InspectionLikeProcessing): Int = processingsToPriorityMap.getValue(processing)
|
||||||
|
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
|
||||||
do {
|
do {
|
||||||
var modificationStamp: Long? = file.modificationStamp
|
var modificationStamp: Long? = file.modificationStamp
|
||||||
val elementToActions = runReadAction {
|
val elementToActions = runReadAction {
|
||||||
|
|||||||
+20
-12
@@ -7,27 +7,35 @@ package org.jetbrains.kotlin.nj2k.postProcessing
|
|||||||
|
|
||||||
import com.intellij.openapi.editor.RangeMarker
|
import com.intellij.openapi.editor.RangeMarker
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
import org.jetbrains.kotlin.j2k.JKMultipleFilesPostProcessingTarget
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
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.nj2k.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
|
||||||
|
|
||||||
|
|
||||||
interface GeneralPostProcessing {
|
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 {
|
abstract class ElementsBasedPostProcessing : GeneralPostProcessing {
|
||||||
final override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
final override fun runProcessing(target: JKPostProcessingTarget, converterContext: NewJ2kConverterContext) {
|
||||||
val elements = runReadAction {
|
runProcessing(target.elements(), converterContext)
|
||||||
rangeMarker?.let { marker ->
|
|
||||||
val range = marker.range ?: return@let emptyList()
|
|
||||||
file.elementsInRange(range)
|
|
||||||
} ?: listOf(file)
|
|
||||||
}
|
|
||||||
runProcessing(elements, converterContext)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun runProcessing(elements: List<PsiElement>, converterContext: NewJ2kConverterContext)
|
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.PsiElement
|
||||||
import com.intellij.psi.search.LocalSearchScope
|
import com.intellij.psi.search.LocalSearchScope
|
||||||
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
|
||||||
import com.intellij.refactoring.rename.RenamePsiElementProcessor
|
import com.intellij.refactoring.rename.RenamePsiElementProcessor
|
||||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||||
|
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
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.KtSimpleNameReference
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.references.readWriteAccess
|
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.CommentSaver
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
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.JKFakeFieldData
|
||||||
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKFieldData
|
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKFieldData
|
||||||
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKMethodData
|
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKMethodData
|
||||||
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.NewExternalCodeProcessing
|
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.NewExternalCodeProcessing
|
||||||
|
import org.jetbrains.kotlin.nj2k.fqNameWithoutCompanions
|
||||||
import org.jetbrains.kotlin.nj2k.postProcessing.*
|
import org.jetbrains.kotlin.nj2k.postProcessing.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
@@ -51,16 +55,59 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|||||||
import org.jetbrains.kotlin.utils.mapToIndex
|
import org.jetbrains.kotlin.utils.mapToIndex
|
||||||
|
|
||||||
class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing() {
|
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 =
|
private fun KtNamedFunction.hasOverrides(): Boolean =
|
||||||
toLightMethods().singleOrNull()?.let { lightMethod ->
|
toLightMethods().singleOrNull()?.let { lightMethod ->
|
||||||
OverridingMethodsSearch.search(lightMethod).findFirst()
|
if (OverridingMethodsSearch.search(lightMethod).findFirst() != null) return@let true
|
||||||
} != null
|
if (elements.size == 1) return@let false
|
||||||
|
elements.any { element ->
|
||||||
|
OverridingMethodsSearch.search(lightMethod, LocalSearchScope(element), true).findFirst() != null
|
||||||
|
}
|
||||||
|
} == true
|
||||||
|
|
||||||
private fun KtNamedFunction.hasSuperFunction(): Boolean =
|
private fun KtNamedFunction.hasSuperFunction(): Boolean =
|
||||||
resolveToDescriptorIfAny()?.original?.overriddenDescriptors?.isNotEmpty() == true
|
resolveToDescriptorIfAny(resolutionFacade)?.original?.overriddenDescriptors?.isNotEmpty() == true
|
||||||
|
|
||||||
private fun KtNamedFunction.hasInvalidSuperDescriptors(): Boolean =
|
private fun KtNamedFunction.hasInvalidSuperDescriptors(): Boolean =
|
||||||
resolveToDescriptorIfAny()
|
resolveToDescriptorIfAny(resolutionFacade)
|
||||||
?.original
|
?.original
|
||||||
?.overriddenDescriptors
|
?.overriddenDescriptors
|
||||||
?.any { it.isJavaDescriptor || it is FunctionDescriptor } == true
|
?.any { it.isJavaDescriptor || it is FunctionDescriptor } == true
|
||||||
@@ -216,7 +263,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun KtElement.usages() =
|
private fun KtElement.usages() =
|
||||||
ReferencesSearch.search(this, LocalSearchScope(containingKtFile))
|
searcher.search(this)
|
||||||
|
|
||||||
private fun <T : KtExpression> T.withReplacedExpressionInBody(
|
private fun <T : KtExpression> T.withReplacedExpressionInBody(
|
||||||
from: KtElement,
|
from: KtElement,
|
||||||
@@ -249,7 +296,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
|
|
||||||
val sorted = mutableListOf<KtClassOrObject>()
|
val sorted = mutableListOf<KtClassOrObject>()
|
||||||
val visited = Array(size) { false }
|
val visited = Array(size) { false }
|
||||||
val descriptors = map { it.resolveToDescriptorIfAny()!! }
|
val descriptors = map { it.resolveToDescriptorIfAny(resolutionFacade)!! }
|
||||||
val descriptorToIndex = descriptors.mapToIndex()
|
val descriptorToIndex = descriptors.mapToIndex()
|
||||||
val outers = descriptors.map { descriptor ->
|
val outers = descriptors.map { descriptor ->
|
||||||
descriptor.superClassAndSuperInterfaces().mapNotNull { descriptorToIndex[it] }
|
descriptor.superClassAndSuperInterfaces().mapNotNull { descriptorToIndex[it] }
|
||||||
@@ -273,25 +320,6 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
return sorted
|
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 =
|
private fun causesNameConflictInCurrentDeclarationAndItsParents(name: String, declaration: DeclarationDescriptor?): Boolean =
|
||||||
when (declaration) {
|
when (declaration) {
|
||||||
is ClassDescriptor -> {
|
is ClassDescriptor -> {
|
||||||
@@ -310,27 +338,11 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun calculatePropertyType(getter: KtNamedFunction?, setter: KtNamedFunction?): KotlinType? {
|
private fun calculatePropertyType(getter: KtNamedFunction?, setter: KtNamedFunction?): KotlinType? {
|
||||||
val getterType = getter?.resolveToDescriptorIfAny()?.returnType
|
val getterType = getter?.resolveToDescriptorIfAny(resolutionFacade)?.returnType
|
||||||
val setterType = setter?.resolveToDescriptorIfAny()?.valueParameters?.singleOrNull()?.type
|
val setterType = setter?.resolveToDescriptorIfAny(resolutionFacade)?.valueParameters?.singleOrNull()?.type
|
||||||
return calculatePropertyType(getterType, setterType)
|
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> {
|
private fun KtClassOrObject.collectPropertiesData(collectingState: CollectingState): List<PropertyData> {
|
||||||
return declarations
|
return declarations
|
||||||
.asSequence()
|
.asSequence()
|
||||||
@@ -356,7 +368,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
val name = realGetter?.name ?: realSetter?.name!!
|
val name = realGetter?.name ?: realSetter?.name!!
|
||||||
|
|
||||||
val superDeclarationOwner = (realGetter?.function ?: realSetter?.function)
|
val superDeclarationOwner = (realGetter?.function ?: realSetter?.function)
|
||||||
?.resolveToDescriptorIfAny()
|
?.resolveToDescriptorIfAny(resolutionFacade)
|
||||||
?.overriddenDescriptors
|
?.overriddenDescriptors
|
||||||
?.firstOrNull()
|
?.firstOrNull()
|
||||||
?.findPsi()
|
?.findPsi()
|
||||||
@@ -378,7 +390,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
klass: KtClassOrObject,
|
klass: KtClassOrObject,
|
||||||
factory: KtPsiFactory
|
factory: KtPsiFactory
|
||||||
): List<PropertyWithAccessors> {
|
): List<PropertyWithAccessors> {
|
||||||
val classDescriptor = klass.resolveToDescriptorIfAny() ?: return emptyList()
|
val classDescriptor = klass.resolveToDescriptorIfAny(resolutionFacade) ?: return emptyList()
|
||||||
|
|
||||||
val variablesDescriptorsMap =
|
val variablesDescriptorsMap =
|
||||||
(listOfNotNull(classDescriptor.getSuperClassNotAny()) + classDescriptor.getSuperInterfaces())
|
(listOfNotNull(classDescriptor.getSuperClassNotAny()) + classDescriptor.getSuperInterfaces())
|
||||||
@@ -462,7 +474,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
|
|
||||||
|
|
||||||
val getter = realGetter ?: when {
|
val getter = realGetter ?: when {
|
||||||
realProperty?.property?.resolveToDescriptorIfAny()?.overriddenDescriptors?.any {
|
realProperty?.property?.resolveToDescriptorIfAny(resolutionFacade)?.overriddenDescriptors?.any {
|
||||||
it.safeAs<VariableDescriptor>()?.isVar == true
|
it.safeAs<VariableDescriptor>()?.isVar == true
|
||||||
} == true -> FakeGetter(name, null, "")
|
} == true -> FakeGetter(name, null, "")
|
||||||
|
|
||||||
@@ -487,7 +499,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
realProperty?.property?.isVar == true ->
|
realProperty?.property?.isVar == true ->
|
||||||
FakeSetter(name, null, "")
|
FakeSetter(name, null, "")
|
||||||
|
|
||||||
realProperty?.property?.resolveToDescriptorIfAny()?.overriddenDescriptors?.any {
|
realProperty?.property?.resolveToDescriptorIfAny(resolutionFacade)?.overriddenDescriptors?.any {
|
||||||
it.safeAs<VariableDescriptor>()?.isVar == true
|
it.safeAs<VariableDescriptor>()?.isVar == true
|
||||||
} == true
|
} == true
|
||||||
|| variablesDescriptorsMap[name]?.isVar == true ->
|
|| variablesDescriptorsMap[name]?.isVar == true ->
|
||||||
@@ -523,7 +535,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun KtProperty.renameTo(newName: String, factory: KtPsiFactory) {
|
private fun KtProperty.renameTo(newName: String, factory: KtPsiFactory) {
|
||||||
for (usage in usages().toList()) {
|
for (usage in usages()) {
|
||||||
val element = usage.element
|
val element = usage.element
|
||||||
val isBackingField = element is KtNameReferenceExpression
|
val isBackingField = element is KtNameReferenceExpression
|
||||||
&& element.text == KtTokens.FIELD_KEYWORD.value
|
&& element.text == KtTokens.FIELD_KEYWORD.value
|
||||||
@@ -540,8 +552,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing
|
|||||||
|
|
||||||
private fun convertClass(
|
private fun convertClass(
|
||||||
klass: KtClassOrObject,
|
klass: KtClassOrObject,
|
||||||
propertiesData: List<PropertyData>,
|
propertiesData: List<PropertyData>
|
||||||
externalCodeUpdater: NewExternalCodeProcessing
|
|
||||||
) {
|
) {
|
||||||
val factory = KtPsiFactory(klass)
|
val factory = KtPsiFactory(klass)
|
||||||
val accessors = propertiesData.filterGettersAndSetters(klass, factory)
|
val accessors = propertiesData.filterGettersAndSetters(klass, factory)
|
||||||
|
|||||||
+10
-14
@@ -5,9 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.postProcessing.processings
|
package org.jetbrains.kotlin.nj2k.postProcessing.processings
|
||||||
|
|
||||||
import com.intellij.openapi.editor.RangeMarker
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
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.common.collectors.FunctionConstraintsCollector
|
||||||
import org.jetbrains.kotlin.nj2k.inference.mutability.*
|
import org.jetbrains.kotlin.nj2k.inference.mutability.*
|
||||||
import org.jetbrains.kotlin.nj2k.inference.nullability.*
|
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.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
|
||||||
|
|
||||||
abstract class InferenceProcessing : GeneralPostProcessing {
|
abstract class InferenceProcessing : ElementsBasedPostProcessing() {
|
||||||
final override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
override fun runProcessing(elements: List<PsiElement>, converterContext: NewJ2kConverterContext) {
|
||||||
val elements = if (rangeMarker != null) {
|
val kotlinElements = elements.filterIsInstance<KtElement>()
|
||||||
val range = rangeMarker.range ?: return
|
val resolutionFacade = runReadAction {
|
||||||
runReadAction { file.elementsInRange(range) }.filterIsInstance<KtElement>()
|
KotlinCacheService.getInstance(converterContext.project).getResolutionFacade(kotlinElements)
|
||||||
} else listOf(file)
|
}
|
||||||
val resolutionFacade = runReadAction { file.getResolutionFacade() }
|
createInferenceFacade(resolutionFacade, converterContext).runOn(kotlinElements)
|
||||||
createInferenceFacade(resolutionFacade, converterContext).runOn(elements)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun createInferenceFacade(
|
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.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.nj2k.JKImportStorage
|
import org.jetbrains.kotlin.nj2k.JKImportStorage
|
||||||
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
|
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.GeneralPostProcessing
|
||||||
import org.jetbrains.kotlin.nj2k.postProcessing.runUndoTransparentActionInEdt
|
import org.jetbrains.kotlin.nj2k.postProcessing.runUndoTransparentActionInEdt
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
import org.jetbrains.kotlin.psi.KtQualifiedExpression
|
||||||
|
|
||||||
class ShortenReferenceProcessing : GeneralPostProcessing {
|
class ShortenReferenceProcessing : FileBasedPostProcessing() {
|
||||||
private val filter = filter@{ element: PsiElement ->
|
private val filter = filter@{ element: PsiElement ->
|
||||||
when (element) {
|
when (element) {
|
||||||
is KtQualifiedExpression -> when {
|
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) {
|
runUndoTransparentActionInEdt(inWriteAction = false) {
|
||||||
if (rangeMarker != null) {
|
if (rangeMarker != null) {
|
||||||
if (rangeMarker.isValid) {
|
if (rangeMarker.isValid) {
|
||||||
|
|||||||
+20
-15
@@ -13,16 +13,19 @@ import com.intellij.psi.PsiElementVisitor
|
|||||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
import org.jetbrains.kotlin.idea.core.util.range
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
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.NewJ2kConverterContext
|
||||||
import org.jetbrains.kotlin.nj2k.asLabel
|
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.GeneralPostProcessing
|
||||||
import org.jetbrains.kotlin.nj2k.postProcessing.runUndoTransparentActionInEdt
|
import org.jetbrains.kotlin.nj2k.postProcessing.runUndoTransparentActionInEdt
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||||
|
|
||||||
|
|
||||||
class FormatCodeProcessing : GeneralPostProcessing {
|
class FormatCodeProcessing : FileBasedPostProcessing() {
|
||||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||||
val codeStyleManager = CodeStyleManager.getInstance(file.project)
|
val codeStyleManager = CodeStyleManager.getInstance(file.project)
|
||||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||||
if (rangeMarker != null) {
|
if (rangeMarker != null) {
|
||||||
@@ -38,28 +41,30 @@ class FormatCodeProcessing : GeneralPostProcessing {
|
|||||||
|
|
||||||
|
|
||||||
class ClearUnknownLabelsProcessing : GeneralPostProcessing {
|
class ClearUnknownLabelsProcessing : GeneralPostProcessing {
|
||||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
override fun runProcessing(target: JKPostProcessingTarget, converterContext: NewJ2kConverterContext) {
|
||||||
val comments = mutableListOf<PsiComment>()
|
val comments = mutableListOf<PsiComment>()
|
||||||
runUndoTransparentActionInEdt(inWriteAction = true) {
|
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||||
file.accept(object : PsiElementVisitor() {
|
target.elements().forEach { element ->
|
||||||
override fun visitElement(element: PsiElement) {
|
element.accept(object : PsiElementVisitor() {
|
||||||
element.acceptChildren(this)
|
override fun visitElement(element: PsiElement) {
|
||||||
}
|
element.acceptChildren(this)
|
||||||
|
|
||||||
override fun visitComment(comment: PsiComment) {
|
|
||||||
if (comment.text.asLabel() != null) {
|
|
||||||
comments += comment
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
override fun visitComment(comment: PsiComment) {
|
||||||
|
if (comment.text.asLabel() != null) {
|
||||||
|
comments += comment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
comments.forEach { it.delete() }
|
comments.forEach { it.delete() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class OptimizeImportsProcessing : GeneralPostProcessing {
|
class OptimizeImportsProcessing : FileBasedPostProcessing() {
|
||||||
override fun runProcessing(file: KtFile, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
override fun runProcessing(file: KtFile, allFiles: List<KtFile>, rangeMarker: RangeMarker?, converterContext: NewJ2kConverterContext) {
|
||||||
val elements = runReadAction {
|
val elements = runReadAction {
|
||||||
when {
|
when {
|
||||||
rangeMarker != null && rangeMarker.isValid -> file.elementsInRange(rangeMarker.range!!)
|
rangeMarker != null && rangeMarker.isValid -> file.elementsInRange(rangeMarker.range!!)
|
||||||
|
|||||||
@@ -17,10 +17,8 @@
|
|||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException
|
|
||||||
import com.intellij.openapi.progress.ProgressIndicator
|
import com.intellij.openapi.progress.ProgressIndicator
|
||||||
import com.intellij.openapi.progress.ProgressManager
|
import com.intellij.openapi.progress.ProgressManager
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
@@ -28,7 +26,6 @@ import com.intellij.openapi.util.Computable
|
|||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|
||||||
import org.jetbrains.kotlin.j2k.*
|
import org.jetbrains.kotlin.j2k.*
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.nj2k.conversions.JKResolver
|
import org.jetbrains.kotlin.nj2k.conversions.JKResolver
|
||||||
@@ -68,36 +65,27 @@ class NewJavaToKotlinConverter(
|
|||||||
elementsToKotlin(files, withProgressProcessor)
|
elementsToKotlin(files, withProgressProcessor)
|
||||||
})
|
})
|
||||||
|
|
||||||
val texts = results.mapIndexed { i, result ->
|
val kotlinFiles = results.mapIndexed { i, result ->
|
||||||
try {
|
runUndoTransparentActionInEdt(inWriteAction = true) {
|
||||||
val kotlinFile = ApplicationManager.getApplication().runReadAction(Computable {
|
val javaFile = files[i]
|
||||||
KtPsiFactory(project).createFileWithLightClassSupport("dummy.kt", result!!.text, files[i])
|
KtPsiFactory(project).createFileWithLightClassSupport(
|
||||||
})
|
javaFile.name.replace(".java", ".kt"),
|
||||||
|
result!!.text,
|
||||||
ApplicationManager.getApplication().invokeAndWait {
|
files[i]
|
||||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
).apply {
|
||||||
runWriteAction {
|
addImports(result.importsToAdd)
|
||||||
kotlinFile.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)
|
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?.checkCanceled()
|
||||||
progress?.fraction = phase / phasesCount.toDouble()
|
progress?.fraction = phase / phasesCount.toDouble()
|
||||||
progress?.text = "$description - phase $phase of $phasesCount"
|
progress?.text = "$description - phase $phase of $phasesCount"
|
||||||
if (files != null && files.isNotEmpty()) {
|
progress?.text2 = when {
|
||||||
progress?.text2 = files[fileIndex].virtualFile.presentableUrl
|
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.codeInsight.generation.GenerateEqualsHelper.getEqualsSignature
|
||||||
import com.intellij.lang.jvm.JvmClassKind
|
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.*
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.InheritanceUtil
|
import com.intellij.psi.util.InheritanceUtil
|
||||||
import com.intellij.psi.util.MethodSignatureUtil
|
import com.intellij.psi.util.MethodSignatureUtil
|
||||||
import com.intellij.psi.util.PsiUtil
|
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.ClassKind
|
||||||
import org.jetbrains.kotlin.j2k.ReferenceSearcher
|
import org.jetbrains.kotlin.j2k.ReferenceSearcher
|
||||||
import org.jetbrains.kotlin.j2k.isNullLiteral
|
import org.jetbrains.kotlin.j2k.isNullLiteral
|
||||||
@@ -141,3 +144,16 @@ val KtDeclaration.fqNameWithoutCompanions
|
|||||||
.filter { it.safeAs<KtObjectDeclaration>()?.isCompanion() != true && it.name != null }
|
.filter { it.safeAs<KtObjectDeclaration>()?.isCompanion() != true && it.name != null }
|
||||||
.toList()
|
.toList()
|
||||||
.foldRight(containingKtFile.packageFqName) { container, acc -> acc.child(Name.identifier(container.name!!)) }
|
.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
|
psiManager.findFile(virtualFile) as PsiJavaFile
|
||||||
}
|
}
|
||||||
|
|
||||||
val externalFiles = File(dirPath + File.separator + "external").listFiles { _, name ->
|
val externalFiles = File(dirPath + File.separator + "external")
|
||||||
name.endsWith(".java") || name.endsWith(".kt")
|
.takeIf { it.exists() }
|
||||||
}!!
|
?.listFiles { _, name ->
|
||||||
|
name.endsWith(".java") || name.endsWith(".kt")
|
||||||
|
}.orEmpty()
|
||||||
|
|
||||||
val externalPsiFiles = externalFiles.map { file ->
|
val externalPsiFiles = externalFiles.map { file ->
|
||||||
val virtualFile = addFile(file, "test")
|
val virtualFile = addFile(file, "test")
|
||||||
|
|||||||
+10
@@ -34,6 +34,11 @@ public class NewJavaToKotlinConverterMultiFileTestGenerated extends AbstractNewJ
|
|||||||
runTest("nj2k/testData/multiFile/AnnotationWithArrayParameter/");
|
runTest("nj2k/testData/multiFile/AnnotationWithArrayParameter/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("DetectPropertiesMultipleFiles")
|
||||||
|
public void testDetectPropertiesMultipleFiles() throws Exception {
|
||||||
|
runTest("nj2k/testData/multiFile/DetectPropertiesMultipleFiles/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("FieldToProperty")
|
@TestMetadata("FieldToProperty")
|
||||||
public void testFieldToProperty() throws Exception {
|
public void testFieldToProperty() throws Exception {
|
||||||
runTest("nj2k/testData/multiFile/FieldToProperty/");
|
runTest("nj2k/testData/multiFile/FieldToProperty/");
|
||||||
@@ -49,6 +54,11 @@ public class NewJavaToKotlinConverterMultiFileTestGenerated extends AbstractNewJ
|
|||||||
runTest("nj2k/testData/multiFile/GetterAndSetterUsages/");
|
runTest("nj2k/testData/multiFile/GetterAndSetterUsages/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("InterfaceWithGetterInOtherFile")
|
||||||
|
public void testInterfaceWithGetterInOtherFile() throws Exception {
|
||||||
|
runTest("nj2k/testData/multiFile/InterfaceWithGetterInOtherFile/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("KT11952")
|
@TestMetadata("KT11952")
|
||||||
public void testKT11952() throws Exception {
|
public void testKT11952() throws Exception {
|
||||||
runTest("nj2k/testData/multiFile/KT11952/");
|
runTest("nj2k/testData/multiFile/KT11952/");
|
||||||
|
|||||||
Reference in New Issue
Block a user