diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 8a6b0fd0bfe..0d994df117e 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -131,7 +131,7 @@ - + diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/inline/KotlinInlineLocalHandler.java b/idea/src/org/jetbrains/jet/plugin/refactoring/inline/KotlinInlineValHandler.java similarity index 85% rename from idea/src/org/jetbrains/jet/plugin/refactoring/inline/KotlinInlineLocalHandler.java rename to idea/src/org/jetbrains/jet/plugin/refactoring/inline/KotlinInlineValHandler.java index bc296fe9122..211de62d46e 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/inline/KotlinInlineLocalHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/inline/KotlinInlineValHandler.java @@ -51,7 +51,7 @@ import org.jetbrains.jet.renderer.DescriptorRenderer; import java.util.*; -public class KotlinInlineLocalHandler extends InlineActionHandler { +public class KotlinInlineValHandler extends InlineActionHandler { @Override public boolean isEnabledForLanguage(Language l) { return l.equals(JetLanguage.INSTANCE); @@ -63,25 +63,24 @@ public class KotlinInlineLocalHandler extends InlineActionHandler { return false; } JetProperty property = (JetProperty) element; - return !property.isVar(); + return !property.isVar() && property.getGetter() == null && property.getReceiverTypeRef() == null; } @Override - public void inlineElement(Project project, final Editor editor, PsiElement element) { + public void inlineElement(final Project project, final Editor editor, PsiElement element) { final JetProperty val = (JetProperty) element; String name = val.getName(); JetExpression initializerInDeclaration = val.getInitializer(); - final Collection references = ReferencesSearch.search(val, GlobalSearchScope.allScope(project), false).findAll(); + final List referenceExpressions = findReferenceExpressions(val); final Set assignments = Sets.newHashSet(); - for (PsiReference ref : references) { - PsiElement refElement = ref.getElement(); - PsiElement parent = refElement.getParent(); + for (JetExpression expression : referenceExpressions) { + PsiElement parent = expression.getParent(); if (parent instanceof JetBinaryExpression && ((JetBinaryExpression) parent).getOperationToken() == JetTokens.EQ && - ((JetBinaryExpression) parent).getLeft() == refElement) { + ((JetBinaryExpression) parent).getLeft() == expression) { assignments.add(parent); } } @@ -108,21 +107,13 @@ public class KotlinInlineLocalHandler extends InlineActionHandler { final String typeArgumentsForCall = getTypeArgumentsStringForCall(initializer); final String parametersForFunctionLiteral = getParametersForFunctionLiteral(initializer); - PsiReference[] referencesArray = references.toArray(references.toArray(new PsiReference[references.size()])); - - EditorColorsManager editorColorsManager = EditorColorsManager.getInstance(); - final TextAttributes searchResultsAttributes = editorColorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); - final HighlightManager highlightManager = HighlightManager.getInstance(project); - - if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) { - highlightManager.addOccurrenceHighlights(editor, referencesArray, searchResultsAttributes, true, null); - if (!showDialog(project, name, references)) { - StatusBar statusBar = WindowManager.getInstance().getStatusBar(project); - if (statusBar != null) { - statusBar.setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting")); - } - return; + highlightExpressions(project, editor, referenceExpressions); + if (!showDialog(project, name, referenceExpressions)) { + StatusBar statusBar = WindowManager.getInstance().getStatusBar(project); + if (statusBar != null) { + statusBar.setInfo(RefactoringBundle.message("press.escape.to.remove.the.highlighting")); } + return; } final List inlinedExpressions = Lists.newArrayList(); @@ -134,13 +125,12 @@ public class KotlinInlineLocalHandler extends InlineActionHandler { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - for (PsiReference reference : references) { - PsiElement referenceElement = reference.getElement(); - if (assignments.contains(referenceElement.getParent())) { + for (JetExpression referenceExpression : referenceExpressions) { + if (assignments.contains(referenceExpression.getParent())) { continue; } - inlinedExpressions.add(replaceExpression(referenceElement, initializer)); + inlinedExpressions.add(replaceExpression(referenceExpression, initializer)); } for (PsiElement assignment : assignments) { @@ -157,10 +147,7 @@ public class KotlinInlineLocalHandler extends InlineActionHandler { addFunctionLiteralParameterTypes(parametersForFunctionLiteral, inlinedExpressions); } - if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) { - highlightManager.addOccurrenceHighlights( - editor, inlinedExpressions.toArray(new PsiElement[inlinedExpressions.size()]), searchResultsAttributes, true, null); - } + highlightExpressions(project, editor, inlinedExpressions); } }); } @@ -169,11 +156,45 @@ public class KotlinInlineLocalHandler extends InlineActionHandler { null); } - private static boolean showDialog(Project project, String name, Collection references) { + private static void highlightExpressions(Project project, Editor editor, List elements) { + if (editor == null || ApplicationManager.getApplication().isUnitTestMode()) { + return; + } + EditorColorsManager editorColorsManager = EditorColorsManager.getInstance(); + TextAttributes searchResultsAttributes = editorColorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + HighlightManager highlightManager = HighlightManager.getInstance(project); + + PsiElement[] elementsArray = elements.toArray(new PsiElement[elements.size()]); + + highlightManager.addOccurrenceHighlights(editor, elementsArray, searchResultsAttributes, true, null); + } + + private static List findReferenceExpressions(JetProperty val) { + List result = Lists.newArrayList(); + + for (PsiReference reference : ReferencesSearch.search(val, GlobalSearchScope.allScope(val.getProject()), false).findAll()) { + JetExpression expression = (JetExpression) reference.getElement(); + PsiElement parent = expression.getParent(); + if (parent instanceof JetQualifiedExpression && ((JetQualifiedExpression) parent).getSelectorExpression() == expression) { + result.add((JetQualifiedExpression) parent); + } + else { + result.add(expression); + } + } + + return result; + } + + private static boolean showDialog(Project project, String name, List referenceExpressions) { + if (ApplicationManager.getApplication().isUnitTestMode()) { + return true; + } + RefactoringMessageDialog dialog = new RefactoringMessageDialog( RefactoringBundle.message("inline.variable.title"), RefactoringBundle.message("inline.local.variable.prompt", name) + " " + - RefactoringBundle.message("occurences.string", references.size()), + RefactoringBundle.message("occurences.string", referenceExpressions.size()), HelpID.INLINE_VARIABLE, "OptionPane.questionIcon", true, diff --git a/idea/testData/refactoring/inline/property/Basic.kt b/idea/testData/refactoring/inline/property/Basic.kt new file mode 100644 index 00000000000..dba6c3f7361 --- /dev/null +++ b/idea/testData/refactoring/inline/property/Basic.kt @@ -0,0 +1,5 @@ +val C = 239 + +fun f() { + println(C) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/Basic.kt.after b/idea/testData/refactoring/inline/property/Basic.kt.after new file mode 100644 index 00000000000..2dbc7327bef --- /dev/null +++ b/idea/testData/refactoring/inline/property/Basic.kt.after @@ -0,0 +1,3 @@ +fun f() { + println(239) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/ClassObjectProperty.kt b/idea/testData/refactoring/inline/property/ClassObjectProperty.kt new file mode 100644 index 00000000000..c9147d3eb24 --- /dev/null +++ b/idea/testData/refactoring/inline/property/ClassObjectProperty.kt @@ -0,0 +1,9 @@ +class Class { + class object { + val p = 239 + } +} + +fun f() { + println(Class.p) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/ClassObjectProperty.kt.after b/idea/testData/refactoring/inline/property/ClassObjectProperty.kt.after new file mode 100644 index 00000000000..35c93f86c9a --- /dev/null +++ b/idea/testData/refactoring/inline/property/ClassObjectProperty.kt.after @@ -0,0 +1,8 @@ +class Class { + class object { + } +} + +fun f() { + println(239) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/ExtensionProperty.kt b/idea/testData/refactoring/inline/property/ExtensionProperty.kt new file mode 100644 index 00000000000..f3165d2d186 --- /dev/null +++ b/idea/testData/refactoring/inline/property/ExtensionProperty.kt @@ -0,0 +1,7 @@ +val Int.C = 239 + +// not implemented yet + +fun f() { + println(5.C) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/InstanceProperty.kt b/idea/testData/refactoring/inline/property/InstanceProperty.kt new file mode 100644 index 00000000000..4466a8cf506 --- /dev/null +++ b/idea/testData/refactoring/inline/property/InstanceProperty.kt @@ -0,0 +1,11 @@ +class Class { + val p = 239 + + fun f() { + println(p) + } +} + +fun f() { + println(Class().p) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/InstanceProperty.kt.after b/idea/testData/refactoring/inline/property/InstanceProperty.kt.after new file mode 100644 index 00000000000..7090a4747dc --- /dev/null +++ b/idea/testData/refactoring/inline/property/InstanceProperty.kt.after @@ -0,0 +1,10 @@ +class Class { + + fun f() { + println(239) + } +} + +fun f() { + println(239) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/ObjectProperty.kt b/idea/testData/refactoring/inline/property/ObjectProperty.kt new file mode 100644 index 00000000000..4c9424940f6 --- /dev/null +++ b/idea/testData/refactoring/inline/property/ObjectProperty.kt @@ -0,0 +1,7 @@ +object Obj { + val p = 239 +} + +fun f() { + println(Obj.p) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/ObjectProperty.kt.after b/idea/testData/refactoring/inline/property/ObjectProperty.kt.after new file mode 100644 index 00000000000..f67b650dae7 --- /dev/null +++ b/idea/testData/refactoring/inline/property/ObjectProperty.kt.after @@ -0,0 +1,6 @@ +object Obj { +} + +fun f() { + println(239) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/QualifiedUsage.kt b/idea/testData/refactoring/inline/property/QualifiedUsage.kt new file mode 100644 index 00000000000..e8c86d71159 --- /dev/null +++ b/idea/testData/refactoring/inline/property/QualifiedUsage.kt @@ -0,0 +1,7 @@ +package foo.bar + +val C = 239 + +fun f() { + println(foo.bar.C) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/QualifiedUsage.kt.after b/idea/testData/refactoring/inline/property/QualifiedUsage.kt.after new file mode 100644 index 00000000000..59e4e7e7e8d --- /dev/null +++ b/idea/testData/refactoring/inline/property/QualifiedUsage.kt.after @@ -0,0 +1,5 @@ +package foo.bar + +fun f() { + println(239) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/WithGetter.kt b/idea/testData/refactoring/inline/property/WithGetter.kt new file mode 100644 index 00000000000..04a3f4227c8 --- /dev/null +++ b/idea/testData/refactoring/inline/property/WithGetter.kt @@ -0,0 +1,8 @@ +val C: Int + get() = 239 + +// not implemented yet + +fun f() { + println(C) +} \ No newline at end of file diff --git a/idea/testData/refactoring/inline/property/WithInitializerAndGetter.kt b/idea/testData/refactoring/inline/property/WithInitializerAndGetter.kt new file mode 100644 index 00000000000..c80ff09d315 --- /dev/null +++ b/idea/testData/refactoring/inline/property/WithInitializerAndGetter.kt @@ -0,0 +1,9 @@ +val C = 239 + get() = $C + 1 + + +// not implemented yet + +fun f() { + println(C) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/AbstractInlineTest.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/AbstractInlineTest.java index f975c887467..91419956cb3 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/AbstractInlineTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/AbstractInlineTest.java @@ -28,7 +28,7 @@ public abstract class AbstractInlineTest extends LightCodeInsightFixtureTestCase final PsiElement targetElement = TargetElementUtilBase.findTargetElement(myFixture.getEditor(), ELEMENT_NAME_ACCEPTED | REFERENCED_ELEMENT_ACCEPTED); - final KotlinInlineLocalHandler handler = new KotlinInlineLocalHandler(); + final KotlinInlineValHandler handler = new KotlinInlineValHandler(); List expectedErrors = InTextDirectivesUtils.findLinesWithPrefixesRemoved(myFixture.getFile().getText(), "// ERROR: "); if (handler.canInlineElement(targetElement)) { diff --git a/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/InlineTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/InlineTestGenerated.java index f11a2c1e592..fec7f90e30b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/InlineTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/refactoring/inline/InlineTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.plugin.refactoring.inline.AbstractInlineTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("idea/testData/refactoring/inline") -@InnerTestClasses({InlineTestGenerated.AddParenthesis.class, InlineTestGenerated.ExplicateParameterTypes.class, InlineTestGenerated.ExplicateTypeArgument.class}) +@InnerTestClasses({InlineTestGenerated.AddParenthesis.class, InlineTestGenerated.ExplicateParameterTypes.class, InlineTestGenerated.ExplicateTypeArgument.class, InlineTestGenerated.Property.class}) public class InlineTestGenerated extends AbstractInlineTest { public void testAllFilesPresentInInline() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/refactoring/inline"), Pattern.compile("^(.+)\\.kt$"), true); @@ -232,11 +232,6 @@ public class InlineTestGenerated extends AbstractInlineTest { public void testQualifiedDontAdd() throws Exception { doTest("idea/testData/refactoring/inline/addParenthesis/QualifiedDontAdd.kt"); } - - @TestMetadata("UnaryIntoBinary.kt") - public void testUnaryIntoBinary() throws Exception { - doTest("idea/testData/refactoring/inline/addParenthesis/UnaryIntoBinary.kt"); - } @TestMetadata("StringTemplate.kt") public void testStringTemplate() throws Exception { @@ -253,6 +248,11 @@ public class InlineTestGenerated extends AbstractInlineTest { doTest("idea/testData/refactoring/inline/addParenthesis/StringTemplateDontAdd.kt"); } + @TestMetadata("UnaryIntoBinary.kt") + public void testUnaryIntoBinary() throws Exception { + doTest("idea/testData/refactoring/inline/addParenthesis/UnaryIntoBinary.kt"); + } + } @TestMetadata("idea/testData/refactoring/inline/explicateParameterTypes") @@ -351,12 +351,61 @@ public class InlineTestGenerated extends AbstractInlineTest { } + @TestMetadata("idea/testData/refactoring/inline/property") + public static class Property extends AbstractInlineTest { + public void testAllFilesPresentInProperty() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/refactoring/inline/property"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("Basic.kt") + public void testBasic() throws Exception { + doTest("idea/testData/refactoring/inline/property/Basic.kt"); + } + + @TestMetadata("ClassObjectProperty.kt") + public void testClassObjectProperty() throws Exception { + doTest("idea/testData/refactoring/inline/property/ClassObjectProperty.kt"); + } + + @TestMetadata("ExtensionProperty.kt") + public void testExtensionProperty() throws Exception { + doTest("idea/testData/refactoring/inline/property/ExtensionProperty.kt"); + } + + @TestMetadata("InstanceProperty.kt") + public void testInstanceProperty() throws Exception { + doTest("idea/testData/refactoring/inline/property/InstanceProperty.kt"); + } + + @TestMetadata("ObjectProperty.kt") + public void testObjectProperty() throws Exception { + doTest("idea/testData/refactoring/inline/property/ObjectProperty.kt"); + } + + @TestMetadata("QualifiedUsage.kt") + public void testQualifiedUsage() throws Exception { + doTest("idea/testData/refactoring/inline/property/QualifiedUsage.kt"); + } + + @TestMetadata("WithGetter.kt") + public void testWithGetter() throws Exception { + doTest("idea/testData/refactoring/inline/property/WithGetter.kt"); + } + + @TestMetadata("WithInitializerAndGetter.kt") + public void testWithInitializerAndGetter() throws Exception { + doTest("idea/testData/refactoring/inline/property/WithInitializerAndGetter.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("InlineTestGenerated"); suite.addTestSuite(InlineTestGenerated.class); suite.addTestSuite(AddParenthesis.class); suite.addTestSuite(ExplicateParameterTypes.class); suite.addTestSuite(ExplicateTypeArgument.class); + suite.addTestSuite(Property.class); return suite; } }