javafx: Add properties defined with @NamedArg to the resources for inspection of redundant FXML attributes and tags, don't add to the resources properties having ambiguous definitions (IDEA-102276)

This commit is contained in:
Pavel Dolgov
2016-03-18 19:05:59 +03:00
parent 757e84aa9a
commit 9c7465fb1e
2 changed files with 248 additions and 25 deletions
@@ -2,6 +2,9 @@ package org.jetbrains.plugins.javaFX.fxml;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.NamedArg;
import javafx.beans.value.WritableValue;
import javafx.event.Event;
import javafx.geometry.NodeOrientation;
import javafx.geometry.Pos;
import javafx.scene.AccessibleRole;
@@ -154,6 +157,7 @@ public class JavaFxGenerateDefaultPropertyValuesScript extends Application {
bindings.add(methodDesc.getName());
}
}
Map<String, Object> constructorNamedArgValues = constructorNamedArgValues(currentClass);
Object instance = null;
for (PropertyDescriptor desc : info.getPropertyDescriptors()) {
@@ -162,15 +166,18 @@ public class JavaFxGenerateDefaultPropertyValuesScript extends Application {
if (ourSkippedProperties.contains(propQualifiedName)) continue;
final Method setter = desc.getWriteMethod();
final boolean hasBinding = bindings.contains(propName + "Property");
if (setter == null || !hasBinding) continue;
final Type type = setter.getGenericParameterTypes()[0];
if (type instanceof Class && isSupportedPropertyType((Class)type)) {
final Object value;
final Class<?> declaringClass;
final Type type;
if (setter != null &&
hasBinding &&
(type = setter.getGenericParameterTypes()[0]) instanceof Class &&
isSupportedPropertyType((Class)type)) {
if (instance == null) {
instance = instantiate(currentClass);
if (instance == null) break;
}
final Object value;
final Method getter = desc.getReadMethod();
try {
value = getter.invoke(instance);
@@ -178,29 +185,34 @@ public class JavaFxGenerateDefaultPropertyValuesScript extends Application {
catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException("Can't invoke " + getter + " on " + currentClass, e);
}
if (value != null) {
final Class<?> declaringClass = getter.getDeclaringClass();
final DefaultValue newValue = new DefaultValue(value, declaringClass.getName());
if (declaringClass.getName().startsWith("javafx")) {
defaultPropertyValues
.computeIfAbsent(currentClass.getName(), unused -> new TreeMap<>())
.put(propName, newValue);
}
declaringClass = getter.getDeclaringClass();
}
else {
value = constructorNamedArgValues.get(propName);
if (value == null) continue;
declaringClass = currentClass;
}
if (value != null) {
final DefaultValue newValue = new DefaultValue(value, declaringClass.getName());
if (declaringClass.getName().startsWith("javafx")) {
defaultPropertyValues
.computeIfAbsent(currentClass.getName(), unused -> new TreeMap<>())
.put(propName, newValue);
}
final Map<String, String> shareableProperties =
declaredProperties.computeIfAbsent(declaringClass.getName(), unused -> new TreeMap<>());
final String sharedValue = shareableProperties.get(propName);
final Map<String, String> shareableProperties =
declaredProperties.computeIfAbsent(declaringClass.getName(), unused -> new TreeMap<>());
final String sharedValue = shareableProperties.get(propName);
if (sharedValue == null) {
shareableProperties.put(propName, newValue.getValueText());
}
else if (!sharedValue.equals(newValue.getValueText())) {
final Set<String> multipleValues = overriddenProperties
.computeIfAbsent(declaringClass.getName(), unused -> new TreeMap<>())
.computeIfAbsent(propName, unused -> new TreeSet<>());
multipleValues.add(sharedValue);
multipleValues.add(newValue.getValueText());
}
if (sharedValue == null) {
shareableProperties.put(propName, newValue.getValueText());
}
else if (!sharedValue.equals(newValue.getValueText())) {
final Set<String> multipleValues = overriddenProperties
.computeIfAbsent(declaringClass.getName(), unused -> new TreeMap<>())
.computeIfAbsent(propName, unused -> new TreeSet<>());
multipleValues.add(sharedValue);
multipleValues.add(newValue.getValueText());
}
}
}
@@ -269,6 +281,124 @@ public class JavaFxGenerateDefaultPropertyValuesScript extends Application {
ourSkippedProperties.forEach(propName -> System.out.println("-- " + propName));
}
private static class Args implements Iterable<String> {
final Set<String> names = new TreeSet<>();
final Map<String, Set<Type>> types = new TreeMap<>();
final Map<String, Set<Object>> values = new TreeMap<>();
void add(String name, Class<?> type, Object value) {
names.add(name);
types.computeIfAbsent(name, n -> new HashSet<Type>()).add(type);
values.computeIfAbsent(name, n -> new HashSet<Object>()).add(value);
}
boolean isEmpty() {
return names.isEmpty();
}
@Override
public Iterator<String> iterator() {
return names.iterator();
}
public Type getType(String name) {
final Set<Type> typeSet = types.get(name);
if (typeSet != null && typeSet.size() == 1) {
return typeSet.iterator().next();
}
return null;
}
public Object getValue(String name) {
final Set<Object> valueSet = values.get(name);
if (valueSet != null && valueSet.size() == 1) {
return valueSet.iterator().next();
}
return null;
}
}
@NotNull
private static Map<String, Object> constructorNamedArgValues(Class<?> aClass) {
if (aClass.isInterface() ||
aClass.isAnnotation() ||
WritableValue.class.isAssignableFrom(aClass) ||
Event.class.isAssignableFrom(aClass)) {
return Collections.emptyMap();
}
final Constructor<?>[] constructors = aClass.getConstructors();
final Args args = new Args();
for (Constructor<?> constructor : constructors) {
final Parameter[] parameters = constructor.getParameters();
for (Parameter parameter : parameters) {
final Class<?> type = parameter.getType();
if (type.isPrimitive() || type.isEnum() || type == String.class) {
final NamedArg namedArg = parameter.getAnnotation(NamedArg.class);
if (namedArg == null) continue;
final String name = namedArg.value();
if (!name.isEmpty()) {
final String defaultValue = namedArg.defaultValue();
if ((type == String.class || type.isEnum()) && !defaultValue.isEmpty() && !"\"\"".equals(defaultValue)) {
args.add(name, type, defaultValue);
}
else if (type == boolean.class) {
args.add(name, type, Boolean.valueOf(defaultValue));
}
else if (type == int.class) {
try {
args.add(name, type, Integer.valueOf(defaultValue));
}
catch (NumberFormatException e) {
args.add(name, type, Integer.valueOf(0));
}
}
else if (type == long.class) {
try {
args.add(name, type, Long.valueOf(defaultValue));
}
catch (NumberFormatException e) {
args.add(name, type, Long.valueOf(0));
}
}
else if (type == double.class) {
try {
args.add(name, type, Double.valueOf(defaultValue));
}
catch (NumberFormatException e) {
args.add(name, type, Double.valueOf(0));
}
}
else if (type == float.class) {
try {
args.add(name, type, Float.valueOf(defaultValue));
}
catch (NumberFormatException e) {
args.add(name, type, Float.valueOf(0));
}
}
else if (!type.isEnum() && type != String.class) {
System.err.println("pri " + type);
}
}
}
}
}
if (args.isEmpty()) return Collections.emptyMap();
Map<String, Object> result = new TreeMap<>();
for (String name : args) {
final Type type = args.getType(name);
if (type != null) {
final Object value = args.getValue(name);
if (value != null) {
result.put(name, value);
}
}
}
return result;
}
private static boolean areValuesEqual(DefaultValue first, DefaultValue second) {
return second.getValueText().equals(first.getValueText());
}
@@ -77,9 +77,34 @@ javafx.animation.TranslateTransition#fromZ=NaN
javafx.animation.TranslateTransition#toX=NaN
javafx.animation.TranslateTransition#toY=NaN
javafx.animation.TranslateTransition#toZ=NaN
javafx.geometry.BoundingBox#depth=0.0
javafx.geometry.BoundingBox#height=0.0
javafx.geometry.BoundingBox#minX=0.0
javafx.geometry.BoundingBox#minY=0.0
javafx.geometry.BoundingBox#minZ=0.0
javafx.geometry.BoundingBox#width=0.0
javafx.geometry.Dimension2D#height=0.0
javafx.geometry.Dimension2D#width=0.0
javafx.geometry.Insets#bottom=0.0
javafx.geometry.Insets#left=0.0
javafx.geometry.Insets#right=0.0
javafx.geometry.Insets#top=0.0
javafx.geometry.Point2D#x=0.0
javafx.geometry.Point2D#y=0.0
javafx.geometry.Point3D#x=0.0
javafx.geometry.Point3D#y=0.0
javafx.geometry.Point3D#z=0.0
javafx.geometry.Rectangle2D#height=0.0
javafx.geometry.Rectangle2D#minX=0.0
javafx.geometry.Rectangle2D#minY=0.0
javafx.geometry.Rectangle2D#width=0.0
javafx.print.PageRange#endPage=0
javafx.print.PageRange#startPage=0
javafx.scene.Camera#farClip=100.0
javafx.scene.Camera#nearClip=0.1
javafx.scene.Group#autoSizeChildren=true
javafx.scene.ImageCursor#hotspotX=0.0
javafx.scene.ImageCursor#hotspotY=0.0
javafx.scene.LightBase#lightOn=true
javafx.scene.Node#cache=false
javafx.scene.Node#cacheHint=DEFAULT
@@ -101,6 +126,7 @@ javafx.scene.Node#translateZ=0.0
javafx.scene.Node#visible=true
javafx.scene.PerspectiveCamera#fieldOfView=30.0
javafx.scene.PerspectiveCamera#verticalFieldOfView=true
javafx.scene.Scene#depthBuffer=false
javafx.scene.canvas.Canvas#height=0.0
javafx.scene.canvas.Canvas#width=0.0
javafx.scene.chart.Axis#animated=true
@@ -149,6 +175,8 @@ javafx.scene.control.Dialog#resizable=false
javafx.scene.control.Dialog#title=Confirmation
javafx.scene.control.DialogPane#expanded=false
javafx.scene.control.Hyperlink#visited=false
javafx.scene.control.IndexRange#end=0
javafx.scene.control.IndexRange#start=0
javafx.scene.control.Labeled#contentDisplay=LEFT
javafx.scene.control.Labeled#ellipsisString=...
javafx.scene.control.Labeled#graphicTextGap=4.0
@@ -237,6 +265,7 @@ javafx.scene.control.TableColumnBase#sortable=true
javafx.scene.control.TableColumnBase#style=
javafx.scene.control.TableColumnBase#text=
javafx.scene.control.TableColumnBase#visible=true
javafx.scene.control.TablePosition#row=0
javafx.scene.control.TableView#editable=false
javafx.scene.control.TableView#fixedCellSize=-1.0
javafx.scene.control.TableView#tableMenuButtonVisible=false
@@ -263,6 +292,7 @@ javafx.scene.control.Tooltip#textOverrun=ELLIPSIS
javafx.scene.control.Tooltip#wrapText=false
javafx.scene.control.TreeItem#expanded=false
javafx.scene.control.TreeTableColumn#sortType=ASCENDING
javafx.scene.control.TreeTablePosition#row=0
javafx.scene.control.TreeTableView#editable=false
javafx.scene.control.TreeTableView#fixedCellSize=-1.0
javafx.scene.control.TreeTableView#showRoot=true
@@ -346,17 +376,57 @@ javafx.scene.effect.Shadow#blurType=THREE_PASS_BOX
javafx.scene.effect.Shadow#height=21.0
javafx.scene.effect.Shadow#radius=10.0
javafx.scene.effect.Shadow#width=21.0
javafx.scene.image.Image#backgroundLoading=false
javafx.scene.image.Image#preserveRatio=false
javafx.scene.image.Image#requestedHeight=0.0
javafx.scene.image.Image#requestedWidth=0.0
javafx.scene.image.ImageView#fitHeight=0.0
javafx.scene.image.ImageView#fitWidth=0.0
javafx.scene.image.ImageView#preserveRatio=false
javafx.scene.image.ImageView#smooth=true
javafx.scene.image.ImageView#x=0.0
javafx.scene.image.ImageView#y=0.0
javafx.scene.image.WritableImage#height=0
javafx.scene.image.WritableImage#width=0
javafx.scene.input.TouchPoint#id=0
javafx.scene.input.TouchPoint#screenX=0.0
javafx.scene.input.TouchPoint#screenY=0.0
javafx.scene.input.TouchPoint#x=0.0
javafx.scene.input.TouchPoint#y=0.0
javafx.scene.layout.BackgroundPosition#horizontalAsPercentage=false
javafx.scene.layout.BackgroundPosition#horizontalPosition=0.0
javafx.scene.layout.BackgroundPosition#verticalAsPercentage=false
javafx.scene.layout.BackgroundPosition#verticalPosition=0.0
javafx.scene.layout.BackgroundSize#contain=false
javafx.scene.layout.BackgroundSize#cover=false
javafx.scene.layout.BackgroundSize#height=0.0
javafx.scene.layout.BackgroundSize#heightAsPercentage=false
javafx.scene.layout.BackgroundSize#width=0.0
javafx.scene.layout.BackgroundSize#widthAsPercentage=false
javafx.scene.layout.BorderImage#filled=false
javafx.scene.layout.BorderStrokeStyle#dashOffset=0.0
javafx.scene.layout.BorderStrokeStyle#miterLimit=0.0
javafx.scene.layout.BorderWidths#bottom=0.0
javafx.scene.layout.BorderWidths#bottomAsPercentage=false
javafx.scene.layout.BorderWidths#left=0.0
javafx.scene.layout.BorderWidths#leftAsPercentage=false
javafx.scene.layout.BorderWidths#right=0.0
javafx.scene.layout.BorderWidths#rightAsPercentage=false
javafx.scene.layout.BorderWidths#top=0.0
javafx.scene.layout.BorderWidths#topAsPercentage=false
javafx.scene.layout.ColumnConstraints#fillWidth=true
javafx.scene.layout.ColumnConstraints#maxWidth=-1.0
javafx.scene.layout.ColumnConstraints#minWidth=-1.0
javafx.scene.layout.ColumnConstraints#percentWidth=-1.0
javafx.scene.layout.ColumnConstraints#prefWidth=-1.0
javafx.scene.layout.CornerRadii#bottomLeftHorizontalRadius=0.0
javafx.scene.layout.CornerRadii#bottomLeftVerticalRadius=0.0
javafx.scene.layout.CornerRadii#bottomRightHorizontalRadius=0.0
javafx.scene.layout.CornerRadii#bottomRightVerticalRadius=0.0
javafx.scene.layout.CornerRadii#topLeftHorizontalRadius=0.0
javafx.scene.layout.CornerRadii#topLeftVerticalRadius=0.0
javafx.scene.layout.CornerRadii#topRightHorizontalRadius=0.0
javafx.scene.layout.CornerRadii#topRightVerticalRadius=0.0
javafx.scene.layout.FlowPane#alignment=TOP_LEFT
javafx.scene.layout.FlowPane#columnHalignment=LEFT
javafx.scene.layout.FlowPane#hgap=0.0
@@ -408,7 +478,28 @@ javafx.scene.media.MediaView#preserveRatio=true
javafx.scene.media.MediaView#smooth=true
javafx.scene.media.MediaView#x=0.0
javafx.scene.media.MediaView#y=0.0
javafx.scene.paint.Color#blue=0.0
javafx.scene.paint.Color#green=0.0
javafx.scene.paint.Color#opacity=1.0
javafx.scene.paint.Color#red=0.0
javafx.scene.paint.ImagePattern#height=0.0
javafx.scene.paint.ImagePattern#proportional=false
javafx.scene.paint.ImagePattern#width=0.0
javafx.scene.paint.ImagePattern#x=0.0
javafx.scene.paint.ImagePattern#y=0.0
javafx.scene.paint.LinearGradient#endX=1.0
javafx.scene.paint.LinearGradient#endY=1.0
javafx.scene.paint.LinearGradient#proportional=true
javafx.scene.paint.LinearGradient#startX=0.0
javafx.scene.paint.LinearGradient#startY=0.0
javafx.scene.paint.PhongMaterial#specularPower=32.0
javafx.scene.paint.RadialGradient#centerX=0.0
javafx.scene.paint.RadialGradient#centerY=0.0
javafx.scene.paint.RadialGradient#focusAngle=0.0
javafx.scene.paint.RadialGradient#focusDistance=0.0
javafx.scene.paint.RadialGradient#proportional=true
javafx.scene.paint.RadialGradient#radius=1.0
javafx.scene.paint.Stop#offset=0.0
javafx.scene.shape.Arc#centerX=0.0
javafx.scene.shape.Arc#centerY=0.0
javafx.scene.shape.Arc#length=0.0
@@ -489,6 +580,7 @@ javafx.scene.shape.Shape3D#cullFace=BACK
javafx.scene.shape.Shape3D#drawMode=FILL
javafx.scene.shape.Sphere#radius=1.0
javafx.scene.shape.VLineTo#y=0.0
javafx.scene.text.Font#size=0.0
javafx.scene.text.Text#boundsType=LOGICAL
javafx.scene.text.Text#fontSmoothingType=GRAY
javafx.scene.text.Text#impl_caretBias=true
@@ -535,6 +627,7 @@ javafx.scene.transform.Shear#y=0.0
javafx.scene.transform.Translate#x=0.0
javafx.scene.transform.Translate#y=0.0
javafx.scene.transform.Translate#z=0.0
javafx.scene.web.PopupFeatures#resizable=false
javafx.scene.web.WebEngine#javaScriptEnabled=true
javafx.scene.web.WebView#contextMenuEnabled=true
javafx.scene.web.WebView#fontScale=1.0