Fix for KT-12677. J2K: Invalid SAM constructor redundancy detection
Now all J2kPostProcessing's executing in fixed order, dependent on it index in J2kPostProcessingRegistrar._processings
This commit is contained in:
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
||||
import org.jetbrains.kotlin.utils.mapToIndex
|
||||
import java.util.*
|
||||
|
||||
interface J2kPostProcessing {
|
||||
@@ -49,6 +50,12 @@ object J2KPostProcessingRegistrar {
|
||||
val processings: Collection<J2kPostProcessing>
|
||||
get() = _processings
|
||||
|
||||
private val processingsToPriorityMap = HashMap<J2kPostProcessing, Int>()
|
||||
|
||||
fun priority(processing: J2kPostProcessing): Int {
|
||||
return processingsToPriorityMap[processing]!!
|
||||
}
|
||||
|
||||
init {
|
||||
_processings.add(RemoveExplicitTypeArgumentsProcessing())
|
||||
_processings.add(RemoveRedundantOverrideVisibilityProcessing())
|
||||
@@ -111,18 +118,13 @@ object J2KPostProcessingRegistrar {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified TElement : KtElement, TIntention: SelfTargetingRangeIntention<TElement>> registerIntentionBasedProcessing(
|
||||
intention: TIntention
|
||||
) {
|
||||
//TODO: replace with optional argument when supported for inline functions
|
||||
return registerIntentionBasedProcessing<TElement, TIntention>(intention, { true })
|
||||
processingsToPriorityMap.putAll(_processings.mapToIndex())
|
||||
}
|
||||
|
||||
private inline fun <reified TElement : KtElement, TIntention: SelfTargetingRangeIntention<TElement>> registerIntentionBasedProcessing(
|
||||
intention: TIntention,
|
||||
noinline additionalChecker: (TElement) -> Boolean
|
||||
noinline additionalChecker: (TElement) -> Boolean = { true }
|
||||
) {
|
||||
_processings.add(object : J2kPostProcessing {
|
||||
override fun createAction(element: KtElement, diagnostics: Diagnostics): (() -> Unit)? {
|
||||
|
||||
@@ -21,9 +21,6 @@ import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiRecursiveElementVisitor
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager
|
||||
import com.intellij.psi.impl.PsiModificationTrackerImpl
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.range
|
||||
@@ -54,14 +51,12 @@ class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
||||
while (elementToActions.isNotEmpty()) {
|
||||
var modificationStamp: Long? = file.modificationStamp
|
||||
|
||||
for ((element, actions) in elementToActions) {
|
||||
for ((action, processing) in actions) {
|
||||
if (element.isValid) {
|
||||
action()
|
||||
}
|
||||
else {
|
||||
modificationStamp = null
|
||||
}
|
||||
for ((element, action, processing) in elementToActions) {
|
||||
if (element.isValid) {
|
||||
action()
|
||||
}
|
||||
else {
|
||||
modificationStamp = null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,14 +78,14 @@ class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private data class ActionData(val action: () -> Unit, val processing: J2kPostProcessing)
|
||||
private data class ActionData(val element: KtElement, val action: () -> Unit, val priority: Int)
|
||||
|
||||
private fun collectAvailableActions(file: KtFile, rangeMarker: RangeMarker?): LinkedHashMap<KtElement, SmartList<ActionData>> {
|
||||
private fun collectAvailableActions(file: KtFile, rangeMarker: RangeMarker?): List<ActionData> {
|
||||
val diagnostics = analyzeFileRange(file, rangeMarker)
|
||||
|
||||
val elementToActions = LinkedHashMap<KtElement, SmartList<ActionData>>()
|
||||
val availableActions = ArrayList<ActionData>()
|
||||
|
||||
file.accept(object : PsiRecursiveElementVisitor(){
|
||||
file.accept(object : PsiRecursiveElementVisitor() {
|
||||
override fun visitElement(element: PsiElement) {
|
||||
if (element is KtElement) {
|
||||
val rangeResult = rangeFilter(element, rangeMarker)
|
||||
@@ -102,15 +97,15 @@ class J2kPostProcessor(private val formatCode: Boolean) : PostProcessor {
|
||||
J2KPostProcessingRegistrar.processings.forEach { processing ->
|
||||
val action = processing.createAction(element, diagnostics)
|
||||
if (action != null) {
|
||||
elementToActions.getOrPut(element) { SmartList() }.add(ActionData(action, processing))
|
||||
availableActions.add(ActionData(element, action, J2KPostProcessingRegistrar.priority(processing)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return elementToActions
|
||||
availableActions.sortBy { it.priority }
|
||||
return availableActions
|
||||
}
|
||||
|
||||
private fun analyzeFileRange(file: KtFile, rangeMarker: RangeMarker?): Diagnostics {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package test;
|
||||
public class Stage {
|
||||
public void context(Acceptor acceptor) {
|
||||
acceptor.acceptFace(new Face() {
|
||||
@Override public void subject(String p) {
|
||||
System.out.println(p);
|
||||
}
|
||||
});
|
||||
acceptor.setFace(new Face() {
|
||||
@Override public void subject(String p) {
|
||||
System.out.println(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test
|
||||
|
||||
class Stage {
|
||||
fun context(acceptor: Acceptor) {
|
||||
acceptor.acceptFace { p -> println(p) }
|
||||
acceptor.face = Face { p -> println(p) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package test;
|
||||
public class Acceptor {
|
||||
private Face face;
|
||||
public Face getFace() { return face; }
|
||||
public void setFace(Face face) { this.face = face; }
|
||||
|
||||
public void acceptFace(Face face) {}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package test;
|
||||
public class Acceptor {
|
||||
private Face face;
|
||||
public Face getFace() { return face; }
|
||||
public void setFace(Face face) { this.face = face; }
|
||||
|
||||
public void acceptFace(Face face) {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package test;
|
||||
public interface Face {
|
||||
void subject(String p);
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package test;
|
||||
public interface Face {
|
||||
void subject(String p);
|
||||
}
|
||||
@@ -47,6 +47,12 @@ public class JavaToKotlinConverterMultiFileTestGenerated extends AbstractJavaToK
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionalInterfaceAcceptor")
|
||||
public void testFunctionalInterfaceAcceptor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/multiFile/FunctionalInterfaceAcceptor/");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GetterAndSetterUsages")
|
||||
public void testGetterAndSetterUsages() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("j2k/testData/multiFile/GetterAndSetterUsages/");
|
||||
|
||||
Reference in New Issue
Block a user