diff --git a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/Bundle.properties b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/Bundle.properties
index ec59b7ec94c7..fb08af9426d6 100644
--- a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/Bundle.properties
+++ b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/Bundle.properties
@@ -79,6 +79,7 @@ ERR_PullUp_MemberAlreadyExists=Member "{0}" already exists in the target type.
ERR_CannotPullupDuplicateMembers=Cannot pull up two members with the same signature.
ERR_PullupNonPublicToInterface=Member "{0}" is being moved to interface, but is not public.
ERR_PullupStaticToInterface=Member "{0}" cannot be pulled up to interface, it is static.
+ERR_PullupNonNotInitializedToInterface=Member "{0}" cannot be pulled up to interface, it is not initialized.
TXT_PullUp_AddMethod=Add abstract method\: {0}
# Move member to the target type (0 = member name)
diff --git a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveMembersRefactoringPlugin.java b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveMembersRefactoringPlugin.java
index 3af5c11f9930..bc62819ea6fb 100644
--- a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveMembersRefactoringPlugin.java
+++ b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/MoveMembersRefactoringPlugin.java
@@ -19,6 +19,7 @@
package org.netbeans.modules.refactoring.java.plugins;
import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
import com.sun.source.util.TreePath;
import java.io.IOException;
import java.net.URL;
@@ -29,20 +30,17 @@
import javax.lang.model.util.ElementFilter;
import org.netbeans.api.java.classpath.ClassPath;
import org.netbeans.api.java.source.*;
-import org.netbeans.api.java.source.ClasspathInfo.PathKind;
import org.netbeans.api.project.FileOwnerQuery;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ProjectUtils;
import org.netbeans.modules.refactoring.api.AbstractRefactoring;
import org.netbeans.modules.refactoring.api.MoveRefactoring;
import org.netbeans.modules.refactoring.api.Problem;
-import org.netbeans.modules.refactoring.api.ProgressEvent;
import org.netbeans.modules.refactoring.java.RefactoringUtils;
import org.netbeans.modules.refactoring.java.api.JavaMoveMembersProperties;
import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils;
import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin;
import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
-import org.netbeans.spi.java.classpath.support.ClassPathSupport;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
import org.openide.util.Lookup;
@@ -66,6 +64,8 @@
"ERR_MoveAbstractMember=Cannot move abstract method \"{0}\"",
"# {0} - Method name",
"ERR_MoveMethodPolymorphic=Cannot move polymorphic method \"{0}\"",
+ "# {0} - Field name",
+ "ERR_MoveNotInitializedToInterface=Member \"{0}\" cannot be moved to interface, it is not initialized.",
"WRN_InitNoAccess=Field initializer uses local accessors which will not be accessible",
"# {0} - File displayname : line number",
"WRN_NoAccessor=No accessor found to invoke the method from: {0}",
@@ -239,6 +239,19 @@ protected Problem fastCheckParameters(CompilationController javac) throws IOExce
if(targetPackage.isUnnamed() && !sourcePackage.isUnnamed()) {
return new Problem(true, NbBundle.getMessage(MoveMembersRefactoringPlugin.class, "ERR_MovingMemberToDefaultPackage")); //NOI18N
}
+ if (targetClass.getKind().isInterface()) {
+
+ for (TreePathHandle treePathHandle : source) {
+ Element element = treePathHandle.resolveElement(javac);
+ if (element != null && element.getKind() == ElementKind.FIELD) {
+ VariableElement variableElement = (VariableElement) element;
+ VariableTree variableTree = (VariableTree) javac.getTrees().getTree(variableElement);
+ if (variableTree != null && variableTree.getInitializer() == null) {
+ return createProblem(p, true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_MoveNotInitializedToInterface", element.getSimpleName()));
+ }
+ }
+ }
+ }
for (TreePathHandle treePathHandle : source) {
Element element = treePathHandle.resolveElement(javac);
List extends Element> enclosedElements = targetElement.getEnclosedElements();
diff --git a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/PullUpRefactoringPlugin.java b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/PullUpRefactoringPlugin.java
index ad59b6be036e..9473239053a4 100644
--- a/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/PullUpRefactoringPlugin.java
+++ b/java/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/PullUpRefactoringPlugin.java
@@ -18,16 +18,17 @@
*/
package org.netbeans.modules.refactoring.java.plugins;
+import com.sun.source.tree.VariableTree;
import java.io.IOException;
import java.util.*;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
import org.netbeans.api.java.source.*;
import org.netbeans.modules.refactoring.api.AbstractRefactoring;
import org.netbeans.modules.refactoring.api.Problem;
-import org.netbeans.modules.refactoring.api.ProgressEvent;
import org.netbeans.modules.refactoring.java.RefactoringUtils;
import org.netbeans.modules.refactoring.java.api.JavaRefactoringUtils;
import org.netbeans.modules.refactoring.java.api.MemberInfo;
@@ -120,7 +121,8 @@ protected Problem preCheck(CompilationController cc) throws IOException {
@Override
- public Problem fastCheckParameters() {
+ public Problem fastCheckParameters(CompilationController cc) throws IOException {
+ cc.toPhase(JavaSource.Phase.RESOLVED);
MemberInfo>[] info = refactoring.getMembers();
// #1 - check whether there are any members to pull up
if (info.length == 0) {
@@ -144,7 +146,8 @@ public Problem fastCheckParameters() {
Problem p=null;
if (refactoring.getTargetType().getKind().isInterface()) {
- for (MemberInfo i:info) {
+ for (MemberInfo> i :info) {
+ Element member = i.getElementHandle().resolve(cc);
if (!i.getModifiers().contains(Modifier.PUBLIC)) {
p = createProblem(p, false, NbBundle.getMessage(PullUpRefactoringPlugin.class,"ERR_PullupNonPublicToInterface" ,i.getName()));
}
@@ -152,7 +155,15 @@ public Problem fastCheckParameters() {
if (i.getModifiers().contains(Modifier.STATIC)) {
p = createProblem(p, true, NbBundle.getMessage(PullUpRefactoringPlugin.class,"ERR_PullupStaticToInterface" ,i.getName()));
}
+ if (member.getKind() == ElementKind.FIELD) {
+ VariableElement variableElement = (VariableElement) member;
+ VariableTree variableTree = (VariableTree) cc.getTrees().getTree(variableElement);
+ if (variableTree != null && variableTree.getInitializer() == null) {
+ return createProblem(p, true, NbBundle.getMessage(PullUpRefactoringPlugin.class, "ERR_PullupNonNotInitializedToInterface", member.getSimpleName()));
+ }
+ }
}
+
}
for (MemberInfo> i : info) {
@@ -237,7 +248,6 @@ protected Problem checkParameters(CompilationController cc) throws IOException {
// !sourceResource.equals(targetResource),
// !sourceResource.getPackageName().equals(targetResource.getPackageName()));
// }
-
fireProgressListenerStep();
}
diff --git a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/plugins/Bundle_test.properties b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/plugins/Bundle_test.properties
index 067ec0affd78..330a1f1b1c78 100644
--- a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/plugins/Bundle_test.properties
+++ b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/plugins/Bundle_test.properties
@@ -69,6 +69,7 @@ ERR_MoveToSameClass=ERR_MoveToSameClass
ERR_MoveToSuperClass=ERR_MoveToSuperClass
ERR_MoveToSubClass=ERR_MoveToSubClass
ERR_MoveGenericField=ERR_MoveGenericField
+ERR_MoveNotInitializedToInterface=ERR_MoveNotInitializedToInterface
WRN_InitNoAccess=WRN_InitNoAccess
WRN_NoAccessor=WRN_NoAccessor
ERR_CannotMovePublicIntoSamePackage=ERR_CannotMovePublicIntoSamePackage
@@ -82,6 +83,7 @@ ERR_ClassToMoveClashesInner=ERR_ClassToMoveClashesInner
ERR_PullUp_MemberAlreadyExists=ERR_PullUp_MemberAlreadyExists
ERR_PullUp_MemberTargetType=ERR_PullUp_MemberTargetType
ERR_PullupStaticToInterface=ERR_PullupStaticToInterface
+ERR_PullupNonNotInitializedToInterface=ERR_PullupNonNotInitializedToInterface
# Copy
ERR_ClassToMoveClashes=ERR_ClassToMoveClashes
diff --git a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/MoveFieldTest.java b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/MoveFieldTest.java
index b1cebd15aa46..07b579913409 100644
--- a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/MoveFieldTest.java
+++ b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/MoveFieldTest.java
@@ -57,6 +57,50 @@ public void testMoveField() throws Exception {
+ "}\n"));
}
+ public void testMoveNotInitializedFieldToInterface() throws Exception {
+ writeFilesAndWaitForScan(src,
+ new File("t/A.java", "package t;\n"
+ + "public class A {\n"
+ + " public static int i;\n"
+ + "}\n"),
+ new File("t/B.java", "package t;\n"
+ + "public interface B {\n"
+ + "}\n"));
+ performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.ESCALATE, false, new Problem(true, "ERR_MoveNotInitializedToInterface"));
+ }
+
+ public void testMoveInitializedFieldToInterface() throws Exception {
+ writeFilesAndWaitForScan(src,
+ new File("t/A.java",
+ """
+ package t;
+ public class A {
+ public static int i = 1;
+ }
+ """),
+ new File("t/B.java",
+ """
+ package t;
+ public interface B {
+ }
+ """));
+ performMove(src.getFileObject("t/A.java"), new int[]{1}, src.getFileObject("t/B.java"), Visibility.ESCALATE, false);
+ verifyContent(src,
+ new File("t/A.java",
+ """
+ package t;
+ public class A {
+ }
+ """),
+ new File("t/B.java",
+ """
+ package t;
+ public interface B {
+ public static int i = 1;
+ }
+ """));
+ }
+
public void test242909() throws Exception {
writeFilesAndWaitForScan(src,
new File("t/A.java", "package t;\n"
diff --git a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/PullUpTest.java b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/PullUpTest.java
index fb7cde7eda01..768f8f7127a2 100644
--- a/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/PullUpTest.java
+++ b/java/refactoring.java/test/unit/src/org/netbeans/modules/refactoring/java/test/PullUpTest.java
@@ -172,6 +172,23 @@ public void test206683() throws Exception {
performPullUp(src.getFileObject("pullup/A.java"), 1, Boolean.FALSE, new Problem(true, "ERR_PullUp_MemberAlreadyExists"));
}
+ public void testPullUpNotInitializedFieldToInterface() throws Exception {
+ writeFilesAndWaitForScan(src,
+ new File("pullup/A.java", "package pullup; public interface A {}"),
+ new File("pullup/B.java", "package pullup; public class B implements A { public int i; }"));
+ performPullUpIface(src.getFileObject("pullup/B.java"), 1, 0, Boolean.FALSE, new Problem(true, "ERR_PullupNonNotInitializedToInterface"));
+ }
+
+ public void testPullUpInitializedFieldToInterface() throws Exception {
+ writeFilesAndWaitForScan(src,
+ new File("t/A.java", "package pullup; public interface A {}"),
+ new File("t/B.java", "package pullup; public class B implements A { public int i = 1; }"));
+ performPullUpIface(src.getFileObject("t/B.java"), 1,0, Boolean.FALSE);
+ verifyContent(src,
+ new File("t/A.java", "package pullup; public interface A { public int i = 1; }"),
+ new File("t/B.java", "package pullup; public class B implements A {}"));
+ }
+
public void testPullUpField() throws Exception {
writeFilesAndWaitForScan(src,
new File("pullup/A.java", "package pullup; public class A extends B { public int i; }"),