From 22e6bef23e4bff0dfdf110ad68492af1b79b404f Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Thu, 25 Jul 2024 16:12:05 -0400 Subject: [PATCH] Fix local var cleanup to avoid method references (#1541) - fix VarCleanUpCore visitor maybeUserVar() method to return false for a method reference initializer - add new test to CleanUpTest11 - fixes #1524 --- .../jdt/internal/ui/fix/VarCleanUpCore.java | 6 +- .../jdt/ui/tests/quickfix/CleanUpTest11.java | 140 +++++++++++------- 2 files changed, 89 insertions(+), 57 deletions(-) diff --git a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/VarCleanUpCore.java b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/VarCleanUpCore.java index 2acfe405b1c..6a678edf81c 100644 --- a/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/VarCleanUpCore.java +++ b/org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/fix/VarCleanUpCore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2023 Fabrice TIERCELIN and others. + * Copyright (c) 2020, 2024 Fabrice TIERCELIN and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -34,6 +34,7 @@ import org.eclipse.jdt.core.dom.ClassInstanceCreation; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Expression; +import org.eclipse.jdt.core.dom.ExpressionMethodReference; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; @@ -148,6 +149,9 @@ public boolean visit(final SingleVariableDeclaration node) { } private boolean maybeUseVar(final Type type, final Expression initializer, final int extraDimensions) { + if (initializer instanceof ExpressionMethodReference) { + return false; + } if (type.isVar() || initializer == null || initializer.resolveTypeBinding() == null diff --git a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest11.java b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest11.java index aaa3bc27fd5..3c2d848a631 100644 --- a/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest11.java +++ b/org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/CleanUpTest11.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2020, 2021 Red Hat Inc. and others. + * Copyright (c) 2020, 2024 Red Hat Inc. and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -56,9 +56,9 @@ public void testUseLocalVariableTypeInferenceInLambda1() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Predicate - + public class E { public void foo() { Predicate cc = (String s) -> { return s.length() > 0; }; @@ -71,9 +71,9 @@ public void foo() { String expected= """ package test1; - + import java.util.function.Predicate - + public class E { public void foo() { Predicate cc = (var s) -> { return s.length() > 0; }; @@ -89,7 +89,7 @@ public void testUseLocalVariableTypeInferenceInLambda2() throws Exception { IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + public class E1 { private interface I1 { public void run(String s, int i, Boolean b); @@ -105,7 +105,7 @@ public void foo(int doNotRefactorParameter) { String expected= """ package test1; - + public class E1 { private interface I1 { public void run(String s, int i, Boolean b); @@ -125,14 +125,14 @@ public void testUseLocalVariableTypeInferenceInParamCallWithLambda() throws Exce IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Function; - + public class E1 { public void foo() { debug((String a) -> a.length()); } - + private void debug(Function function) { System.out.println(function); } @@ -144,14 +144,14 @@ private void debug(Function function) { String expected= """ package test1; - + import java.util.function.Function; - + public class E1 { public void foo() { debug((var a) -> a.length()); } - + private void debug(Function function) { System.out.println(function); } @@ -167,14 +167,14 @@ public void testDoNotUseLocalVariableTypeInferenceInWildCardParamCallWithLambda( IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Function; - + public class E1 { public void foo() { debug((String a) -> a.length()); } - + private void debug(Function function) { System.out.println(function); } @@ -193,14 +193,14 @@ public void testDoNotUseLocalVariableTypeInferenceInWildCardConstructorWithLambd IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Function; - + public class E1 { public static void main(String[] args) { new E1((String a) -> a.length()); } - + public E1(Function function) { System.out.println(function); } @@ -219,36 +219,36 @@ public void testDoNotUseLocalVariableTypeInferenceInWildCardSuperCallsWithLambda IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Function; - + public class E1 { public E1(Function function) { System.out.println(function); } - + public void method(Function function) { System.out.println(function); } - + } """; ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); String sample2= """ package test1; - + import java.util.function.Function; - + public class E2 extends E1 { public E2(Function function) { super((String a) -> a.length()); } - + public void method(Function function) { super.method((String a) -> a.length()); } - + } """; ICompilationUnit cu2= pack1.createCompilationUnit("E2.java", sample2, false, null); @@ -264,9 +264,9 @@ public void testUseLocalVariableTypeInferenceInParamTypeDeclarationWithLambda() IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Predicate; - + public class E1 { public void foo() { Predicate cc = (String s) -> (s.length() > 0); @@ -279,9 +279,9 @@ public void foo() { String expected= """ package test1; - + import java.util.function.Predicate; - + public class E1 { public void foo() { Predicate cc = (var s) -> (s.length() > 0); @@ -298,9 +298,9 @@ public void testDoNotUseLocalVariableTypeInferenceInWildCardParamDeclarationWith IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Predicate; - + public class E1 { public void foo() { Predicate cc = (String s) -> (s.length() > 0); @@ -320,9 +320,9 @@ public void testUseLocalVariableTypeInferenceInParamFieldDeclarationWithLambda() IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Predicate; - + public class E1 { public Predicate cc = (String s) -> (s.length() > 0); } @@ -333,9 +333,9 @@ public class E1 { String expected= """ package test1; - + import java.util.function.Predicate; - + public class E1 { public Predicate cc = (var s) -> (s.length() > 0); } @@ -350,9 +350,9 @@ public void testDoNotUseLocalVariableTypeInferenceInWildCardParamFieldDeclaratio IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + import java.util.function.Predicate; - + public class E1 { public Predicate cc = (String s) -> (s.length() > 0); } @@ -364,6 +364,34 @@ public class E1 { assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); } + @Test + public void testDoNotUseLocalVariableTypeInferenceWithMethodRef() throws Exception { + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=570058 + IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null); + String sample= """ + package test1; + + interface MyIntf { + void bla(Object... o); + } + + public class E1 { + + private void bla(Object... o) { + } + + private void foo() { + MyIntf myin = this::bla; + } + + } + """; + ICompilationUnit cu1= pack1.createCompilationUnit("E1.java", sample, false, null); + + enable(CleanUpConstants.USE_VAR); + + assertRefactoringHasNoChange(new ICompilationUnit[] { cu1 }); + } @Test public void testUseStringIsBlank() throws Exception { @@ -371,14 +399,14 @@ public void testUseStringIsBlank() throws Exception { IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); String given= """ package test1; - + import java.util.List; - + public class E { private static final int ZERO = 0; private static final int THREE = 3; private static final String EMPTY_STRING = ""; - + void isBlank(String text) { if (text.strip().isEmpty()) { System.err.println("Text must not be blank"); @@ -418,7 +446,7 @@ void isBlank(String text) { System.err.println("Text must not be blank"); } } - + void isNotBlank(String text, StringBuilder builder) { if (!text.strip().isEmpty()) { System.out.println(text) @@ -443,7 +471,7 @@ void isNotBlank(String text, StringBuilder builder) { System.out.println(text) } } - + void printList(List list) { list.stream().filter(s -> !s.strip().isEmpty()).map(String::strip); list.stream().filter(s -> s.strip().length() != 0).map(String::strip); @@ -453,14 +481,14 @@ void printList(List list) { String expected= """ package test1; - + import java.util.List; - + public class E { private static final int ZERO = 0; private static final int THREE = 3; private static final String EMPTY_STRING = ""; - + void isBlank(String text) { if (text.isBlank()) { System.err.println("Text must not be blank"); @@ -500,7 +528,7 @@ void isBlank(String text) { System.err.println("Text must not be blank"); } } - + void isNotBlank(String text, StringBuilder builder) { if (!text.isBlank()) { System.out.println(text) @@ -525,7 +553,7 @@ void isNotBlank(String text, StringBuilder builder) { System.out.println(text) } } - + void printList(List list) { list.stream().filter(s -> !s.isBlank()).map(String::strip); list.stream().filter(s -> !s.isBlank()).map(String::strip); @@ -547,37 +575,37 @@ public void testDoNotUseStringIsBlank() throws Exception { IPackageFragment pack= fSourceFolder.createPackageFragment("test1", false, null); String sample= """ package test1; - + public class NotAString { int mostlyZero= 0; private static int NON_FINAL_ZERO = 0; - + public String strip() { return ""; } - + void doNotUseStringIsBlank(NotAString noString, String text) { if (noString.strip().length() == 0) { System.err.println("Text must not be blank"); } - + if (text.strip().length() == mostlyZero) { System.err.println("Text must not be blank"); } else if (text.strip().length() <= NON_FINAL_ZERO) { System.err.println("Text must not be blank"); } } - + void doNotUseStringIsBlankWithUnknownString(String text, String emptyString) { if (text.strip().equals(emptyString)) { System.err.println("Text must not be blank"); } - + if (emptyString.equals(text.strip())) { System.err.println("Text must not be blank"); } } - + void bug_573831(String text) { if (equals(text.strip())) { System.err.println("Applying the cleanup should not cause NPE");