Javafx: Simplify properties search and renaming in FXML. Fix NPE (IDEA-105038, IDEA-105231)

This commit is contained in:
Pavel Dolgov
2016-05-04 15:28:06 +03:00
parent f6e393fd4d
commit 669c1114df
3 changed files with 33 additions and 27 deletions
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.xml.XmlElementDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
@@ -71,7 +72,8 @@ abstract class JavaFxImportClassFix extends ImportClassFixBase<XmlTag, JavaFxTag
@Override
protected String getQualifiedName(XmlTag tag) {
return tag.getDescriptor().getQualifiedName();
final XmlElementDescriptor descriptor = tag.getDescriptor();
return descriptor != null ? descriptor.getQualifiedName() : tag.getName();
}
@Override
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.javaFX.fxml.refs;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.cache.CacheManager;
@@ -29,6 +30,7 @@ import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
@@ -104,27 +106,29 @@ public class JavaFxMethodSearcher implements QueryExecutor<PsiReference, Referen
private static boolean searchMethodInFile(@NotNull PsiMethod psiMethod,
@NotNull PsiFile file,
@NotNull Processor<PsiReference> consumer) {
class StopException extends RuntimeException {
}
try {
file.accept(new XmlRecursiveElementVisitor() {
@Override
public void visitXmlAttribute(XmlAttribute attribute) {
final PsiReference[] references = attribute.getReferences();
for (PsiReference reference : references) {
if ((reference instanceof JavaFxStaticPropertyReference || reference instanceof JavaFxEventHandlerReference) &&
reference.isReferenceTo(psiMethod)) {
if (!consumer.process(reference)) {
throw new StopException();
}
final Ref<Boolean> stopped = new Ref<>(false);
file.accept(new XmlRecursiveElementVisitor() {
@Override
public void visitXmlElement(XmlElement element) {
if (stopped.get()) return;
super.visitXmlElement(element);
}
@Override
public void visitXmlAttribute(XmlAttribute attribute) {
if (stopped.get()) return;
final PsiReference[] references = attribute.getReferences();
for (PsiReference reference : references) {
if ((reference instanceof JavaFxStaticPropertyReference || reference instanceof JavaFxEventHandlerReference) &&
reference.isReferenceTo(psiMethod)) {
if (!consumer.process(reference)) {
stopped.set(true);
return;
}
}
}
});
return true;
}
catch (StopException unused) {
return false;
}
}
});
return !stopped.get();
}
}
@@ -138,17 +138,17 @@ public class JavaFxPropertyRenameHandler implements RenameHandler {
@NotNull
private static Map<PsiElement, String> getElementsToRename(@NotNull JavaFxPropertyReference reference, @NotNull String newPropertyName) {
final Map<PsiElement, String> rename = new THashMap<>();
putIfKeyNotNull(rename, reference.getGetter(), () -> PropertyUtil.suggestGetterName(newPropertyName, reference.getType()));
putIfKeyNotNull(rename, reference.getField(), () -> newPropertyName);
putIfKeyNotNull(rename, reference.getSetter(), () -> PropertyUtil.suggestSetterName(newPropertyName));
putIfKeyNotNull(rename, reference.getObservableGetter(), () -> newPropertyName + JavaFxCommonNames.PROPERTY_METHOD_SUFFIX);
putIfKeyNotNull(rename, reference.getStaticSetter(), () -> PropertyUtil.suggestSetterName(newPropertyName));
putIfKeyNotNull(rename, reference.getGetter(), PropertyUtil.suggestGetterName(newPropertyName, reference.getType()));
putIfKeyNotNull(rename, reference.getField(), newPropertyName);
putIfKeyNotNull(rename, reference.getSetter(), PropertyUtil.suggestSetterName(newPropertyName));
putIfKeyNotNull(rename, reference.getObservableGetter(), newPropertyName + JavaFxCommonNames.PROPERTY_METHOD_SUFFIX);
putIfKeyNotNull(rename, reference.getStaticSetter(), PropertyUtil.suggestSetterName(newPropertyName));
//TODO add "name" parameter of the observable property constructor (like new SimpleObjectProperty(this, "name", null);
return rename;
}
private static <K, V> void putIfKeyNotNull(Map<K, V> map, K key, NotNullProducer<V> valueProducer) {
if (key != null) map.put(key, valueProducer.produce());
private static <K, V> void putIfKeyNotNull(@NotNull Map<K, V> map, @Nullable K key, @NotNull V value) {
if (key != null) map.put(key, value);
}
private static class PropertyRenameDialog extends RenameDialog {