Supported inlining constant properties.

This commit is contained in:
Evgeny Gerashchenko
2013-07-24 14:15:11 +04:00
parent b721b0211a
commit a13092e525
17 changed files with 205 additions and 40 deletions
+1 -1
View File
@@ -131,7 +131,7 @@
<refactoring.moveHandler implementation="org.jetbrains.jet.plugin.refactoring.move.JetMoveFilesOrDirectoriesHandler"/>
<refactoring.copyHandler implementation="org.jetbrains.jet.plugin.refactoring.copy.JetCopyClassHandler"/>
<refactoring.changeSignatureUsageProcessor implementation="org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureUsageProcessor"/>
<inlineActionHandler implementation="org.jetbrains.jet.plugin.refactoring.inline.KotlinInlineLocalHandler"/>
<inlineActionHandler implementation="org.jetbrains.jet.plugin.refactoring.inline.KotlinInlineValHandler"/>
<treeStructureProvider implementation="org.jetbrains.jet.plugin.projectView.JetProjectViewProvider"/>
<colorSettingsPage implementation="org.jetbrains.jet.plugin.highlighter.JetColorSettingsPage"/>
@@ -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<PsiReference> references = ReferencesSearch.search(val, GlobalSearchScope.allScope(project), false).findAll();
final List<JetExpression> referenceExpressions = findReferenceExpressions(val);
final Set<PsiElement> 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<JetExpression> 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<PsiReference> references) {
private static void highlightExpressions(Project project, Editor editor, List<? extends PsiElement> 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<JetExpression> findReferenceExpressions(JetProperty val) {
List<JetExpression> 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<JetExpression> 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,
@@ -0,0 +1,5 @@
val C = 239
fun f() {
println(<caret>C)
}
@@ -0,0 +1,3 @@
fun f() {
println(239)
}
@@ -0,0 +1,9 @@
class Class {
class object {
val p = 239
}
}
fun f() {
println(Class.<caret>p)
}
@@ -0,0 +1,8 @@
class Class {
class object {
}
}
fun f() {
println(239)
}
@@ -0,0 +1,7 @@
val Int.C = 239
// not implemented yet
fun f() {
println(5.<caret>C)
}
@@ -0,0 +1,11 @@
class Class {
val p = 239
fun f() {
println(p)
}
}
fun f() {
println(Class().<caret>p)
}
@@ -0,0 +1,10 @@
class Class {
fun f() {
println(239)
}
}
fun f() {
println(239)
}
@@ -0,0 +1,7 @@
object Obj {
val p = 239
}
fun f() {
println(Obj.<caret>p)
}
@@ -0,0 +1,6 @@
object Obj {
}
fun f() {
println(239)
}
@@ -0,0 +1,7 @@
package foo.bar
val C = 239
fun f() {
println(foo.bar.<caret>C)
}
@@ -0,0 +1,5 @@
package foo.bar
fun f() {
println(239)
}
@@ -0,0 +1,8 @@
val C: Int
get() = 239
// not implemented yet
fun f() {
println(<caret>C)
}
@@ -0,0 +1,9 @@
val C = 239
get() = $C + 1
// not implemented yet
fun f() {
println(<caret>C)
}
@@ -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<String> expectedErrors = InTextDirectivesUtils.findLinesWithPrefixesRemoved(myFixture.getFile().getText(), "// ERROR: ");
if (handler.canInlineElement(targetElement)) {
@@ -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;
}
}