mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
javafx: support propertyProperty rename/delete (IDEA-109574)
This commit is contained in:
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiField;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
@@ -31,6 +32,17 @@ public abstract class GetterSetterPrototypeProvider {
|
||||
public abstract boolean canGeneratePrototypeFor(PsiField field);
|
||||
public abstract PsiMethod[] generateGetters(PsiField field);
|
||||
public abstract PsiMethod[] generateSetters(PsiField field);
|
||||
public PsiMethod[] findGetters(PsiClass psiClass, String propertyName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String suggestGetterName(String propertyName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isSimpleGetter(PsiMethod method, String oldPropertyName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public abstract boolean isReadOnly(PsiField field);
|
||||
|
||||
@@ -51,4 +63,27 @@ public abstract class GetterSetterPrototypeProvider {
|
||||
}
|
||||
return field.hasModifierProperty(PsiModifier.FINAL);
|
||||
}
|
||||
|
||||
public static PsiMethod[] findGetters(PsiClass aClass, String propertyName, boolean isStatic) {
|
||||
if (!isStatic) {
|
||||
for (GetterSetterPrototypeProvider provider : Extensions.getExtensions(EP_NAME)) {
|
||||
final PsiMethod[] getterSetter = provider.findGetters(aClass, propertyName);
|
||||
if (getterSetter != null) return getterSetter;
|
||||
}
|
||||
}
|
||||
final PsiMethod propertyGetterSetter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
|
||||
if (propertyGetterSetter != null) {
|
||||
return new PsiMethod[] {propertyGetterSetter};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String suggestNewGetterName(String oldPropertyName, String newPropertyName, PsiMethod method) {
|
||||
for (GetterSetterPrototypeProvider provider : Extensions.getExtensions(EP_NAME)) {
|
||||
if (provider.isSimpleGetter(method, oldPropertyName)) {
|
||||
return provider.suggestGetterName(newPropertyName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.refactoring.rename;
|
||||
|
||||
import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -43,10 +44,7 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameJavaVariableProcessor");
|
||||
@@ -150,7 +148,9 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
|
||||
String newPropertyName = manager.variableNameToPropertyName(newName, VariableKind.FIELD);
|
||||
|
||||
boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
|
||||
PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
|
||||
|
||||
PsiMethod[] getters = GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic);
|
||||
|
||||
PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
|
||||
|
||||
boolean shouldRenameSetterParameter = false;
|
||||
@@ -161,22 +161,31 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
|
||||
shouldRenameSetterParameter = parameterName.equals(setterParameter.getName());
|
||||
}
|
||||
|
||||
String newGetterName = "";
|
||||
|
||||
if (getter != null) {
|
||||
String getterId = getter.getName();
|
||||
newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId);
|
||||
if (newGetterName.equals(getterId)) {
|
||||
getter = null;
|
||||
newGetterName = null;
|
||||
} else {
|
||||
for (PsiMethod method : getter.findDeepestSuperMethods()) {
|
||||
if (method instanceof PsiCompiledElement) {
|
||||
getter = null;
|
||||
break;
|
||||
}
|
||||
if (getters != null) {
|
||||
List<PsiMethod> validGetters = new ArrayList<PsiMethod>();
|
||||
for (PsiMethod getter : getters) {
|
||||
String newGetterName = GetterSetterPrototypeProvider.suggestNewGetterName(propertyName, newPropertyName, getter);
|
||||
String getterId = null;
|
||||
if (newGetterName == null) {
|
||||
getterId = getter.getName();
|
||||
newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getterId);
|
||||
}
|
||||
if (newGetterName.equals(getterId)) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
boolean valid = true;
|
||||
for (PsiMethod method : getter.findDeepestSuperMethods()) {
|
||||
if (method instanceof PsiCompiledElement) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!valid) continue;
|
||||
}
|
||||
validGetters.add(getter);
|
||||
}
|
||||
getters = validGetters.isEmpty() ? null : validGetters.toArray(new PsiMethod[validGetters.size()]);
|
||||
}
|
||||
|
||||
String newSetterName = "";
|
||||
@@ -201,14 +210,20 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
if ((getter != null || setter != null) && askToRenameAccesors(getter, setter, newName, project)) {
|
||||
getter = null;
|
||||
if ((getters != null || setter != null) && askToRenameAccesors(getters != null ? getters[0] : null, setter, newName, project)) {
|
||||
getters = null;
|
||||
setter = null;
|
||||
shouldRenameSetterParameter = false;
|
||||
}
|
||||
|
||||
if (getter != null) {
|
||||
addOverriddenAndImplemented(getter, newGetterName, allRenames);
|
||||
if (getters != null) {
|
||||
for (PsiMethod getter : getters) {
|
||||
String newGetterName = GetterSetterPrototypeProvider.suggestNewGetterName(propertyName, newPropertyName, getter);
|
||||
if (newGetterName == null) {
|
||||
newGetterName = PropertyUtil.suggestGetterName(newPropertyName, field.getType(), getter.getName());
|
||||
}
|
||||
addOverriddenAndImplemented(getter, newGetterName, allRenames);
|
||||
}
|
||||
}
|
||||
|
||||
if (setter != null) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.refactoring.safeDelete;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
|
||||
import com.intellij.codeInsight.generation.GetterSetterPrototypeProvider;
|
||||
import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
|
||||
import com.intellij.ide.util.SuperMethodWarningUtil;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
@@ -187,21 +188,30 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase {
|
||||
PsiClass aClass = field.getContainingClass();
|
||||
if (aClass != null) {
|
||||
boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
|
||||
PsiMethod getter = PropertyUtil.findPropertyGetter(aClass, propertyName, isStatic, false);
|
||||
if (allElementsToDelete.contains(getter) || getter != null && !getter.isPhysical()) getter = null;
|
||||
PsiMethod[] getters = GetterSetterPrototypeProvider.findGetters(aClass, propertyName, isStatic);
|
||||
if (getters != null) {
|
||||
final List<PsiMethod> validGetters = new ArrayList<PsiMethod>(1);
|
||||
for (PsiMethod getter : getters) {
|
||||
if (!allElementsToDelete.contains(getter) && (getter != null && getter.isPhysical())) {
|
||||
validGetters.add(getter);
|
||||
}
|
||||
}
|
||||
getters = validGetters.isEmpty() ? null : validGetters.toArray(new PsiMethod[validGetters.size()]);
|
||||
}
|
||||
|
||||
PsiMethod setter = PropertyUtil.findPropertySetter(aClass, propertyName, isStatic, false);
|
||||
if (allElementsToDelete.contains(setter) || setter != null && !setter.isPhysical()) setter = null;
|
||||
if (askUser && (getter != null || setter != null)) {
|
||||
if (askUser && (getters != null || setter != null)) {
|
||||
final String message =
|
||||
RefactoringMessageUtil.getGetterSetterMessage(field.getName(), RefactoringBundle.message("delete.title"), getter, setter);
|
||||
if (Messages.showYesNoDialog(project, message, RefactoringBundle.message("safe.delete.title"), Messages.getQuestionIcon()) != 0) {
|
||||
getter = null;
|
||||
RefactoringMessageUtil.getGetterSetterMessage(field.getName(), RefactoringBundle.message("delete.title"), getters != null ? getters[0] : null, setter);
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() && Messages.showYesNoDialog(project, message, RefactoringBundle.message("safe.delete.title"), Messages.getQuestionIcon()) != 0) {
|
||||
getters = null;
|
||||
setter = null;
|
||||
}
|
||||
}
|
||||
List<PsiElement> elements = new ArrayList<PsiElement>();
|
||||
if (setter != null) elements.add(setter);
|
||||
if (getter != null) elements.add(getter);
|
||||
if (getters != null) Collections.addAll(elements, getters);
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.javaFX;
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.openapi.application.PluginPathManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.rename.RenameProcessor;
|
||||
import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.javaFX.fxml.AbstractJavaFXTestCase;
|
||||
|
||||
public class RefactoringFieldTest extends AbstractJavaFXTestCase {
|
||||
|
||||
public void testPropertyRename() throws Exception {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
performRename("newName");
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
public void testPropertyDelete() throws Exception {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
performDelete();
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
protected void performRename(String newName) {
|
||||
PsiElement element = TargetElementUtilBase.findTargetElement(myFixture.getEditor(), TargetElementUtilBase
|
||||
.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
|
||||
|
||||
new RenameProcessor(getProject(), element, newName, false, false).run();
|
||||
}
|
||||
|
||||
private void performDelete() {
|
||||
final PsiElement psiElement = TargetElementUtilBase
|
||||
.findTargetElement(myFixture.getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
|
||||
assertNotNull("No element found in text:\n" + myFixture.getFile().getText(), psiElement);
|
||||
SafeDeleteHandler.invoke(getProject(), new PsiElement[]{psiElement}, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return PluginPathManager.getPluginHomePath("javaFX") + "/testData/fieldRefactoring/";
|
||||
}
|
||||
}
|
||||
@@ -81,6 +81,28 @@ public class JavaFxGetterSetterPrototypeProvider extends GetterSetterPrototypePr
|
||||
return new PsiMethod[] {setter};
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiMethod[] findGetters(PsiClass psiClass, String propertyName) {
|
||||
final String getterName = suggestGetterName(propertyName);
|
||||
final PsiMethod specificGetter = psiClass
|
||||
.findMethodBySignature(JavaPsiFacade.getElementFactory(psiClass.getProject()).createMethod(getterName, PsiType.VOID), false);
|
||||
if (specificGetter != null) {
|
||||
final PsiMethod getter = PropertyUtil.findPropertyGetter(psiClass, propertyName, false, false);
|
||||
return getter == null ? new PsiMethod[] {specificGetter} : new PsiMethod[] {getter, specificGetter};
|
||||
}
|
||||
return super.findGetters(psiClass, propertyName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String suggestGetterName(String propertyName) {
|
||||
return propertyName + "Property";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimpleGetter(PsiMethod method, String oldPropertyName) {
|
||||
return method.getName().equals(suggestGetterName(oldPropertyName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(PsiField field) {
|
||||
return !InheritanceUtil.isInheritor(field.getType(), JavaFxCommonClassNames.JAVAFX_BEANS_VALUE_WRITABLE_VALUE);
|
||||
|
||||
18
plugins/javaFX/testData/fieldRefactoring/PropertyDelete.java
Normal file
18
plugins/javaFX/testData/fieldRefactoring/PropertyDelete.java
Normal file
@@ -0,0 +1,18 @@
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
class Test {
|
||||
private IntegerProperty c<caret>ount = new SimpleIntegerProperty(this, "count");
|
||||
|
||||
public int getCount() {
|
||||
return count.get();
|
||||
}
|
||||
|
||||
public IntegerProperty countProperty() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count.set(count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
class Test {
|
||||
|
||||
}
|
||||
18
plugins/javaFX/testData/fieldRefactoring/PropertyRename.java
Normal file
18
plugins/javaFX/testData/fieldRefactoring/PropertyRename.java
Normal file
@@ -0,0 +1,18 @@
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
class Test {
|
||||
private IntegerProperty c<caret>ount = new SimpleIntegerProperty(this, "count");
|
||||
|
||||
public int getCount() {
|
||||
return count.get();
|
||||
}
|
||||
|
||||
public IntegerProperty countProperty() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count.set(count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import javafx.beans.property.IntegerProperty;
|
||||
import javafx.beans.property.SimpleIntegerProperty;
|
||||
|
||||
class Test {
|
||||
private IntegerProperty newName = new SimpleIntegerProperty(this, "count");
|
||||
|
||||
public int getNewName() {
|
||||
return newName.get();
|
||||
}
|
||||
|
||||
public IntegerProperty newNameProperty() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
public void setNewName(int newName) {
|
||||
this.newName.set(newName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user