Inline Variable: Var support
#KT-5169 Fixed
This commit is contained in:
@@ -54,18 +54,20 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic;
|
|||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.idea.JetLanguage;
|
import org.jetbrains.kotlin.idea.JetLanguage;
|
||||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
|
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils;
|
||||||
|
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade;
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers;
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers;
|
||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences;
|
import org.jetbrains.kotlin.idea.util.ShortenReferences;
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens;
|
import org.jetbrains.kotlin.lexer.JetTokens;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.JetPsiUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils;
|
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||||
import org.jetbrains.kotlin.types.JetType;
|
import org.jetbrains.kotlin.types.JetType;
|
||||||
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -85,7 +87,7 @@ public class KotlinInlineValHandler extends InlineActionHandler {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
JetProperty property = (JetProperty) element;
|
JetProperty property = (JetProperty) element;
|
||||||
return !property.isVar() && property.getGetter() == null && property.getReceiverTypeReference() == null;
|
return property.getGetter() == null && property.getReceiverTypeReference() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -101,9 +103,15 @@ public class KotlinInlineValHandler extends InlineActionHandler {
|
|||||||
final Set<PsiElement> assignments = Sets.newHashSet();
|
final Set<PsiElement> assignments = Sets.newHashSet();
|
||||||
for (JetExpression expression : referenceExpressions) {
|
for (JetExpression expression : referenceExpressions) {
|
||||||
PsiElement parent = expression.getParent();
|
PsiElement parent = expression.getParent();
|
||||||
if (parent instanceof JetBinaryExpression &&
|
|
||||||
((JetBinaryExpression) parent).getOperationToken() == JetTokens.EQ &&
|
JetBinaryExpression assignment = JetPsiUtilKt.getAssignmentByLHS(expression);
|
||||||
((JetBinaryExpression) parent).getLeft() == expression) {
|
if (assignment != null) {
|
||||||
|
assignments.add(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection SuspiciousMethodCalls
|
||||||
|
if (parent instanceof JetUnaryExpression &&
|
||||||
|
OperatorConventions.INCREMENT_OPERATIONS.contains(((JetUnaryExpression) parent).getOperationToken())) {
|
||||||
assignments.add(parent);
|
assignments.add(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,6 +119,10 @@ public class KotlinInlineValHandler extends InlineActionHandler {
|
|||||||
final JetExpression initializer;
|
final JetExpression initializer;
|
||||||
if (initializerInDeclaration != null) {
|
if (initializerInDeclaration != null) {
|
||||||
initializer = initializerInDeclaration;
|
initializer = initializerInDeclaration;
|
||||||
|
if (!assignments.isEmpty()) {
|
||||||
|
reportAmbiguousAssignment(project, editor, name, assignments);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (assignments.size() == 1) {
|
if (assignments.size() == 1) {
|
||||||
@@ -120,9 +132,7 @@ public class KotlinInlineValHandler extends InlineActionHandler {
|
|||||||
initializer = null;
|
initializer = null;
|
||||||
}
|
}
|
||||||
if (initializer == null) {
|
if (initializer == null) {
|
||||||
String key = assignments.isEmpty() ? "variable.has.no.initializer" : "variable.has.no.dominating.definition";
|
reportAmbiguousAssignment(project, editor, name, assignments);
|
||||||
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, name));
|
|
||||||
CommonRefactoringUtil.showErrorHint(project, editor, message, RefactoringBundle.message("inline.variable.title"), HelpID.INLINE_VARIABLE);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,6 +206,23 @@ public class KotlinInlineValHandler extends InlineActionHandler {
|
|||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void reportAmbiguousAssignment(Project project, Editor editor, String name, Set<PsiElement> assignments) {
|
||||||
|
String key = assignments.isEmpty() ? "variable.has.no.initializer" : "variable.has.no.dominating.definition";
|
||||||
|
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, name));
|
||||||
|
showErrorHint(project, editor, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void reportWriteAccess(Project project, Editor editor, String name) {
|
||||||
|
String message = RefactoringBundle.getCannotRefactorMessage(
|
||||||
|
RefactoringBundle.message("variable.is.accessed.for.writing", name)
|
||||||
|
);
|
||||||
|
showErrorHint(project, editor, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showErrorHint(Project project, Editor editor, String message) {
|
||||||
|
CommonRefactoringUtil.showErrorHint(project, editor, message, RefactoringBundle.message("inline.variable.title"), HelpID.INLINE_VARIABLE);
|
||||||
|
}
|
||||||
|
|
||||||
private static void highlightExpressions(Project project, Editor editor, List<? extends PsiElement> elements) {
|
private static void highlightExpressions(Project project, Editor editor, List<? extends PsiElement> elements) {
|
||||||
if (editor == null || ApplicationManager.getApplication().isUnitTestMode()) {
|
if (editor == null || ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
-4
@@ -1,4 +0,0 @@
|
|||||||
fun f() {
|
|
||||||
var v = 239
|
|
||||||
println(<caret>v)
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// ERROR: Cannot perform refactoring.\nCannot find a single definition to inline
|
||||||
fun f() {
|
fun f() {
|
||||||
val v = if (true) a else b
|
val v = if (true) a else b
|
||||||
println(<caret>v++)
|
println(<caret>v++)
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
fun f() {
|
|
||||||
println((if (true) a else b)++)
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
fun foo() {
|
||||||
|
var x = 1
|
||||||
|
val t = <caret>x + 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo() {
|
||||||
|
val t = 1 + 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// ERROR: Cannot perform refactoring.\nCannot find a single definition to inline
|
||||||
|
fun foo() {
|
||||||
|
var x = 1
|
||||||
|
val t = <caret>x + 1
|
||||||
|
x = 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// ERROR: Cannot perform refactoring.\nCannot find a single definition to inline
|
||||||
|
fun foo() {
|
||||||
|
var x = 1
|
||||||
|
val t = <caret>x + 1
|
||||||
|
x++
|
||||||
|
}
|
||||||
@@ -101,9 +101,21 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("Var.kt")
|
@TestMetadata("varNoWrite.kt")
|
||||||
public void testVar() throws Exception {
|
public void testVarNoWrite() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/inline/Var.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/inline/varNoWrite.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("varWithAssignment.kt")
|
||||||
|
public void testVarWithAssignment() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/inline/varWithAssignment.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("varWithInc.kt")
|
||||||
|
public void testVarWithInc() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/inline/varWithInc.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user