From cc5ab52b0202cd9b515db15d832f4edbba081a15 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Mon, 2 Nov 2020 10:06:07 +0100 Subject: [PATCH] Added implementation for FxProperty --- src/core/lombok/ConfigurationKeys.java | 9 + .../lombok/core/handlers/HandlerUtil.java | 12 + .../eclipse/handlers/HandleFxProperty.java | 360 ++++++++++++++++++ src/core/lombok/extern/javafx/FxProperty.java | 89 +++++ .../javac/handlers/HandleFxProperty.java | 316 +++++++++++++++ .../beans/property/BooleanProperty.java | 5 + .../javafx/beans/property/DoubleProperty.java | 5 + .../javafx/beans/property/FloatProperty.java | 5 + .../beans/property/IntegerProperty.java | 5 + .../javafx/beans/property/ListProperty.java | 8 + .../javafx/beans/property/LongProperty.java | 5 + .../javafx/beans/property/MapProperty.java | 7 + .../javafx/beans/property/ObjectProperty.java | 6 + .../stubs/javafx/beans/property/Property.java | 5 + .../property/ReadOnlyBooleanProperty.java | 5 + .../property/ReadOnlyDoubleProperty.java | 5 + .../beans/property/ReadOnlyFloatProperty.java | 5 + .../property/ReadOnlyIntegerProperty.java | 5 + .../beans/property/ReadOnlyListProperty.java | 8 + .../beans/property/ReadOnlyLongProperty.java | 5 + .../beans/property/ReadOnlyMapProperty.java | 7 + .../property/ReadOnlyObjectProperty.java | 6 + .../beans/property/ReadOnlyProperty.java | 5 + .../beans/property/ReadOnlySetProperty.java | 7 + .../property/ReadOnlyStringProperty.java | 5 + .../javafx/beans/property/SetProperty.java | 8 + .../javafx/beans/property/StringProperty.java | 6 + .../javafx/collections/ObservableList.java | 5 + .../javafx/collections/ObservableMap.java | 5 + .../javafx/collections/ObservableSet.java | 5 + .../after-delombok/FxPropertyExisting.java | 18 + .../after-delombok/FxPropertyOnClass.java | 275 +++++++++++++ .../after-delombok/FxPropertyReadOnly.java | 32 ++ .../after-delombok/FxPropertySimple.java | 275 +++++++++++++ .../after-ecj/FxPropertyExisting.java | 18 + .../resource/after-ecj/FxPropertyOnClass.java | 178 +++++++++ .../after-ecj/FxPropertyReadOnly.java | 25 ++ .../resource/after-ecj/FxPropertySimple.java | 178 +++++++++ .../resource/before/FxPropertyExisting.java | 20 + .../resource/before/FxPropertyOnClass.java | 29 ++ .../resource/before/FxPropertyReadOnly.java | 10 + .../resource/before/FxPropertySimple.java | 28 ++ 42 files changed, 2015 insertions(+) create mode 100644 src/core/lombok/eclipse/handlers/HandleFxProperty.java create mode 100644 src/core/lombok/extern/javafx/FxProperty.java create mode 100644 src/core/lombok/javac/handlers/HandleFxProperty.java create mode 100644 test/stubs/javafx/beans/property/BooleanProperty.java create mode 100644 test/stubs/javafx/beans/property/DoubleProperty.java create mode 100644 test/stubs/javafx/beans/property/FloatProperty.java create mode 100644 test/stubs/javafx/beans/property/IntegerProperty.java create mode 100644 test/stubs/javafx/beans/property/ListProperty.java create mode 100644 test/stubs/javafx/beans/property/LongProperty.java create mode 100644 test/stubs/javafx/beans/property/MapProperty.java create mode 100644 test/stubs/javafx/beans/property/ObjectProperty.java create mode 100644 test/stubs/javafx/beans/property/Property.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyBooleanProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyDoubleProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyFloatProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyIntegerProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyListProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyLongProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyMapProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyObjectProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlySetProperty.java create mode 100644 test/stubs/javafx/beans/property/ReadOnlyStringProperty.java create mode 100644 test/stubs/javafx/beans/property/SetProperty.java create mode 100644 test/stubs/javafx/beans/property/StringProperty.java create mode 100644 test/stubs/javafx/collections/ObservableList.java create mode 100644 test/stubs/javafx/collections/ObservableMap.java create mode 100644 test/stubs/javafx/collections/ObservableSet.java create mode 100644 test/transform/resource/after-delombok/FxPropertyExisting.java create mode 100644 test/transform/resource/after-delombok/FxPropertyOnClass.java create mode 100644 test/transform/resource/after-delombok/FxPropertyReadOnly.java create mode 100644 test/transform/resource/after-delombok/FxPropertySimple.java create mode 100644 test/transform/resource/after-ecj/FxPropertyExisting.java create mode 100644 test/transform/resource/after-ecj/FxPropertyOnClass.java create mode 100644 test/transform/resource/after-ecj/FxPropertyReadOnly.java create mode 100644 test/transform/resource/after-ecj/FxPropertySimple.java create mode 100644 test/transform/resource/before/FxPropertyExisting.java create mode 100644 test/transform/resource/before/FxPropertyOnClass.java create mode 100644 test/transform/resource/before/FxPropertyReadOnly.java create mode 100644 test/transform/resource/before/FxPropertySimple.java diff --git a/src/core/lombok/ConfigurationKeys.java b/src/core/lombok/ConfigurationKeys.java index 05550a06b0..a345b33435 100644 --- a/src/core/lombok/ConfigurationKeys.java +++ b/src/core/lombok/ConfigurationKeys.java @@ -678,6 +678,15 @@ private ConfigurationKeys() {} */ public static final ConfigurationKey JACKSONIZED_FLAG_USAGE = new ConfigurationKey("lombok.jacksonized.flagUsage", "Emit a warning or error if @Jacksonized is used.") {}; + // ----- FxProperty ----- + + /** + * lombok configuration: {@code lombok.fxproperty.flagUsage} = {@code WARNING} | {@code ERROR}. + * + * If set, any usage of {@code @FxProperty} results in a warning / error. + */ + public static final ConfigurationKey FXPROPERTY_FLAG_USAGE = new ConfigurationKey("lombok.fxproperty.flagUsage", "Emit a warning or error if @FxProperty is used.") {}; + // ----- Configuration System ----- /** diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java index c00b5dca5b..51066c40d0 100644 --- a/src/core/lombok/core/handlers/HandlerUtil.java +++ b/src/core/lombok/core/handlers/HandlerUtil.java @@ -563,6 +563,18 @@ public static String toWithName(AST ast, AnnotationValues ac return toAccessorName(ast, accessors, fieldName, isBoolean, "with", "with", false); } + /** + * Generates a property name from a given field name. + * + * Strategy: Take the field name and append {@code "Property"} at the end. + * + * @param fieldName the name of the field. + * @return The property name for this field. + */ + public static String toPropertyName(CharSequence fieldName) { + return fieldName + "Property"; + } + /** * Generates a withBy name from a given field name. * diff --git a/src/core/lombok/eclipse/handlers/HandleFxProperty.java b/src/core/lombok/eclipse/handlers/HandleFxProperty.java new file mode 100644 index 0000000000..3bedc4fae3 --- /dev/null +++ b/src/core/lombok/eclipse/handlers/HandleFxProperty.java @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2020-2021 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.eclipse.handlers; + +import static lombok.core.handlers.HandlerUtil.*; +import static lombok.eclipse.Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.jdt.internal.compiler.ast.Annotation; +import org.eclipse.jdt.internal.compiler.ast.Argument; +import org.eclipse.jdt.internal.compiler.ast.Expression; +import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.MessageSend; +import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.NameReference; +import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; +import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; +import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; +import org.eclipse.jdt.internal.compiler.ast.TypeReference; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.lookup.TypeIds; + +import lombok.ConfigurationKeys; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.handlers.HandlerUtil.FieldAccess; +import lombok.eclipse.Eclipse; +import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult; +import lombok.extern.javafx.FxProperty; +import lombok.spi.Provides; + +/** + * Handles the {@link FxProperty} annotation for eclipse. + */ +@Provides +public class HandleFxProperty extends EclipseAnnotationHandler { + + @Override public void handle(AnnotationValues annotation, Annotation ast, EclipseNode annotationNode) { + handleFlagUsage(annotationNode, ConfigurationKeys.FXPROPERTY_FLAG_USAGE, "@FxProperty"); + + Collection fields = annotationNode.upFromAnnotationToFields(); + EclipseNode node = annotationNode.up(); + FxProperty annotationInstance = annotation.getInstance(); + boolean readOnly = annotationInstance.readOnly(); + + if (node == null) return; + + switch (node.getKind()) { + case FIELD: + createFxPropertyForFields(fields, annotationNode, readOnly); + break; + case TYPE: + createFxPropertyForType(node, annotationNode, readOnly); + break; + } + } + + private void createFxPropertyForType(EclipseNode typeNode, EclipseNode annotationNode, boolean readOnly) { + TypeDeclaration typeDecl = (TypeDeclaration) typeNode.get(); + boolean notClassOrEnum = (typeDecl.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; + if (notClassOrEnum) { + annotationNode.addError("@FxProperty is only supported on a class, an enum, or a field."); + return; + } + for (EclipseNode field : typeNode.down()) { + if (field.getKind() != Kind.FIELD) continue; + if (field.getName().startsWith("$")) continue; + + createFxPropertyForField(field, annotationNode, readOnly, false); + } + } + + private void createFxPropertyForFields(Collection fields, EclipseNode annotationNode, boolean readOnly) { + for (EclipseNode field : fields) { + createFxPropertyForField(field, annotationNode, readOnly, true); + } + } + + private void createFxPropertyForField(EclipseNode fieldNode, EclipseNode source, boolean readOnly, boolean whine) { + FieldDeclaration fieldDecl = (FieldDeclaration) fieldNode.get(); + EclipseNode typeNode = upToTypeNode(fieldNode); + + FieldInfo fieldInfo = getFieldInfo(fieldNode, fieldDecl); + if (fieldInfo == null) { + if (whine) source.addError("@FxProperty is only supported on predefined JavaFx property types."); + return; + } + + addPropertyAccessor(fieldNode, source, typeNode, fieldInfo, readOnly); + addGetter(fieldNode, source, typeNode, fieldInfo); + addSetter(fieldNode, source, typeNode, fieldInfo, readOnly); + } + + private void addGetter(EclipseNode fieldNode, EclipseNode source, EclipseNode typeNode, FieldInfo fieldInfo) { + String methodName = buildAccessorName(fieldNode, "get", fieldNode.getName()); + if (methodExists(methodName, typeNode, 0) != MemberExistsResult.NOT_EXISTS) { + return; + } + + TypeDeclaration parent = (TypeDeclaration) upToTypeNode(fieldNode).get(); + + MethodDeclaration method = createGetter(fieldNode, fieldInfo); + method.traverse(new SetGeneratedByVisitor(source.get()), parent.scope); + + injectMethod(typeNode, method); + } + + private void addSetter(EclipseNode fieldNode, EclipseNode source, EclipseNode typeNode, FieldInfo fieldInfo, boolean readOnly) { + if (fieldInfo.readOnly) return; + + String methodName = buildAccessorName(fieldNode, "set", fieldNode.getName()); + if (methodExists(methodName, typeNode, 1) != MemberExistsResult.NOT_EXISTS) { + return; + } + + TypeDeclaration parent = (TypeDeclaration) upToTypeNode(fieldNode).get(); + + MethodDeclaration method = createSetter(fieldNode, fieldInfo, readOnly); + method.traverse(new SetGeneratedByVisitor(source.get()), parent.scope); + + injectMethod(typeNode, method); + } + + private void addPropertyAccessor(EclipseNode fieldNode, EclipseNode source, EclipseNode typeNode, FieldInfo fieldInfo, boolean readOnly) { + String methodName = toPropertyName(fieldNode.getName()); + if (methodExists(methodName, typeNode, 0) != MemberExistsResult.NOT_EXISTS) { + return; + } + + TypeDeclaration parent = (TypeDeclaration) upToTypeNode(fieldNode).get(); + + MethodDeclaration method = createPropertyAccessor(fieldNode, fieldInfo, readOnly); + method.traverse(new SetGeneratedByVisitor(source.get()), parent.scope); + + injectMethod(typeNode, method); + } + + + private MethodDeclaration createPropertyAccessor(EclipseNode fieldNode, FieldInfo fieldInfo, boolean readOnly) { + String methodName = toPropertyName(fieldNode.getName()); + + TypeDeclaration parent = (TypeDeclaration) upToTypeNode(fieldNode).get(); + + Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, null); + Statement returnStatement = new ReturnStatement(fieldRef, 0, 0); + + MethodDeclaration method = new MethodDeclaration(parent.compilationResult); + method.modifiers = ClassFileConstants.AccPublic; + method.returnType = fieldInfo.getPropertyType(readOnly); + method.selector = methodName.toCharArray(); + method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; + method.statements = new Statement[] {returnStatement}; + + return method; + } + + private MethodDeclaration createSetter(EclipseNode fieldNode, FieldInfo fieldInfo, boolean readOnly) { + String methodName = buildAccessorName(fieldNode, "set", fieldNode.getName()); + + TypeDeclaration parent = (TypeDeclaration) upToTypeNode(fieldNode).get(); + + char[] paramName = fieldNode.getName().toCharArray(); + Argument param = new Argument(paramName, 0, fieldInfo.getType(), Modifier.FINAL); + + Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, null); + NameReference fieldNameRef = new SingleNameReference(paramName, 0); + + MessageSend set = new MessageSend(); + set.receiver = fieldRef; + set.selector = "set".toCharArray(); + set.arguments = new Expression [] {fieldNameRef}; + + MethodDeclaration method = new MethodDeclaration(parent.compilationResult); + method.modifiers = ClassFileConstants.AccFinal | (readOnly ? ClassFileConstants.AccPrivate : ClassFileConstants.AccPublic); + method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0); + method.selector = methodName.toCharArray(); + method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; + method.arguments = new Argument[] {param}; + method.statements = new Statement[] {set}; + + return method; + } + + private MethodDeclaration createGetter(EclipseNode fieldNode, FieldInfo fieldInfo) { + String methodName = buildAccessorName(fieldNode, "get", fieldNode.getName()); + + TypeDeclaration parent = (TypeDeclaration) upToTypeNode(fieldNode).get(); + + Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, null); + + MessageSend get = new MessageSend(); + get.receiver = fieldRef; + get.selector = "get".toCharArray(); + + Statement returnStatement = new ReturnStatement(get, 0, 0); + + MethodDeclaration method = new MethodDeclaration(parent.compilationResult); + method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccFinal; + method.returnType = fieldInfo.getType(); + method.selector = methodName.toCharArray(); + method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; + method.statements = new Statement[] {returnStatement}; + + return method; + } + + static class FieldInfo { + EclipseNode fieldNode; + String propertyType; + String returnType; + boolean readOnly; + private TypeReference[] typeArguments; + + FieldInfo(EclipseNode fieldNode, String propertyType, String returnType) { + this.fieldNode = fieldNode; + this.propertyType = propertyType; + this.returnType = returnType; + this.readOnly = propertyType.contains("ReadOnly"); + } + + FieldInfo(EclipseNode fieldNode, String propertyType, String returnType, TypeReference[] typeArguments) { + this(fieldNode, propertyType, returnType); + this.typeArguments = typeArguments; + } + + TypeReference getType() { + Integer primitiveType = PRIMITIVE_TYPE_MAP.get(returnType); + if (primitiveType != null) { + return TypeReference.baseTypeReference(primitiveType, 0); + } + + if (returnType.endsWith("Object")) { + return copyType(typeArguments[0]); + } + + char[][] qualifiedName = Eclipse.fromQualifiedName(returnType); + if (typeArguments == null) { + return generateQualifiedTypeRef(fieldNode.get(), qualifiedName); + } + + long[] p = Eclipse.poss(fieldNode.get(), qualifiedName.length); + TypeReference[][] rr = new TypeReference[qualifiedName.length][]; + rr[rr.length - 1] = copyTypes(typeArguments, fieldNode.get()); + return new ParameterizedQualifiedTypeReference(qualifiedName, rr, 0, p); + } + + TypeReference getPropertyType(boolean asReadOnly) { + String type = propertyType; + if (asReadOnly && !readOnly) { + type = "javafx.beans.property.ReadOnly" + propertyType.substring(22); + } + char[][] qualifiedName = Eclipse.fromQualifiedName(type); + if (typeArguments == null) { + return generateQualifiedTypeRef(fieldNode.get(), qualifiedName); + } + + long[] p = Eclipse.poss(fieldNode.get(), qualifiedName.length); + TypeReference[][] rr = new TypeReference[qualifiedName.length][]; + rr[rr.length - 1] = copyTypes(typeArguments, fieldNode.get()); + return new ParameterizedQualifiedTypeReference(qualifiedName, rr, 0, p); + } + } + + private static Map SIMPLE_PROPERTY_TYPE_MAP; + private static Map GENERIC_PROPERTY_TYPE_MAP; + static { + Map m = new HashMap(); + m.put("javafx.beans.property.ObjectProperty", "java.lang.Object"); + m.put("javafx.beans.property.ListProperty", "javafx.collections.ObservableList"); + m.put("javafx.beans.property.MapProperty", "javafx.collections.ObservableMap"); + m.put("javafx.beans.property.SetProperty", "javafx.collections.ObservableSet"); + + m.put("javafx.beans.property.ReadOnlyObjectProperty", "java.lang.Object"); + m.put("javafx.beans.property.ReadOnlyListProperty", "javafx.collections.ObservableList"); + m.put("javafx.beans.property.ReadOnlyMapProperty", "javafx.collections.ObservableMap"); + m.put("javafx.beans.property.ReadOnlySetProperty", "javafx.collections.ObservableSet"); + GENERIC_PROPERTY_TYPE_MAP = Collections.unmodifiableMap(m); + + m.put("javafx.beans.property.IntegerProperty", "java.lang.Integer"); + m.put("javafx.beans.property.LongProperty", "java.lang.Long"); + m.put("javafx.beans.property.FloatProperty", "java.lang.Float"); + m.put("javafx.beans.property.DoubleProperty", "java.lang.Double"); + m.put("javafx.beans.property.BooleanProperty", "java.lang.Boolean"); + m.put("javafx.beans.property.StringProperty", "java.lang.String"); + + m.put("javafx.beans.property.ReadOnlyIntegerProperty", "java.lang.Integer"); + m.put("javafx.beans.property.ReadOnlyLongProperty", "java.lang.Long"); + m.put("javafx.beans.property.ReadOnlyFloatProperty", "java.lang.Float"); + m.put("javafx.beans.property.ReadOnlyDoubleProperty", "java.lang.Double"); + m.put("javafx.beans.property.ReadOnlyBooleanProperty", "java.lang.Boolean"); + m.put("javafx.beans.property.ReadOnlyStringProperty", "java.lang.String"); + SIMPLE_PROPERTY_TYPE_MAP = Collections.unmodifiableMap(m); + } + + private static Map PRIMITIVE_TYPE_MAP; + static { + Map m = new HashMap(); + m.put("java.lang.Integer", TypeIds.T_int); + m.put("java.lang.Long", TypeIds.T_long); + m.put("java.lang.Float", TypeIds.T_float); + m.put("java.lang.Double", TypeIds.T_double); + m.put("java.lang.Boolean", TypeIds.T_boolean); + PRIMITIVE_TYPE_MAP = Collections.unmodifiableMap(m); + } + + private FieldInfo getFieldInfo(EclipseNode fieldNode, FieldDeclaration fieldDecl) { + TypeReference vartype = fieldDecl.type; + + if (vartype.getTypeArguments() != null) { + if (vartype.getTypeArguments().length != 1) { + return null; + } + TypeReference[] arguments = vartype.getTypeArguments()[0]; + + for (Entry property : GENERIC_PROPERTY_TYPE_MAP.entrySet()) { + if (typeMatches(property.getKey(), fieldNode, vartype)) { + return new FieldInfo(fieldNode, property.getKey(), property.getValue(), arguments); + } + } + return null; + } + + for (Entry property : SIMPLE_PROPERTY_TYPE_MAP.entrySet()) { + if (typeMatches(property.getKey(), fieldNode, vartype)) { + return new FieldInfo(fieldNode, property.getKey(), property.getValue()); + } + } + return null; + } +} diff --git a/src/core/lombok/extern/javafx/FxProperty.java b/src/core/lombok/extern/javafx/FxProperty.java new file mode 100644 index 0000000000..16bc9e4253 --- /dev/null +++ b/src/core/lombok/extern/javafx/FxProperty.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2020 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.extern.javafx; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Put on any field to make lombok build getter and setter for a JavaFx property. + *

+ * Complete documentation is found at the project lombok features page for @FxProperty. + *

+ * Example: + *

+ *     private @FxProperty StringProperty foo;
+ * 
+ * + * will generate: + * + *
+ *     public final String getFoo() {
+ *         return this.foo.get();
+ *     }
+ *     public final void setFoo(String foo) {
+ *         return this.foo.set(foo);
+ *     }
+ *     public StringProperty fooProperty() {
+ *         return this.foo;
+ *     }
+ * 
+ *

+ * This annotation can also be applied to a class, in which case it'll be as if all fields that don't already have + * a {@code @FxProperty} annotation. + */ +@Target({ElementType.TYPE, ElementType.FIELD}) +@Retention(RetentionPolicy.SOURCE) +public @interface FxProperty { + /** + * Generate a read only property instead of normal one. This will create a + * private setter and converts the return type of the property accessor to + * the right ReadOnly*Property. + *

+ * Example: + * + *

+	 * 	private @FxProperty(readOnly = true) StringProperty foo;
+	 * 
+ * + * will generate: + * + *
+	 * 	public final String getFoo() {
+	 * 		return this.foo.get();
+	 * 	}
+	 * 
+	 * 	private final void setFoo(String foo) {
+	 * 		return this.foo.set(foo);
+	 * 	}
+	 * 
+	 * 	public ReadOnlyStringProperty fooProperty() {
+	 * 		return this.foo;
+	 * 	}
+	 * 
+ * + * @return + */ + boolean readOnly() default false; +} diff --git a/src/core/lombok/javac/handlers/HandleFxProperty.java b/src/core/lombok/javac/handlers/HandleFxProperty.java new file mode 100644 index 0000000000..0f4c05c418 --- /dev/null +++ b/src/core/lombok/javac/handlers/HandleFxProperty.java @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2020-2021 The Project Lombok Authors. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package lombok.javac.handlers; + +import static lombok.core.handlers.HandlerUtil.*; +import static lombok.javac.Javac.*; +import static lombok.javac.handlers.JavacHandlerUtil.*; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCTypeParameter; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Name; + +import lombok.ConfigurationKeys; +import lombok.core.AST.Kind; +import lombok.core.AnnotationValues; +import lombok.core.handlers.HandlerUtil.FieldAccess; +import lombok.extern.javafx.FxProperty; +import lombok.javac.Javac; +import lombok.javac.JavacAnnotationHandler; +import lombok.javac.JavacNode; +import lombok.javac.JavacTreeMaker; +import lombok.javac.JavacTreeMaker.TypeTag; +import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; +import lombok.spi.Provides; + +/** + * Handles the {@link FxProperty} annotation for javac. + */ +@Provides +public class HandleFxProperty extends JavacAnnotationHandler { + + @Override public void handle(AnnotationValues annotation, JCAnnotation ast, JavacNode annotationNode) { + handleFlagUsage(annotationNode, ConfigurationKeys.FXPROPERTY_FLAG_USAGE, "@FxProperty"); + + Collection fields = annotationNode.upFromAnnotationToFields(); + deleteAnnotationIfNeccessary(annotationNode, FxProperty.class); + JavacNode node = annotationNode.up(); + FxProperty annotationInstance = annotation.getInstance(); + boolean readOnly = annotationInstance.readOnly(); + + if (node == null) return; + + switch (node.getKind()) { + case FIELD: + createFxPropertyForFields(fields, annotationNode, readOnly); + break; + case TYPE: + createFxPropertyForType(node, annotationNode, readOnly); + break; + } + } + + private void createFxPropertyForType(JavacNode typeNode, JavacNode annotationNode, boolean readOnly) { + if (!isClassOrEnum(typeNode)) { + annotationNode.addError("@FxProperty is only supported on a class, an enum, or a field."); + return; + } + for (JavacNode field : typeNode.down()) { + if (field.getKind() != Kind.FIELD) continue; + if (field.getName().startsWith("$")) continue; + + createFxPropertyForField(field, annotationNode, readOnly); + } + } + + private void createFxPropertyForFields(Collection fields, JavacNode annotationNode, boolean readOnly) { + for (JavacNode field : fields) { + createFxPropertyForField(field, annotationNode, readOnly); + } + } + + private void createFxPropertyForField(JavacNode fieldNode, JavacNode source, boolean readOnly) { + JCVariableDecl fieldDecl = (JCVariableDecl)fieldNode.get(); + JavacNode typeNode = upToTypeNode(fieldNode); + + FieldInfo fieldInfo = getFieldInfo(fieldNode, fieldDecl); + if (fieldInfo == null) { + source.addError("@FxProperty is only supported on predefined JavaFx property types."); + return; + } + + addPropertyAccessor(fieldNode, source, typeNode, fieldInfo, readOnly); + addGetter(fieldNode, source, typeNode, fieldInfo); + addSetter(fieldNode, source, typeNode, fieldInfo, readOnly); + } + + private void addGetter(JavacNode fieldNode, JavacNode source, JavacNode typeNode, FieldInfo fieldInfo) { + String methodName = buildAccessorName(fieldNode, "get", fieldNode.getName()); + if (methodExists(methodName, typeNode, 0) != MemberExistsResult.NOT_EXISTS) { + return; + } + + injectMethod(typeNode, recursiveSetGeneratedBy(createGetter(fieldNode, fieldInfo), source)); + } + + private void addSetter(JavacNode fieldNode, JavacNode source, JavacNode typeNode, FieldInfo fieldInfo, boolean readOnly) { + if (fieldInfo.readOnly) return; + + String methodName = buildAccessorName(fieldNode, "set", fieldNode.getName()); + if (methodExists(methodName, typeNode, 1) != MemberExistsResult.NOT_EXISTS) { + return; + } + + injectMethod(typeNode, recursiveSetGeneratedBy(createSetter(fieldNode, fieldInfo, readOnly), source)); + } + + private void addPropertyAccessor(JavacNode fieldNode, JavacNode source, JavacNode typeNode, FieldInfo fieldInfo, boolean readOnly) { + String methodName = toPropertyName(fieldNode.getName()); + if (methodExists(methodName, typeNode, 0) != MemberExistsResult.NOT_EXISTS) { + return; + } + + injectMethod(typeNode, recursiveSetGeneratedBy(createPropertyAccessor(fieldNode, fieldInfo, readOnly), source)); + } + + + private JCMethodDecl createPropertyAccessor(JavacNode fieldNode, FieldInfo fieldInfo, boolean readOnly) { + String methodName = toPropertyName(fieldNode.getName()); + + JavacTreeMaker maker = fieldNode.getTreeMaker(); + + List methodGenericParams = List.nil(); + List parameters = List.nil(); + List throwsClauses = List.nil(); + JCExpression defaultValue = null; + JCBlock methodBody = maker.Block(0, List.of(maker.Return(createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD)))); + + return maker.MethodDef(maker.Modifiers(Flags.PUBLIC), fieldNode.toName(methodName), fieldInfo.getPropertyType(readOnly), methodGenericParams, parameters, throwsClauses, methodBody, defaultValue); + } + + private JCMethodDecl createSetter(JavacNode fieldNode, FieldInfo fieldInfo, boolean readOnly) { + Name methodName = fieldNode.toName(buildAccessorName(fieldNode, "set", fieldNode.getName())); + + JavacTreeMaker maker = fieldNode.getTreeMaker(); + JCVariableDecl fieldDecl = (JCVariableDecl)fieldNode.get(); + + long modifiers = Flags.FINAL | (readOnly ? Flags.PRIVATE : Flags.PUBLIC); + List methodGenericParams = List.nil(); + List throwsClauses = List.nil(); + JCExpression defaultValue = null; + JCExpression methodType = maker.Type(Javac.createVoidType(fieldNode.getSymbolTable(), CTC_VOID)); + + Name paramName = fieldDecl.name; + long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, fieldNode.getContext()); + List parameters = List.of(maker.VarDef(maker.Modifiers(flags, List.nil()), paramName, fieldInfo.getType(), null)); + + List typeargs = List.nil(); + JCExpression fieldRef = createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD); + JCMethodInvocation write = maker.Apply(typeargs, maker.Select(fieldRef, fieldNode.toName("set")), List.of(maker.Ident(paramName))); + JCBlock methodBody = maker.Block(0, List.of(maker.Exec(write))); + + return maker.MethodDef(maker.Modifiers(modifiers), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, defaultValue); + } + + private JCMethodDecl createGetter(JavacNode fieldNode, FieldInfo fieldInfo) { + Name methodName = fieldNode.toName(buildAccessorName(fieldNode, "get", fieldNode.getName())); + + JavacTreeMaker maker = fieldNode.getTreeMaker(); + + List methodGenericParams = List.nil(); + List parameters = List.nil(); + List throwsClauses = List.nil(); + JCExpression defaultValue = null; + List args = List.nil(); + + List typeargs = List.nil(); + JCExpression fieldRef = createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD); + JCMethodInvocation apply = maker.Apply(typeargs, maker.Select(fieldRef, fieldNode.toName("get")), args); + JCBlock methodBody = maker.Block(0, List.of(maker.Return(apply))); + + return maker.MethodDef(maker.Modifiers(Flags.PUBLIC | Flags.FINAL), methodName, fieldInfo.getType(), methodGenericParams, parameters, throwsClauses, methodBody, defaultValue); + } + + static class FieldInfo { + JavacNode fieldNode; + String propertyType; + String returnType; + boolean readOnly; + private List typeArguments; + + FieldInfo(JavacNode fieldNode, String propertyType, String returnType) { + this.fieldNode = fieldNode; + this.propertyType = propertyType; + this.returnType = returnType; + this.readOnly = propertyType.contains("ReadOnly"); + } + + FieldInfo(JavacNode fieldNode, String propertyType, String returnType, List typeArguments) { + this(fieldNode, propertyType, returnType); + this.typeArguments = typeArguments; + } + + JCExpression getType() { + TypeTag primitiveTypeTag = PRIMITIVE_TYPE_MAP.get(returnType); + if (primitiveTypeTag != null) { + return fieldNode.getTreeMaker().TypeIdent(primitiveTypeTag); + } + + JCExpression typeRef = genTypeRef(fieldNode, returnType); + + if (typeArguments == null) return typeRef; + + if (returnType.endsWith("Object")) { + return typeArguments.get(0); + } + return fieldNode.getTreeMaker().TypeApply(typeRef, typeArguments); + } + + JCExpression getPropertyType(boolean asReadOnly) { + String type = propertyType; + if (asReadOnly && !readOnly) { + type = "javafx.beans.property.ReadOnly" + propertyType.substring(22); + } + return genTypeRef(fieldNode, type); + } + } + + private static Map SIMPLE_PROPERTY_TYPE_MAP; + private static Map GENERIC_PROPERTY_TYPE_MAP; + static { + Map m = new HashMap(); + m.put("javafx.beans.property.ObjectProperty", "java.lang.Object"); + m.put("javafx.beans.property.ListProperty", "javafx.collections.ObservableList"); + m.put("javafx.beans.property.MapProperty", "javafx.collections.ObservableMap"); + m.put("javafx.beans.property.SetProperty", "javafx.collections.ObservableSet"); + + m.put("javafx.beans.property.ReadOnlyObjectProperty", "java.lang.Object"); + m.put("javafx.beans.property.ReadOnlyListProperty", "javafx.collections.ObservableList"); + m.put("javafx.beans.property.ReadOnlyMapProperty", "javafx.collections.ObservableMap"); + m.put("javafx.beans.property.ReadOnlySetProperty", "javafx.collections.ObservableSet"); + GENERIC_PROPERTY_TYPE_MAP = Collections.unmodifiableMap(m); + + m.put("javafx.beans.property.IntegerProperty", "java.lang.Integer"); + m.put("javafx.beans.property.LongProperty", "java.lang.Long"); + m.put("javafx.beans.property.FloatProperty", "java.lang.Float"); + m.put("javafx.beans.property.DoubleProperty", "java.lang.Double"); + m.put("javafx.beans.property.BooleanProperty", "java.lang.Boolean"); + m.put("javafx.beans.property.StringProperty", "java.lang.String"); + + m.put("javafx.beans.property.ReadOnlyIntegerProperty", "java.lang.Integer"); + m.put("javafx.beans.property.ReadOnlyLongProperty", "java.lang.Long"); + m.put("javafx.beans.property.ReadOnlyFloatProperty", "java.lang.Float"); + m.put("javafx.beans.property.ReadOnlyDoubleProperty", "java.lang.Double"); + m.put("javafx.beans.property.ReadOnlyBooleanProperty", "java.lang.Boolean"); + m.put("javafx.beans.property.ReadOnlyStringProperty", "java.lang.String"); + SIMPLE_PROPERTY_TYPE_MAP = Collections.unmodifiableMap(m); + } + + private static Map PRIMITIVE_TYPE_MAP; + static { + Map m = new HashMap(); + m.put("java.lang.Integer", CTC_INT); + m.put("java.lang.Long", CTC_LONG); + m.put("java.lang.Float", CTC_FLOAT); + m.put("java.lang.Double", CTC_DOUBLE); + m.put("java.lang.Boolean", CTC_BOOLEAN); + PRIMITIVE_TYPE_MAP = Collections.unmodifiableMap(m); + } + + private FieldInfo getFieldInfo(JavacNode fieldNode, JCVariableDecl fieldDecl) { + JCExpression vartype = fieldDecl.vartype; + if (vartype instanceof JCTypeApply) { + JCTypeApply typeApply = (JCTypeApply) vartype; + JCExpression clazz = typeApply.clazz; + List arguments = typeApply.arguments; + + for (Entry property : GENERIC_PROPERTY_TYPE_MAP.entrySet()) { + if (typeMatches(property.getKey(), fieldNode, clazz)) { + return new FieldInfo(fieldNode, property.getKey(), property.getValue(), arguments); + } + } + return null; + } + + for (Entry property : SIMPLE_PROPERTY_TYPE_MAP.entrySet()) { + if (typeMatches(property.getKey(), fieldNode, vartype)) { + return new FieldInfo(fieldNode, property.getKey(), property.getValue()); + } + } + return null; + } +} diff --git a/test/stubs/javafx/beans/property/BooleanProperty.java b/test/stubs/javafx/beans/property/BooleanProperty.java new file mode 100644 index 0000000000..8ed02f2fd7 --- /dev/null +++ b/test/stubs/javafx/beans/property/BooleanProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class BooleanProperty extends ReadOnlyBooleanProperty { + public void set(boolean value) { } +} diff --git a/test/stubs/javafx/beans/property/DoubleProperty.java b/test/stubs/javafx/beans/property/DoubleProperty.java new file mode 100644 index 0000000000..f233f169f8 --- /dev/null +++ b/test/stubs/javafx/beans/property/DoubleProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class DoubleProperty extends ReadOnlyDoubleProperty { + public void set(double value) { } +} diff --git a/test/stubs/javafx/beans/property/FloatProperty.java b/test/stubs/javafx/beans/property/FloatProperty.java new file mode 100644 index 0000000000..16ff7d55db --- /dev/null +++ b/test/stubs/javafx/beans/property/FloatProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class FloatProperty extends ReadOnlyFloatProperty { + public void set(float value) { } +} diff --git a/test/stubs/javafx/beans/property/IntegerProperty.java b/test/stubs/javafx/beans/property/IntegerProperty.java new file mode 100644 index 0000000000..c16300877d --- /dev/null +++ b/test/stubs/javafx/beans/property/IntegerProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class IntegerProperty extends ReadOnlyIntegerProperty { + public void set(int value) { } +} diff --git a/test/stubs/javafx/beans/property/ListProperty.java b/test/stubs/javafx/beans/property/ListProperty.java new file mode 100644 index 0000000000..f27213574c --- /dev/null +++ b/test/stubs/javafx/beans/property/ListProperty.java @@ -0,0 +1,8 @@ +package javafx.beans.property; + +import javafx.collections.ObservableList; + +public class ListProperty extends ReadOnlyListProperty { + public void set(ObservableList value) { } +} + diff --git a/test/stubs/javafx/beans/property/LongProperty.java b/test/stubs/javafx/beans/property/LongProperty.java new file mode 100644 index 0000000000..308f366504 --- /dev/null +++ b/test/stubs/javafx/beans/property/LongProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class LongProperty extends ReadOnlyLongProperty { + public void set(long value) { } +} diff --git a/test/stubs/javafx/beans/property/MapProperty.java b/test/stubs/javafx/beans/property/MapProperty.java new file mode 100644 index 0000000000..807987a869 --- /dev/null +++ b/test/stubs/javafx/beans/property/MapProperty.java @@ -0,0 +1,7 @@ +package javafx.beans.property; + +import javafx.collections.ObservableMap; + +public class MapProperty extends ReadOnlyMapProperty { + public void set(ObservableMap value) { } +} diff --git a/test/stubs/javafx/beans/property/ObjectProperty.java b/test/stubs/javafx/beans/property/ObjectProperty.java new file mode 100644 index 0000000000..14c402e560 --- /dev/null +++ b/test/stubs/javafx/beans/property/ObjectProperty.java @@ -0,0 +1,6 @@ +package javafx.beans.property; + +public class ObjectProperty extends ReadOnlyObjectProperty { + public void set(T value) { } +} + diff --git a/test/stubs/javafx/beans/property/Property.java b/test/stubs/javafx/beans/property/Property.java new file mode 100644 index 0000000000..a92ebe4e03 --- /dev/null +++ b/test/stubs/javafx/beans/property/Property.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public interface Property extends ReadOnlyProperty { + public void set(T value); +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyBooleanProperty.java b/test/stubs/javafx/beans/property/ReadOnlyBooleanProperty.java new file mode 100644 index 0000000000..d46def3ec6 --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyBooleanProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class ReadOnlyBooleanProperty { + public boolean get() { return false; } +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyDoubleProperty.java b/test/stubs/javafx/beans/property/ReadOnlyDoubleProperty.java new file mode 100644 index 0000000000..df87658459 --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyDoubleProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class ReadOnlyDoubleProperty { + public double get() { return 0d; } +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyFloatProperty.java b/test/stubs/javafx/beans/property/ReadOnlyFloatProperty.java new file mode 100644 index 0000000000..62414f5a35 --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyFloatProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class ReadOnlyFloatProperty { + public float get() { return 0f; } +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyIntegerProperty.java b/test/stubs/javafx/beans/property/ReadOnlyIntegerProperty.java new file mode 100644 index 0000000000..0af040c92d --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyIntegerProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class ReadOnlyIntegerProperty { + public int get() { return 0; } +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyListProperty.java b/test/stubs/javafx/beans/property/ReadOnlyListProperty.java new file mode 100644 index 0000000000..a63d2973e9 --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyListProperty.java @@ -0,0 +1,8 @@ +package javafx.beans.property; + +import javafx.collections.ObservableList; + +public class ReadOnlyListProperty { + public ObservableList get() { return null; } +} + diff --git a/test/stubs/javafx/beans/property/ReadOnlyLongProperty.java b/test/stubs/javafx/beans/property/ReadOnlyLongProperty.java new file mode 100644 index 0000000000..4485dc8993 --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyLongProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class ReadOnlyLongProperty { + public long get() { return 0; } +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyMapProperty.java b/test/stubs/javafx/beans/property/ReadOnlyMapProperty.java new file mode 100644 index 0000000000..f096578ee3 --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyMapProperty.java @@ -0,0 +1,7 @@ +package javafx.beans.property; + +import javafx.collections.ObservableMap; + +public class ReadOnlyMapProperty { + public ObservableMap get() { return null; } +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyObjectProperty.java b/test/stubs/javafx/beans/property/ReadOnlyObjectProperty.java new file mode 100644 index 0000000000..a95f93203c --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyObjectProperty.java @@ -0,0 +1,6 @@ +package javafx.beans.property; + +public class ReadOnlyObjectProperty { + public T get() { return null; } +} + diff --git a/test/stubs/javafx/beans/property/ReadOnlyProperty.java b/test/stubs/javafx/beans/property/ReadOnlyProperty.java new file mode 100644 index 0000000000..e522c13daf --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public interface ReadOnlyProperty { + public T get(); +} diff --git a/test/stubs/javafx/beans/property/ReadOnlySetProperty.java b/test/stubs/javafx/beans/property/ReadOnlySetProperty.java new file mode 100644 index 0000000000..0fab82f7aa --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlySetProperty.java @@ -0,0 +1,7 @@ +package javafx.beans.property; + +import javafx.collections.ObservableSet; + +public class ReadOnlySetProperty { + public ObservableSet get() { return null; } +} diff --git a/test/stubs/javafx/beans/property/ReadOnlyStringProperty.java b/test/stubs/javafx/beans/property/ReadOnlyStringProperty.java new file mode 100644 index 0000000000..4a24175046 --- /dev/null +++ b/test/stubs/javafx/beans/property/ReadOnlyStringProperty.java @@ -0,0 +1,5 @@ +package javafx.beans.property; + +public class ReadOnlyStringProperty { + public String get() { return null; } +} diff --git a/test/stubs/javafx/beans/property/SetProperty.java b/test/stubs/javafx/beans/property/SetProperty.java new file mode 100644 index 0000000000..8dab57df1a --- /dev/null +++ b/test/stubs/javafx/beans/property/SetProperty.java @@ -0,0 +1,8 @@ +package javafx.beans.property; + +import javafx.collections.ObservableSet; + +public class SetProperty { + public ObservableSet get() { return null; } + public void set(ObservableSet value) { } +} diff --git a/test/stubs/javafx/beans/property/StringProperty.java b/test/stubs/javafx/beans/property/StringProperty.java new file mode 100644 index 0000000000..6d0a949384 --- /dev/null +++ b/test/stubs/javafx/beans/property/StringProperty.java @@ -0,0 +1,6 @@ +package javafx.beans.property; + +public class StringProperty { + public String get() { return null; } + public void set(String value) { } +} diff --git a/test/stubs/javafx/collections/ObservableList.java b/test/stubs/javafx/collections/ObservableList.java new file mode 100644 index 0000000000..37398e36b7 --- /dev/null +++ b/test/stubs/javafx/collections/ObservableList.java @@ -0,0 +1,5 @@ +package javafx.collections; + +public class ObservableList { + +} diff --git a/test/stubs/javafx/collections/ObservableMap.java b/test/stubs/javafx/collections/ObservableMap.java new file mode 100644 index 0000000000..b92d47333b --- /dev/null +++ b/test/stubs/javafx/collections/ObservableMap.java @@ -0,0 +1,5 @@ +package javafx.collections; + +public class ObservableMap { + +} diff --git a/test/stubs/javafx/collections/ObservableSet.java b/test/stubs/javafx/collections/ObservableSet.java new file mode 100644 index 0000000000..7f1e53c907 --- /dev/null +++ b/test/stubs/javafx/collections/ObservableSet.java @@ -0,0 +1,5 @@ +package javafx.collections; + +public class ObservableSet { + +} diff --git a/test/transform/resource/after-delombok/FxPropertyExisting.java b/test/transform/resource/after-delombok/FxPropertyExisting.java new file mode 100644 index 0000000000..e5262dd317 --- /dev/null +++ b/test/transform/resource/after-delombok/FxPropertyExisting.java @@ -0,0 +1,18 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; + +class FxPropertyExisting { + private IntegerProperty integer; + + public ReadOnlyIntegerProperty integerProperty() { + return this.integer; + } + + public int getInteger() { + return this.integer.get(); + } + + public void setInteger(int integer) { + this.integer.set(integer); + } +} diff --git a/test/transform/resource/after-delombok/FxPropertyOnClass.java b/test/transform/resource/after-delombok/FxPropertyOnClass.java new file mode 100644 index 0000000000..874f838174 --- /dev/null +++ b/test/transform/resource/after-delombok/FxPropertyOnClass.java @@ -0,0 +1,275 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; + +class FxPropertyOnClass { + private IntegerProperty integer1; + private LongProperty long1; + private FloatProperty float1; + private DoubleProperty double1; + private BooleanProperty boolean1; + private StringProperty string1; + private ObjectProperty object1; + private ListProperty list1; + private SetProperty set1; + private MapProperty map1; + private ReadOnlyIntegerProperty integer2; + private ReadOnlyLongProperty long2; + private ReadOnlyFloatProperty float2; + private ReadOnlyDoubleProperty double2; + private ReadOnlyBooleanProperty boolean2; + private ReadOnlyStringProperty string2; + private ReadOnlyObjectProperty object2; + private ReadOnlyListProperty list2; + private ReadOnlySetProperty set2; + private ReadOnlyMapProperty map2; + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.IntegerProperty integer1Property() { + return this.integer1; + } + + @java.lang.SuppressWarnings("all") + public final int getInteger1() { + return this.integer1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setInteger1(final int integer1) { + this.integer1.set(integer1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.LongProperty long1Property() { + return this.long1; + } + + @java.lang.SuppressWarnings("all") + public final long getLong1() { + return this.long1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setLong1(final long long1) { + this.long1.set(long1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.FloatProperty float1Property() { + return this.float1; + } + + @java.lang.SuppressWarnings("all") + public final float getFloat1() { + return this.float1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setFloat1(final float float1) { + this.float1.set(float1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.DoubleProperty double1Property() { + return this.double1; + } + + @java.lang.SuppressWarnings("all") + public final double getDouble1() { + return this.double1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setDouble1(final double double1) { + this.double1.set(double1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.BooleanProperty boolean1Property() { + return this.boolean1; + } + + @java.lang.SuppressWarnings("all") + public final boolean getBoolean1() { + return this.boolean1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setBoolean1(final boolean boolean1) { + this.boolean1.set(boolean1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.StringProperty string1Property() { + return this.string1; + } + + @java.lang.SuppressWarnings("all") + public final java.lang.String getString1() { + return this.string1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setString1(final java.lang.String string1) { + this.string1.set(string1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ObjectProperty object1Property() { + return this.object1; + } + + @java.lang.SuppressWarnings("all") + public final BigDecimal getObject1() { + return this.object1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setObject1(final BigDecimal object1) { + this.object1.set(object1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ListProperty list1Property() { + return this.list1; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableList getList1() { + return this.list1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setList1(final javafx.collections.ObservableList list1) { + this.list1.set(list1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.SetProperty set1Property() { + return this.set1; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableSet getSet1() { + return this.set1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setSet1(final javafx.collections.ObservableSet set1) { + this.set1.set(set1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.MapProperty map1Property() { + return this.map1; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableMap getMap1() { + return this.map1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setMap1(final javafx.collections.ObservableMap map1) { + this.map1.set(map1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyIntegerProperty integer2Property() { + return this.integer2; + } + + @java.lang.SuppressWarnings("all") + public final int getInteger2() { + return this.integer2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyLongProperty long2Property() { + return this.long2; + } + + @java.lang.SuppressWarnings("all") + public final long getLong2() { + return this.long2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyFloatProperty float2Property() { + return this.float2; + } + + @java.lang.SuppressWarnings("all") + public final float getFloat2() { + return this.float2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyDoubleProperty double2Property() { + return this.double2; + } + + @java.lang.SuppressWarnings("all") + public final double getDouble2() { + return this.double2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyBooleanProperty boolean2Property() { + return this.boolean2; + } + + @java.lang.SuppressWarnings("all") + public final boolean getBoolean2() { + return this.boolean2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyStringProperty string2Property() { + return this.string2; + } + + @java.lang.SuppressWarnings("all") + public final java.lang.String getString2() { + return this.string2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyObjectProperty object2Property() { + return this.object2; + } + + @java.lang.SuppressWarnings("all") + public final BigDecimal getObject2() { + return this.object2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyListProperty list2Property() { + return this.list2; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableList getList2() { + return this.list2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlySetProperty set2Property() { + return this.set2; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableSet getSet2() { + return this.set2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyMapProperty map2Property() { + return this.map2; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableMap getMap2() { + return this.map2.get(); + } +} diff --git a/test/transform/resource/after-delombok/FxPropertyReadOnly.java b/test/transform/resource/after-delombok/FxPropertyReadOnly.java new file mode 100644 index 0000000000..1a63745ed2 --- /dev/null +++ b/test/transform/resource/after-delombok/FxPropertyReadOnly.java @@ -0,0 +1,32 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; + +class FxPropertyReadOnly { + private IntegerProperty integer1; + private ReadOnlyIntegerProperty integer2; + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyIntegerProperty integer1Property() { + return this.integer1; + } + + @java.lang.SuppressWarnings("all") + public final int getInteger1() { + return this.integer1.get(); + } + + @java.lang.SuppressWarnings("all") + private final void setInteger1(final int integer1) { + this.integer1.set(integer1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyIntegerProperty integer2Property() { + return this.integer2; + } + + @java.lang.SuppressWarnings("all") + public final int getInteger2() { + return this.integer2.get(); + } +} diff --git a/test/transform/resource/after-delombok/FxPropertySimple.java b/test/transform/resource/after-delombok/FxPropertySimple.java new file mode 100644 index 0000000000..087029f84e --- /dev/null +++ b/test/transform/resource/after-delombok/FxPropertySimple.java @@ -0,0 +1,275 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; + +class FxPropertySimple { + private IntegerProperty integer1; + private LongProperty long1; + private FloatProperty float1; + private DoubleProperty double1; + private BooleanProperty boolean1; + private StringProperty string1; + private ObjectProperty object1; + private ListProperty list1; + private SetProperty set1; + private MapProperty map1; + private ReadOnlyIntegerProperty integer2; + private ReadOnlyLongProperty long2; + private ReadOnlyFloatProperty float2; + private ReadOnlyDoubleProperty double2; + private ReadOnlyBooleanProperty boolean2; + private ReadOnlyStringProperty string2; + private ReadOnlyObjectProperty object2; + private ReadOnlyListProperty list2; + private ReadOnlySetProperty set2; + private ReadOnlyMapProperty map2; + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.IntegerProperty integer1Property() { + return this.integer1; + } + + @java.lang.SuppressWarnings("all") + public final int getInteger1() { + return this.integer1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setInteger1(final int integer1) { + this.integer1.set(integer1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.LongProperty long1Property() { + return this.long1; + } + + @java.lang.SuppressWarnings("all") + public final long getLong1() { + return this.long1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setLong1(final long long1) { + this.long1.set(long1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.FloatProperty float1Property() { + return this.float1; + } + + @java.lang.SuppressWarnings("all") + public final float getFloat1() { + return this.float1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setFloat1(final float float1) { + this.float1.set(float1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.DoubleProperty double1Property() { + return this.double1; + } + + @java.lang.SuppressWarnings("all") + public final double getDouble1() { + return this.double1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setDouble1(final double double1) { + this.double1.set(double1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.BooleanProperty boolean1Property() { + return this.boolean1; + } + + @java.lang.SuppressWarnings("all") + public final boolean getBoolean1() { + return this.boolean1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setBoolean1(final boolean boolean1) { + this.boolean1.set(boolean1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.StringProperty string1Property() { + return this.string1; + } + + @java.lang.SuppressWarnings("all") + public final java.lang.String getString1() { + return this.string1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setString1(final java.lang.String string1) { + this.string1.set(string1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ObjectProperty object1Property() { + return this.object1; + } + + @java.lang.SuppressWarnings("all") + public final BigDecimal getObject1() { + return this.object1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setObject1(final BigDecimal object1) { + this.object1.set(object1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ListProperty list1Property() { + return this.list1; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableList getList1() { + return this.list1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setList1(final javafx.collections.ObservableList list1) { + this.list1.set(list1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.SetProperty set1Property() { + return this.set1; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableSet getSet1() { + return this.set1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setSet1(final javafx.collections.ObservableSet set1) { + this.set1.set(set1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.MapProperty map1Property() { + return this.map1; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableMap getMap1() { + return this.map1.get(); + } + + @java.lang.SuppressWarnings("all") + public final void setMap1(final javafx.collections.ObservableMap map1) { + this.map1.set(map1); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyIntegerProperty integer2Property() { + return this.integer2; + } + + @java.lang.SuppressWarnings("all") + public final int getInteger2() { + return this.integer2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyLongProperty long2Property() { + return this.long2; + } + + @java.lang.SuppressWarnings("all") + public final long getLong2() { + return this.long2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyFloatProperty float2Property() { + return this.float2; + } + + @java.lang.SuppressWarnings("all") + public final float getFloat2() { + return this.float2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyDoubleProperty double2Property() { + return this.double2; + } + + @java.lang.SuppressWarnings("all") + public final double getDouble2() { + return this.double2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyBooleanProperty boolean2Property() { + return this.boolean2; + } + + @java.lang.SuppressWarnings("all") + public final boolean getBoolean2() { + return this.boolean2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyStringProperty string2Property() { + return this.string2; + } + + @java.lang.SuppressWarnings("all") + public final java.lang.String getString2() { + return this.string2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyObjectProperty object2Property() { + return this.object2; + } + + @java.lang.SuppressWarnings("all") + public final BigDecimal getObject2() { + return this.object2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyListProperty list2Property() { + return this.list2; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableList getList2() { + return this.list2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlySetProperty set2Property() { + return this.set2; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableSet getSet2() { + return this.set2.get(); + } + + @java.lang.SuppressWarnings("all") + public javafx.beans.property.ReadOnlyMapProperty map2Property() { + return this.map2; + } + + @java.lang.SuppressWarnings("all") + public final javafx.collections.ObservableMap getMap2() { + return this.map2.get(); + } +} diff --git a/test/transform/resource/after-ecj/FxPropertyExisting.java b/test/transform/resource/after-ecj/FxPropertyExisting.java new file mode 100644 index 0000000000..7983f0eaab --- /dev/null +++ b/test/transform/resource/after-ecj/FxPropertyExisting.java @@ -0,0 +1,18 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; +class FxPropertyExisting { + private @FxProperty IntegerProperty integer; + FxPropertyExisting() { + super(); + } + public ReadOnlyIntegerProperty integerProperty() { + return this.integer; + } + public int getInteger() { + return this.integer.get(); + } + public void setInteger(int integer) { + this.integer.set(integer); + } +} diff --git a/test/transform/resource/after-ecj/FxPropertyOnClass.java b/test/transform/resource/after-ecj/FxPropertyOnClass.java new file mode 100644 index 0000000000..51c0cfce99 --- /dev/null +++ b/test/transform/resource/after-ecj/FxPropertyOnClass.java @@ -0,0 +1,178 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; +@FxProperty class FxPropertyOnClass { + private IntegerProperty integer1; + private LongProperty long1; + private FloatProperty float1; + private DoubleProperty double1; + private BooleanProperty boolean1; + private StringProperty string1; + private ObjectProperty object1; + private ListProperty list1; + private SetProperty set1; + private MapProperty map1; + private ReadOnlyIntegerProperty integer2; + private ReadOnlyLongProperty long2; + private ReadOnlyFloatProperty float2; + private ReadOnlyDoubleProperty double2; + private ReadOnlyBooleanProperty boolean2; + private ReadOnlyStringProperty string2; + private ReadOnlyObjectProperty object2; + private ReadOnlyListProperty list2; + private ReadOnlySetProperty set2; + private ReadOnlyMapProperty map2; + FxPropertyOnClass() { + super(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.IntegerProperty integer1Property() { + return this.integer1; + } + public final @java.lang.SuppressWarnings("all") int getInteger1() { + return this.integer1.get(); + } + public final @java.lang.SuppressWarnings("all") void setInteger1(final int integer1) { + this.integer1.set(integer1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.LongProperty long1Property() { + return this.long1; + } + public final @java.lang.SuppressWarnings("all") long getLong1() { + return this.long1.get(); + } + public final @java.lang.SuppressWarnings("all") void setLong1(final long long1) { + this.long1.set(long1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.FloatProperty float1Property() { + return this.float1; + } + public final @java.lang.SuppressWarnings("all") float getFloat1() { + return this.float1.get(); + } + public final @java.lang.SuppressWarnings("all") void setFloat1(final float float1) { + this.float1.set(float1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.DoubleProperty double1Property() { + return this.double1; + } + public final @java.lang.SuppressWarnings("all") double getDouble1() { + return this.double1.get(); + } + public final @java.lang.SuppressWarnings("all") void setDouble1(final double double1) { + this.double1.set(double1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.BooleanProperty boolean1Property() { + return this.boolean1; + } + public final @java.lang.SuppressWarnings("all") boolean getBoolean1() { + return this.boolean1.get(); + } + public final @java.lang.SuppressWarnings("all") void setBoolean1(final boolean boolean1) { + this.boolean1.set(boolean1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.StringProperty string1Property() { + return this.string1; + } + public final @java.lang.SuppressWarnings("all") java.lang.String getString1() { + return this.string1.get(); + } + public final @java.lang.SuppressWarnings("all") void setString1(final java.lang.String string1) { + this.string1.set(string1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ObjectProperty object1Property() { + return this.object1; + } + public final @java.lang.SuppressWarnings("all") BigDecimal getObject1() { + return this.object1.get(); + } + public final @java.lang.SuppressWarnings("all") void setObject1(final BigDecimal object1) { + this.object1.set(object1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ListProperty list1Property() { + return this.list1; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableList getList1() { + return this.list1.get(); + } + public final @java.lang.SuppressWarnings("all") void setList1(final javafx.collections.ObservableList list1) { + this.list1.set(list1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.SetProperty set1Property() { + return this.set1; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableSet getSet1() { + return this.set1.get(); + } + public final @java.lang.SuppressWarnings("all") void setSet1(final javafx.collections.ObservableSet set1) { + this.set1.set(set1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.MapProperty map1Property() { + return this.map1; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableMap getMap1() { + return this.map1.get(); + } + public final @java.lang.SuppressWarnings("all") void setMap1(final javafx.collections.ObservableMap map1) { + this.map1.set(map1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyIntegerProperty integer2Property() { + return this.integer2; + } + public final @java.lang.SuppressWarnings("all") int getInteger2() { + return this.integer2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyLongProperty long2Property() { + return this.long2; + } + public final @java.lang.SuppressWarnings("all") long getLong2() { + return this.long2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyFloatProperty float2Property() { + return this.float2; + } + public final @java.lang.SuppressWarnings("all") float getFloat2() { + return this.float2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyDoubleProperty double2Property() { + return this.double2; + } + public final @java.lang.SuppressWarnings("all") double getDouble2() { + return this.double2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyBooleanProperty boolean2Property() { + return this.boolean2; + } + public final @java.lang.SuppressWarnings("all") boolean getBoolean2() { + return this.boolean2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyStringProperty string2Property() { + return this.string2; + } + public final @java.lang.SuppressWarnings("all") java.lang.String getString2() { + return this.string2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyObjectProperty object2Property() { + return this.object2; + } + public final @java.lang.SuppressWarnings("all") BigDecimal getObject2() { + return this.object2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyListProperty list2Property() { + return this.list2; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableList getList2() { + return this.list2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlySetProperty set2Property() { + return this.set2; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableSet getSet2() { + return this.set2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyMapProperty map2Property() { + return this.map2; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableMap getMap2() { + return this.map2.get(); + } +} diff --git a/test/transform/resource/after-ecj/FxPropertyReadOnly.java b/test/transform/resource/after-ecj/FxPropertyReadOnly.java new file mode 100644 index 0000000000..81e2d6fe5b --- /dev/null +++ b/test/transform/resource/after-ecj/FxPropertyReadOnly.java @@ -0,0 +1,25 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; +@FxProperty(readOnly = true) class FxPropertyReadOnly { + private IntegerProperty integer1; + private ReadOnlyIntegerProperty integer2; + FxPropertyReadOnly() { + super(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyIntegerProperty integer1Property() { + return this.integer1; + } + public final @java.lang.SuppressWarnings("all") int getInteger1() { + return this.integer1.get(); + } + private final @java.lang.SuppressWarnings("all") void setInteger1(final int integer1) { + this.integer1.set(integer1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyIntegerProperty integer2Property() { + return this.integer2; + } + public final @java.lang.SuppressWarnings("all") int getInteger2() { + return this.integer2.get(); + } +} diff --git a/test/transform/resource/after-ecj/FxPropertySimple.java b/test/transform/resource/after-ecj/FxPropertySimple.java new file mode 100644 index 0000000000..e3e67d9de5 --- /dev/null +++ b/test/transform/resource/after-ecj/FxPropertySimple.java @@ -0,0 +1,178 @@ +import java.math.BigDecimal; +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; +class FxPropertySimple { + private @FxProperty IntegerProperty integer1; + private @FxProperty LongProperty long1; + private @FxProperty FloatProperty float1; + private @FxProperty DoubleProperty double1; + private @FxProperty BooleanProperty boolean1; + private @FxProperty StringProperty string1; + private @FxProperty ObjectProperty object1; + private @FxProperty ListProperty list1; + private @FxProperty SetProperty set1; + private @FxProperty MapProperty map1; + private @FxProperty ReadOnlyIntegerProperty integer2; + private @FxProperty ReadOnlyLongProperty long2; + private @FxProperty ReadOnlyFloatProperty float2; + private @FxProperty ReadOnlyDoubleProperty double2; + private @FxProperty ReadOnlyBooleanProperty boolean2; + private @FxProperty ReadOnlyStringProperty string2; + private @FxProperty ReadOnlyObjectProperty object2; + private @FxProperty ReadOnlyListProperty list2; + private @FxProperty ReadOnlySetProperty set2; + private @FxProperty ReadOnlyMapProperty map2; + FxPropertySimple() { + super(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.IntegerProperty integer1Property() { + return this.integer1; + } + public final @java.lang.SuppressWarnings("all") int getInteger1() { + return this.integer1.get(); + } + public final @java.lang.SuppressWarnings("all") void setInteger1(final int integer1) { + this.integer1.set(integer1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.LongProperty long1Property() { + return this.long1; + } + public final @java.lang.SuppressWarnings("all") long getLong1() { + return this.long1.get(); + } + public final @java.lang.SuppressWarnings("all") void setLong1(final long long1) { + this.long1.set(long1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.FloatProperty float1Property() { + return this.float1; + } + public final @java.lang.SuppressWarnings("all") float getFloat1() { + return this.float1.get(); + } + public final @java.lang.SuppressWarnings("all") void setFloat1(final float float1) { + this.float1.set(float1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.DoubleProperty double1Property() { + return this.double1; + } + public final @java.lang.SuppressWarnings("all") double getDouble1() { + return this.double1.get(); + } + public final @java.lang.SuppressWarnings("all") void setDouble1(final double double1) { + this.double1.set(double1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.BooleanProperty boolean1Property() { + return this.boolean1; + } + public final @java.lang.SuppressWarnings("all") boolean getBoolean1() { + return this.boolean1.get(); + } + public final @java.lang.SuppressWarnings("all") void setBoolean1(final boolean boolean1) { + this.boolean1.set(boolean1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.StringProperty string1Property() { + return this.string1; + } + public final @java.lang.SuppressWarnings("all") java.lang.String getString1() { + return this.string1.get(); + } + public final @java.lang.SuppressWarnings("all") void setString1(final java.lang.String string1) { + this.string1.set(string1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ObjectProperty object1Property() { + return this.object1; + } + public final @java.lang.SuppressWarnings("all") BigDecimal getObject1() { + return this.object1.get(); + } + public final @java.lang.SuppressWarnings("all") void setObject1(final BigDecimal object1) { + this.object1.set(object1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ListProperty list1Property() { + return this.list1; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableList getList1() { + return this.list1.get(); + } + public final @java.lang.SuppressWarnings("all") void setList1(final javafx.collections.ObservableList list1) { + this.list1.set(list1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.SetProperty set1Property() { + return this.set1; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableSet getSet1() { + return this.set1.get(); + } + public final @java.lang.SuppressWarnings("all") void setSet1(final javafx.collections.ObservableSet set1) { + this.set1.set(set1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.MapProperty map1Property() { + return this.map1; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableMap getMap1() { + return this.map1.get(); + } + public final @java.lang.SuppressWarnings("all") void setMap1(final javafx.collections.ObservableMap map1) { + this.map1.set(map1); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyIntegerProperty integer2Property() { + return this.integer2; + } + public final @java.lang.SuppressWarnings("all") int getInteger2() { + return this.integer2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyLongProperty long2Property() { + return this.long2; + } + public final @java.lang.SuppressWarnings("all") long getLong2() { + return this.long2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyFloatProperty float2Property() { + return this.float2; + } + public final @java.lang.SuppressWarnings("all") float getFloat2() { + return this.float2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyDoubleProperty double2Property() { + return this.double2; + } + public final @java.lang.SuppressWarnings("all") double getDouble2() { + return this.double2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyBooleanProperty boolean2Property() { + return this.boolean2; + } + public final @java.lang.SuppressWarnings("all") boolean getBoolean2() { + return this.boolean2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyStringProperty string2Property() { + return this.string2; + } + public final @java.lang.SuppressWarnings("all") java.lang.String getString2() { + return this.string2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyObjectProperty object2Property() { + return this.object2; + } + public final @java.lang.SuppressWarnings("all") BigDecimal getObject2() { + return this.object2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyListProperty list2Property() { + return this.list2; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableList getList2() { + return this.list2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlySetProperty set2Property() { + return this.set2; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableSet getSet2() { + return this.set2.get(); + } + public @java.lang.SuppressWarnings("all") javafx.beans.property.ReadOnlyMapProperty map2Property() { + return this.map2; + } + public final @java.lang.SuppressWarnings("all") javafx.collections.ObservableMap getMap2() { + return this.map2.get(); + } +} diff --git a/test/transform/resource/before/FxPropertyExisting.java b/test/transform/resource/before/FxPropertyExisting.java new file mode 100644 index 0000000000..c21d588f44 --- /dev/null +++ b/test/transform/resource/before/FxPropertyExisting.java @@ -0,0 +1,20 @@ +import java.math.BigDecimal; + +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; + +class FxPropertyExisting { + @FxProperty private IntegerProperty integer; + + public ReadOnlyIntegerProperty integerProperty() { + return this.integer; + } + + public int getInteger() { + return this.integer.get(); + } + + public void setInteger(int integer) { + this.integer.set(integer); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/FxPropertyOnClass.java b/test/transform/resource/before/FxPropertyOnClass.java new file mode 100644 index 0000000000..0e39a37f45 --- /dev/null +++ b/test/transform/resource/before/FxPropertyOnClass.java @@ -0,0 +1,29 @@ +import java.math.BigDecimal; + +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; + +@FxProperty +class FxPropertyOnClass { + private IntegerProperty integer1; + private LongProperty long1; + private FloatProperty float1; + private DoubleProperty double1; + private BooleanProperty boolean1; + private StringProperty string1; + private ObjectProperty object1; + private ListProperty list1; + private SetProperty set1; + private MapProperty map1; + + private ReadOnlyIntegerProperty integer2; + private ReadOnlyLongProperty long2; + private ReadOnlyFloatProperty float2; + private ReadOnlyDoubleProperty double2; + private ReadOnlyBooleanProperty boolean2; + private ReadOnlyStringProperty string2; + private ReadOnlyObjectProperty object2; + private ReadOnlyListProperty list2; + private ReadOnlySetProperty set2; + private ReadOnlyMapProperty map2; +} \ No newline at end of file diff --git a/test/transform/resource/before/FxPropertyReadOnly.java b/test/transform/resource/before/FxPropertyReadOnly.java new file mode 100644 index 0000000000..89a4ba25f9 --- /dev/null +++ b/test/transform/resource/before/FxPropertyReadOnly.java @@ -0,0 +1,10 @@ +import java.math.BigDecimal; + +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; + +@FxProperty(readOnly = true) +class FxPropertyReadOnly { + private IntegerProperty integer1; + private ReadOnlyIntegerProperty integer2; +} \ No newline at end of file diff --git a/test/transform/resource/before/FxPropertySimple.java b/test/transform/resource/before/FxPropertySimple.java new file mode 100644 index 0000000000..fbba7c98eb --- /dev/null +++ b/test/transform/resource/before/FxPropertySimple.java @@ -0,0 +1,28 @@ +import java.math.BigDecimal; + +import javafx.beans.property.*; +import lombok.extern.javafx.FxProperty; + +class FxPropertySimple { + @FxProperty private IntegerProperty integer1; + @FxProperty private LongProperty long1; + @FxProperty private FloatProperty float1; + @FxProperty private DoubleProperty double1; + @FxProperty private BooleanProperty boolean1; + @FxProperty private StringProperty string1; + @FxProperty private ObjectProperty object1; + @FxProperty private ListProperty list1; + @FxProperty private SetProperty set1; + @FxProperty private MapProperty map1; + + @FxProperty private ReadOnlyIntegerProperty integer2; + @FxProperty private ReadOnlyLongProperty long2; + @FxProperty private ReadOnlyFloatProperty float2; + @FxProperty private ReadOnlyDoubleProperty double2; + @FxProperty private ReadOnlyBooleanProperty boolean2; + @FxProperty private ReadOnlyStringProperty string2; + @FxProperty private ReadOnlyObjectProperty object2; + @FxProperty private ReadOnlyListProperty list2; + @FxProperty private ReadOnlySetProperty set2; + @FxProperty private ReadOnlyMapProperty map2; +} \ No newline at end of file