diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt index 3338fa266ba..1b4d9b0ff58 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessings.kt @@ -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 get() = _processings + private val processingsToPriorityMap = HashMap() + + fun priority(processing: J2kPostProcessing): Int { + return processingsToPriorityMap[processing]!! + } + init { _processings.add(RemoveExplicitTypeArgumentsProcessing()) _processings.add(RemoveRedundantOverrideVisibilityProcessing()) @@ -111,18 +118,13 @@ object J2KPostProcessingRegistrar { } } } - } - private inline fun > registerIntentionBasedProcessing( - intention: TIntention - ) { - //TODO: replace with optional argument when supported for inline functions - return registerIntentionBasedProcessing(intention, { true }) + processingsToPriorityMap.putAll(_processings.mapToIndex()) } private inline fun > registerIntentionBasedProcessing( intention: TIntention, - noinline additionalChecker: (TElement) -> Boolean + noinline additionalChecker: (TElement) -> Boolean = { true } ) { _processings.add(object : J2kPostProcessing { override fun createAction(element: KtElement, diagnostics: Diagnostics): (() -> Unit)? { diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessor.kt index 29c532012a6..a2914217b92 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/J2kPostProcessor.kt @@ -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> { + private fun collectAvailableActions(file: KtFile, rangeMarker: RangeMarker?): List { val diagnostics = analyzeFileRange(file, rangeMarker) - val elementToActions = LinkedHashMap>() + val availableActions = ArrayList() - 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 { diff --git a/j2k/testData/multiFile/FunctionalInterfaceAcceptor/Stage.java b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/Stage.java new file mode 100644 index 00000000000..6a4d7020eb4 --- /dev/null +++ b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/Stage.java @@ -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); + } + }); + } +} \ No newline at end of file diff --git a/j2k/testData/multiFile/FunctionalInterfaceAcceptor/Stage.kt b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/Stage.kt new file mode 100644 index 00000000000..1c572c6195c --- /dev/null +++ b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/Stage.kt @@ -0,0 +1,8 @@ +package test + +class Stage { + fun context(acceptor: Acceptor) { + acceptor.acceptFace { p -> println(p) } + acceptor.face = Face { p -> println(p) } + } +} \ No newline at end of file diff --git a/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Acceptor.java b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Acceptor.java new file mode 100644 index 00000000000..c4a1def418d --- /dev/null +++ b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Acceptor.java @@ -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) {} +} \ No newline at end of file diff --git a/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Acceptor.java.expected b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Acceptor.java.expected new file mode 100644 index 00000000000..c4a1def418d --- /dev/null +++ b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Acceptor.java.expected @@ -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) {} +} \ No newline at end of file diff --git a/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Face.java b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Face.java new file mode 100644 index 00000000000..fd9cd819b05 --- /dev/null +++ b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Face.java @@ -0,0 +1,4 @@ +package test; +public interface Face { + void subject(String p); +} \ No newline at end of file diff --git a/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Face.java.expected b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Face.java.expected new file mode 100644 index 00000000000..fd9cd819b05 --- /dev/null +++ b/j2k/testData/multiFile/FunctionalInterfaceAcceptor/external/Face.java.expected @@ -0,0 +1,4 @@ +package test; +public interface Face { + void subject(String p); +} \ No newline at end of file diff --git a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterMultiFileTestGenerated.java b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterMultiFileTestGenerated.java index 5a2beb8e7f3..8c3cb1af613 100644 --- a/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterMultiFileTestGenerated.java +++ b/j2k/tests/org/jetbrains/kotlin/j2k/JavaToKotlinConverterMultiFileTestGenerated.java @@ -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/");