Supported vals initialized after.
#KT-2637 in progress
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.plugin.refactoring.inline;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.refactoring.InlineActionHandler;
|
||||
@@ -18,11 +19,14 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.RefactoringMessageDialog;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetLanguage;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
public class KotlinInlineLocalHandler extends InlineActionHandler {
|
||||
@Override
|
||||
@@ -36,7 +40,7 @@ public class KotlinInlineLocalHandler extends InlineActionHandler {
|
||||
return false;
|
||||
}
|
||||
JetProperty property = (JetProperty) element;
|
||||
return property.getInitializer() != null && !property.isVar();
|
||||
return !property.isVar();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,10 +48,40 @@ public class KotlinInlineLocalHandler extends InlineActionHandler {
|
||||
final JetProperty val = (JetProperty) element;
|
||||
String name = val.getName();
|
||||
|
||||
final JetExpression initializer = val.getInitializer();
|
||||
assert initializer != null : element.getText();
|
||||
JetExpression initializerInDeclaration = val.getInitializer();
|
||||
|
||||
final Collection<PsiReference> references = ReferencesSearch.search(val, GlobalSearchScope.allScope(project), false).findAll();
|
||||
|
||||
final Set<PsiElement> assignments = Sets.newHashSet();
|
||||
for (PsiReference ref : references) {
|
||||
PsiElement refElement = ref.getElement();
|
||||
PsiElement parent = refElement.getParent();
|
||||
if (parent instanceof JetBinaryExpression &&
|
||||
((JetBinaryExpression) parent).getOperationToken() == JetTokens.EQ &&
|
||||
((JetBinaryExpression) parent).getLeft() == refElement) {
|
||||
assignments.add(parent);
|
||||
}
|
||||
}
|
||||
|
||||
final JetExpression initializer;
|
||||
if (initializerInDeclaration != null) {
|
||||
initializer = initializerInDeclaration;
|
||||
}
|
||||
else {
|
||||
if (assignments.size() == 1) {
|
||||
initializer = ((JetBinaryExpression) assignments.iterator().next()).getRight();
|
||||
}
|
||||
else {
|
||||
initializer = null;
|
||||
}
|
||||
if (initializer == null) {
|
||||
String key = assignments.isEmpty() ? "variable.has.no.initializer" : "variable.has.no.dominating.definition";
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, name));
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, RefactoringBundle.message("inline.variable.title"), HelpID.INLINE_VARIABLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PsiReference[] referencesArray = references.toArray(references.toArray(new PsiReference[references.size()]));
|
||||
|
||||
if (editor != null && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
@@ -80,6 +114,10 @@ public class KotlinInlineLocalHandler extends InlineActionHandler {
|
||||
public void run() {
|
||||
for (PsiReference reference : references) {
|
||||
PsiElement referenceElement = reference.getElement();
|
||||
if (assignments.contains(referenceElement.getParent())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (referenceElement.getParent() instanceof JetSimpleNameStringTemplateEntry &&
|
||||
!(initializer instanceof JetSimpleNameExpression)) {
|
||||
referenceElement.getParent().replace(JetPsiFactory.createBlockStringTemplateEntry(project, initializer));
|
||||
@@ -89,6 +127,10 @@ public class KotlinInlineLocalHandler extends InlineActionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiElement assignment : assignments) {
|
||||
assignment.delete();
|
||||
}
|
||||
|
||||
val.delete();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// ERROR: Cannot perform refactoring.\nCannot find a single definition to inline.
|
||||
|
||||
fun f() {
|
||||
val v: Int
|
||||
if (true) {
|
||||
v = 239
|
||||
}
|
||||
else {
|
||||
v = 30
|
||||
}
|
||||
println(<caret>v)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun f() {
|
||||
val v: Int
|
||||
v = 239
|
||||
println(<caret>v)
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun f() {
|
||||
println(239)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fun f() {
|
||||
val v: Int
|
||||
try {
|
||||
v = 239
|
||||
} finally {
|
||||
}
|
||||
println(<caret>v)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fun f() {
|
||||
try {
|
||||
} finally {
|
||||
}
|
||||
println(239)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun f() {
|
||||
val v = 239
|
||||
vv = <caret>v
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun f() {
|
||||
vv = 239
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// ERROR: Cannot perform refactoring.\nVariable v has no initializer.
|
||||
|
||||
fun f() {
|
||||
val v: Int
|
||||
println(<caret>v)
|
||||
|
||||
@@ -4,11 +4,14 @@ import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.InTextDirectivesUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.codeInsight.TargetElementUtilBase.ELEMENT_NAME_ACCEPTED;
|
||||
import static com.intellij.codeInsight.TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED;
|
||||
@@ -25,17 +28,27 @@ public abstract class AbstractInlineTest extends LightCodeInsightFixtureTestCase
|
||||
TargetElementUtilBase.findTargetElement(myFixture.getEditor(), ELEMENT_NAME_ACCEPTED | REFERENCED_ELEMENT_ACCEPTED);
|
||||
final KotlinInlineLocalHandler handler = new KotlinInlineLocalHandler();
|
||||
|
||||
assertEquals(afterFileExists, handler.canInlineElement(targetElement));
|
||||
if (!afterFileExists) {
|
||||
return;
|
||||
}
|
||||
List<String> expectedErrors = InTextDirectivesUtils.findLinesWithPrefixesRemoved(myFixture.getFile().getText(), "// ERROR: ");
|
||||
if (handler.canInlineElement(targetElement)) {
|
||||
try {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.inlineElement(myFixture.getProject(), myFixture.getEditor(), targetElement);
|
||||
}
|
||||
});
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handler.inlineElement(myFixture.getProject(), myFixture.getEditor(), targetElement);
|
||||
assertTrue(afterFileExists);
|
||||
assertEmpty(expectedErrors);
|
||||
myFixture.checkResult(FileUtil.loadFile(afterFile));
|
||||
} catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
|
||||
assertFalse(afterFileExists);
|
||||
assertEquals(1, expectedErrors.size());
|
||||
assertEquals(expectedErrors.get(0).replace("\\n", "\n"), e.getMessage());
|
||||
}
|
||||
});
|
||||
myFixture.checkResult(FileUtil.loadFile(afterFile));
|
||||
}
|
||||
else {
|
||||
assertFalse(afterFileExists);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,11 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
||||
doTest("idea/testData/refactoring/inline/MethodReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MultipleInitializers.kt")
|
||||
public void testMultipleInitializers() throws Exception {
|
||||
doTest("idea/testData/refactoring/inline/MultipleInitializers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MultipleUsages.kt")
|
||||
public void testMultipleUsages() throws Exception {
|
||||
doTest("idea/testData/refactoring/inline/MultipleUsages.kt");
|
||||
@@ -67,6 +72,21 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
||||
doTest("idea/testData/refactoring/inline/Parameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SeparateInitializer.kt")
|
||||
public void testSeparateInitializer() throws Exception {
|
||||
doTest("idea/testData/refactoring/inline/SeparateInitializer.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("SeparateInitializerInTry.kt")
|
||||
public void testSeparateInitializerInTry() throws Exception {
|
||||
doTest("idea/testData/refactoring/inline/SeparateInitializerInTry.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("UsedInAssignment.kt")
|
||||
public void testUsedInAssignment() throws Exception {
|
||||
doTest("idea/testData/refactoring/inline/UsedInAssignment.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ValWithoutInitializer.kt")
|
||||
public void testValWithoutInitializer() throws Exception {
|
||||
doTest("idea/testData/refactoring/inline/ValWithoutInitializer.kt");
|
||||
|
||||
Reference in New Issue
Block a user