diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 394f16ff2a7..a2a1aac3eef 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -207,6 +207,9 @@
implementation="org.jetbrains.jet.plugin.refactoring.move.moveTopLevelDeclarations.MoveKotlinTopLevelDeclarationsHandler"
order="before kotlin.moveFilesOrDirectories"/>
+
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt
new file mode 100644
index 00000000000..8ad7fb341d7
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/move/MoveJavaInnerClassKotlinUsagesHandler.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.jet.plugin.refactoring.move
+
+import com.intellij.refactoring.move.moveInner.MoveInnerClassUsagesHandler
+import com.intellij.usageView.UsageInfo
+import com.intellij.psi.PsiClass
+import org.jetbrains.jet.lang.psi.JetQualifiedExpression
+import org.jetbrains.jet.lang.psi.psiUtil.getQualifiedElementSelector
+import org.jetbrains.jet.lang.psi.JetReferenceExpression
+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
+import org.jetbrains.jet.lang.resolve.BindingContext
+import org.jetbrains.jet.lang.psi.JetCallExpression
+import org.jetbrains.jet.lang.psi.JetPsiFactory
+import java.util.Collections
+import java.util.ArrayList
+import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
+import com.intellij.psi.util.PsiTreeUtil
+import com.intellij.psi.PsiWhiteSpace
+
+public class MoveJavaInnerClassKotlinUsagesHandler: MoveInnerClassUsagesHandler {
+ override fun correctInnerClassUsage(usage: UsageInfo, outerClass: PsiClass) {
+ val innerCall = usage.getElement()?.getParent() as? JetCallExpression
+ if (innerCall == null) return
+
+ val receiver = (innerCall.getParent() as? JetQualifiedExpression)?.getReceiverExpression()
+ val outerClassRef = when (receiver) {
+ is JetCallExpression -> receiver.getCalleeExpression()
+ is JetQualifiedExpression -> receiver.getQualifiedElementSelector()
+ else -> null
+ } as? JetSimpleNameExpression
+ if (outerClassRef?.getReference()?.resolve() != outerClass) return
+
+ val outerCall = outerClassRef!!.getParent() as? JetCallExpression
+ if (outerCall == null) return
+
+ val psiFactory = JetPsiFactory(usage.getProject())
+
+ val argumentList = innerCall.getValueArgumentList()
+ if (argumentList != null) {
+ val newArguments = ArrayList()
+ newArguments.add(outerCall.getText()!!)
+ argumentList.getArguments().mapTo(newArguments) { it.getText()!! }
+ argumentList.replace(psiFactory.createCallArguments(newArguments.joinToString(prefix = "(", postfix = ")")))
+ }
+ else {
+ innerCall.getFunctionLiteralArguments().firstOrNull()?.let { lambdaArg ->
+ val anchor = PsiTreeUtil.skipSiblingsBackward(lambdaArg, javaClass())
+ innerCall.addAfter(psiFactory.createCallArguments("(${outerCall.getText()})"), anchor)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance.test_todo b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance.test
similarity index 100%
rename from idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance.test_todo
rename to idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance.test
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/X.java b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/X.java
new file mode 100644
index 00000000000..aadb4fa2a30
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/X.java
@@ -0,0 +1,12 @@
+package a;
+
+import kotlin.Function0;
+
+public class X {
+ private A outer;
+
+ public X(A outer, Function0 f) {
+ this.outer = outer;
+ System.out.println(f.invoke());
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/main.java b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/main.java
new file mode 100644
index 00000000000..af2554f460e
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/main.java
@@ -0,0 +1,6 @@
+package a;
+
+import kotlin.Function0;
+
+public class A {
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/noImports.kt b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/noImports.kt
new file mode 100644
index 00000000000..8eb18554713
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/noImports.kt
@@ -0,0 +1,5 @@
+package a
+
+fun bar(s: String) {
+ val t: X = X(A()) { s }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/onDemandImport.kt b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/onDemandImport.kt
new file mode 100644
index 00000000000..d0cd1a55579
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/onDemandImport.kt
@@ -0,0 +1,7 @@
+package a
+
+import a.A.*
+
+fun bar(s: String) {
+ val t: X = X(A()) { s }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/specificImport.kt b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/specificImport.kt
new file mode 100644
index 00000000000..6ef143a0921
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/after/a/specificImport.kt
@@ -0,0 +1,7 @@
+package a
+
+import a.X
+
+fun bar(s: String) {
+ val t: X = X(A()) { s }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/main.java b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/main.java
new file mode 100644
index 00000000000..1755e2b24d4
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/main.java
@@ -0,0 +1,11 @@
+package a;
+
+import kotlin.Function0;
+
+public class A {
+ public class X {
+ public X(Function0 f) {
+ System.out.println(f.invoke());
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/noImports.kt b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/noImports.kt
new file mode 100644
index 00000000000..65e0495fb70
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/noImports.kt
@@ -0,0 +1,5 @@
+package a
+
+fun bar(s: String) {
+ val t: A.X = A().X { s }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/onDemandImport.kt b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/onDemandImport.kt
new file mode 100644
index 00000000000..ec801813c17
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/onDemandImport.kt
@@ -0,0 +1,7 @@
+package a
+
+import a.A.*
+
+fun bar(s: String) {
+ val t: X = A().X { s }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/specificImport.kt b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/specificImport.kt
new file mode 100644
index 00000000000..255ce5532a3
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/before/a/specificImport.kt
@@ -0,0 +1,7 @@
+package a
+
+import a.A.X
+
+fun bar(s: String) {
+ val t: X = A().X { s }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda.test b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda.test
new file mode 100644
index 00000000000..3979ef41e5b
--- /dev/null
+++ b/idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda.test
@@ -0,0 +1,7 @@
+{
+ "mainFile": "a/main.java",
+ "type": "MOVE_INNER_CLASS",
+ "targetPackage": "a",
+ "outerInstanceParameterName": "outer",
+ "withRuntime": "true"
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/move/AbstractJetMoveTest.kt b/idea/tests/org/jetbrains/jet/plugin/refactoring/move/AbstractJetMoveTest.kt
index 91de20d82d0..1c51314513c 100644
--- a/idea/tests/org/jetbrains/jet/plugin/refactoring/move/AbstractJetMoveTest.kt
+++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/move/AbstractJetMoveTest.kt
@@ -59,6 +59,8 @@ import org.jetbrains.jet.plugin.refactoring.move.moveTopLevelDeclarations.JetFil
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.plugin.search.allScope
import org.jetbrains.jet.plugin.refactoring.runWriteAction
+import org.jetbrains.jet.InTextDirectivesUtils
+import org.jetbrains.jet.testing.ConfigLibraryUtil
public abstract class AbstractJetMoveTest : MultiFileTestCase() {
protected fun doTest(path: String) {
@@ -78,6 +80,10 @@ public abstract class AbstractJetMoveTest : MultiFileTestCase() {
val config = JsonParser().parse(FileUtil.loadFile(File(path), true)) as JsonObject
+ if (config["withRuntime"]?.getAsBoolean() ?: false) {
+ ConfigLibraryUtil.configureKotlinRuntime(myModule, PluginTestCaseBase.fullJdk())
+ }
+
val action = MoveAction.valueOf(config.getString("type"))
val testDir = path.substring(0, path.lastIndexOf("/"))
diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/move/JetMoveTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/move/JetMoveTestGenerated.java
index 8950bd91e7e..a35730169cd 100644
--- a/idea/tests/org/jetbrains/jet/plugin/refactoring/move/JetMoveTestGenerated.java
+++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/move/JetMoveTestGenerated.java
@@ -86,6 +86,18 @@ public class JetMoveTestGenerated extends AbstractJetMoveTest {
doTest(fileName);
}
+ @TestMetadata("java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance.test")
+ public void testJava_moveClass_moveInnerToTop_moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance_MoveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstance.test");
+ doTest(fileName);
+ }
+
+ @TestMetadata("java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda.test")
+ public void testJava_moveClass_moveInnerToTop_moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda_MoveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda/moveNestedClassToTopLevelInTheSamePackageAndAddOuterInstanceWithLambda.test");
+ doTest(fileName);
+ }
+
@TestMetadata("java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndRename/moveNestedClassToTopLevelInTheSamePackageAndRename.test")
public void testJava_moveClass_moveInnerToTop_moveNestedClassToTopLevelInTheSamePackageAndRename_MoveNestedClassToTopLevelInTheSamePackageAndRename() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/move/java/moveClass/moveInnerToTop/moveNestedClassToTopLevelInTheSamePackageAndRename/moveNestedClassToTopLevelInTheSamePackageAndRename.test");