gson-compile/gson-compile-processor/src/main/java/io/gitlab/jfronny/gson/compile/processor/util/valueprocessor/Property.java

161 lines
4.4 KiB
Java

package io.gitlab.jfronny.gson.compile.processor.util.valueprocessor;
import org.jetbrains.annotations.ApiStatus;
import javax.lang.model.element.*;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import java.util.List;
public abstract sealed class Property<T extends Element> {
protected final T element;
private List<? extends AnnotationMirror> annotations;
public Property(T element) {
this.element = element;
this.annotations = element.getAnnotationMirrors();
}
public T getElement() {
return element;
}
/**
* The name of the property. For fields and params this is the name in code. For getters, it may have the 'get' or
* 'is' prefix stripped.
* @see #getCallableName()
*/
public String getName() {
return element.getSimpleName().toString();
}
/**
* The actual name of the property. This will not have any 'get' or 'is' prefix stripped.
* @see #getName()
*/
public String getCallableName() {
return getName();
}
/**
* The property's type.
*/
public TypeMirror getType() {
return element.asType();
}
/**
* Annotations relevant to the property. These may be copied from another source. For example, if this is a getter
* it may contain the annotations on the backing private field.
*/
public List<? extends AnnotationMirror> getAnnotations() {
return annotations;
}
public void setAnnotations(List<? extends AnnotationMirror> annotations) {
this.annotations = annotations;
}
@Override
public String toString() {
return getName() + ": " + getType();
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (!(obj instanceof Property<?> other)) return false;
return element.equals(other.element);
}
@Override
public int hashCode() {
return element.hashCode();
}
public static final class Field extends Property<VariableElement> {
public Field(VariableElement element) {
super(element);
}
}
public static final class Getter extends Property<ExecutableElement> {
private static final String BEAN_PREFIX = "get";
private static final String BEAN_PREFIX_BOOL = "is";
private boolean stripBean = false;
public Getter(ExecutableElement element) {
super(element);
}
public boolean isBean() {
return getBeanPrefix() != null;
}
@Override
public String getName() {
String name = super.getName();
if (stripBean) {
String prefix = getBeanPrefix();
if (prefix != null) {
return Character.toLowerCase(name.charAt(prefix.length())) + name.substring(prefix.length() + 1);
}
}
return name;
}
@Override
public String getCallableName() {
return super.getName();
}
@Override
public TypeMirror getType() {
return element.getReturnType();
}
@ApiStatus.Internal
public void stripBean() {
stripBean = true;
}
private String getBeanPrefix() {
String name = super.getName();
if (element.getReturnType().getKind() == TypeKind.BOOLEAN) {
if (name.length() > BEAN_PREFIX_BOOL.length() && name.startsWith(BEAN_PREFIX_BOOL)) {
return BEAN_PREFIX_BOOL;
}
}
return name.length() > BEAN_PREFIX.length() && name.startsWith(BEAN_PREFIX) ? BEAN_PREFIX : null;
}
}
public static sealed abstract class Param extends Property<VariableElement> {
public Param(VariableElement element) {
super(element);
}
}
public static final class ConstructorParam extends Param {
public ConstructorParam(VariableElement element) {
super(element);
}
}
public static final class BuilderParam extends Param {
private final ExecutableElement method;
public BuilderParam(ExecutableElement method) {
super(method.getParameters().get(0));
this.method = method;
}
@Override
public String getCallableName() {
return method.getSimpleName().toString();
}
}
}