Skip to content

Revamp DataElement Annotations: Redefine entry point

Eclipse Webmaster requested to merge github/fork/dbluhm/spec-classes into next

Created by: dbluhm

Instead of:

@DataElement
@DataField(fieldName = "age", fieldType = int.class, docString = "The person's age.")
@DataField(fieldName = "firstName", fieldType = String.class, docString = "The person's first name.")
@DataField(fieldName = "lastName", fieldType = String.class, docString = "The person's last name.")
public interface Person {
}

DataElements are created as follows:

@DataElement(name = "Person")
public class PersonSpec {
	/**
	 * The person's age.
	 */
	@DataField.Default("42")
	@DataField private int age;

	/**
	 * The person's first name.
	 */
	@DataField.Default(value = "Bob", isString = true)
	@DataField private String firstName;

	/**
	 * The person's last name.
	 */
	@DataField private String lastName;
}

This comes with the following benefits:

  • We can generate an interface that correctly extends IDataElement.
  • The generated interface also includes getters and setters for its DataFields.
  • Modifiers (private, public, static, final, etc.) are preserved.
  • Annotations other than DataField and DateField.Default are preserved.
  • Doc comments are preserved.

Default values for fields

Unfortunately, the default values of a VariableElement (like age, firstName, and lastName in the example above) cannot be retrieved during annotation processing unless they are compiled constants (int, boolean, String, etc.) and the field is set as final.

To accommodate setting a default value for non-final fields, the @DataField.Default annotation was introduced which takes a String which is placed verbatim in the generated implementation class as the default value for that field. As a result of this, default values of type String must include quotation marks in the String itself along with double escaping escaped values. To assist in correctly formatting strings, isString is provided as a flag for @DataField.Default that will cause the string to be passed through Elements.getConstantExpression() and be properly escaped for outputting to source code.

For final fields with primitive values, @DataField.Default is not needed and the value can be set as normal. If the value is not primitive, DataField.Default can be used as described above.

TODO: Lombok Annotations

Due to the way Lombok manipulates the AST, some lombok annotations modify the field's name to include the annotation itself. For instance, @NonNull causes a VariableElement's name information to include @lombok.NonNull in addition to @NonNull being present in its annotation list. This causes problems with the way we generate fields as an "annotation" gets placed after the type information which is syntactically incorrect.

Merge request reports