cn.zenliu.units.enhancer.make.Make Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of units-enhancer Show documentation
Show all versions of units-enhancer Show documentation
byte-buddy based compile time class enhancer framework.
The newest version!
/*
* Source of units
* Copyright (C) 2023. Zen.Liu
*
* SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0"
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Class Path Exception
* Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination.
* As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.
*/
package cn.zenliu.units.enhancer.make;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.bytebuddy.description.annotation.AnnotationDescription;
import net.bytebuddy.description.annotation.AnnotationValue;
import net.bytebuddy.description.field.FieldDescription;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.description.type.TypeDefinition;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.description.type.TypeDescription.Generic;
import net.bytebuddy.description.type.TypeVariableToken;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.annotation.Annotation;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.IntPredicate;
import java.util.function.UnaryOperator;
import static java.util.Collections.emptyList;
import static net.bytebuddy.matcher.ElementMatchers.none;
/**
* ElementMaker
*/
@SuppressWarnings("unused")
public interface Make> {
S $self();
void $validate();
//region Components
interface Modifiers> extends Make {
int $modifiers();
void $modifiers(int v);
default Integer maybe() {
int i = $modifiers();
return i == 0 ? null : i;
}
default S modifiers(int v) {
$modifiers(v);
return $self();
}
//region Api
//@formatter:off
default S Public() {
$modifiers($modifiers() | Modifier.PUBLIC);
return $self();
}
default S Private() {
$modifiers($modifiers() | Modifier.PRIVATE);
return $self();
}
default S Protected() {
$modifiers($modifiers() | Modifier.PROTECTED);
return $self();
}
default S Static() {
$modifiers($modifiers() | Modifier.STATIC);
return $self();
}
default S Final() {
$modifiers($modifiers() | Modifier.FINAL);
return $self();
}
default S Synchronized() {
$modifiers($modifiers() | Modifier.SYNCHRONIZED);
return $self();
}
default S Volatile() {
$modifiers($modifiers() | Modifier.VOLATILE);
return $self();
}
default S Transient() {
$modifiers($modifiers() | Modifier.TRANSIENT);
return $self();
}
default S Native() {
$modifiers($modifiers() | Modifier.NATIVE);
return $self();
}
default S Interface() {
$modifiers($modifiers() | Modifier.INTERFACE);
return $self();
}
default S Abstract() {
$modifiers($modifiers() | Modifier.ABSTRACT);
return $self();
}
default S Bridge() {
$modifiers($modifiers() | 0x00000040);
return $self();
}
default S Varargs() {
$modifiers($modifiers() | 0x00000080);
return $self();
}
default S Synthetic() {
$modifiers($modifiers() | 0x00001000);
return $self();
}
default S Annotation() {
$modifiers($modifiers() | 0x00002000);
return $self();
}
default S Enum() {
$modifiers($modifiers() | 0x00004000);
return $self();
}
default S Mandated() {
$modifiers($modifiers() | 0x00008000);
return $self();
}
default S NotPublic() {
$modifiers($modifiers() & ~Modifier.PUBLIC);
return $self();
}
default S NotPrivate() {
$modifiers($modifiers() & ~Modifier.PRIVATE);
return $self();
}
default S NotProtected() {
$modifiers($modifiers() & ~Modifier.PROTECTED);
return $self();
}
default S NotStatic() {
$modifiers($modifiers() & ~Modifier.STATIC);
return $self();
}
default S NotFinal() {
$modifiers($modifiers() & ~Modifier.FINAL);
return $self();
}
default S NotSynchronized() {
$modifiers($modifiers() & ~Modifier.SYNCHRONIZED);
return $self();
}
default S NotVolatile() {
$modifiers($modifiers() & ~Modifier.VOLATILE);
return $self();
}
default S NotTransient() {
$modifiers($modifiers() & ~Modifier.TRANSIENT);
return $self();
}
default S NotNative() {
$modifiers($modifiers() & ~Modifier.NATIVE);
return $self();
}
default S NotInterface() {
$modifiers($modifiers() & ~Modifier.INTERFACE);
return $self();
}
default S NotAbstract() {
$modifiers($modifiers() & ~Modifier.ABSTRACT);
return $self();
}
default S NotBridge() {
$modifiers($modifiers() & ~0x00000040);
return $self();
}
default S NotVarargs() {
$modifiers($modifiers() & ~0x00000080);
return $self();
}
default S NotSynthetic() {
$modifiers($modifiers() & ~0x00001000);
return $self();
}
default S NotAnnotation() {
$modifiers($modifiers() & ~0x00002000);
return $self();
}
default S NotEnum() {
$modifiers($modifiers() & ~0x00004000);
return $self();
}
default S NotMandated() {
$modifiers($modifiers() & ~0x00008000);
return $self();
}
//@formatter:on
//endregion
default S And(int v) {
$modifiers($modifiers() | v);
return $self();
}
default S Not(int v) {
$modifiers($modifiers() & ~v);
return $self();
}
@Override
default void $validate() {
if ($modifiers() == 0) $modifiers(Modifier.PRIVATE);
}
default int modifiers() {
return $modifiers();
}
}
interface Name> extends Make {
String $name();
void $name(String v);
default String name() {
return $name();
}
default S name(String v) {
$name(v);
return $self();
}
@Override
default void $validate() {
String name = $name();
if (name == null || name.isEmpty()
|| (!Character.isUnicodeIdentifierStart(name.charAt(0)))
|| (!name.chars().skip(1).allMatch(Character::isUnicodeIdentifierPart))
)
throw new AssertionError("invalid name '" + name + "'");
}
abstract class Base> implements Name {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected String $name;
}
}
interface Identifier> extends Make {
String $identifier();
void $identifier(String v);
default String identifier() {
return $identifier();
}
default S identifier(String v) {
$identifier(v);
return $self();
}
@Override
default void $validate() {
String name = $identifier();
if (name == null || name.isEmpty()
|| (!Character.isUnicodeIdentifierStart(name.charAt(0)))
|| (!name.chars().skip(1)
.allMatch(DOT.or(Character::isUnicodeIdentifierPart)))
)
throw new AssertionError("invalid name '" + name + "'");
}
IntPredicate DOT = x -> x == '.';
}
/*
//LIST TEMPLATE
interface $Name$> extends Maker {
void $name$($Type$ v);
$Type$ $name$();
default S add$EName$($EType$ v){
var vs=$name$();
if(vs==null) $name$(vs=new ArrayList<>());
vs.add(v);
return $self();
}
default $Type$ $name0$(){
return $name$();
}
default S $name0$($Type$ v){
$name$(v);
return $self();
}
@Override
default void $validate() {
if ($name$() == null)
$name$(Collections.emptyList());
}
abstract class Base> implements $Name$ {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected $Type$ $name$;
}
}
*/
interface Annotations> extends Make {
void $annotations(List v);
List $annotations();
default S addAnnotation(AnnotationDescription v) {
List vs = $annotations();
if (vs == null) $annotations(vs = new ArrayList<>());
vs.add(v);
return $self();
}
@Override
default void $validate() {
if ($annotations() == null)
$annotations(emptyList());
}
default List annotations() {
return $annotations();
}
default S annotations(List v) {
$annotations(v);
return $self();
}
default S annotation(TypeDescription anno, UnaryOperator v) {
return addAnnotation(v.apply(AnnotationDescription.Builder.ofType(anno)).build());
}
abstract class Base> implements Annotations {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $annotations;
}
}
interface Bounds> extends Make {
void $bounds(List v);
List $bounds();
default S addBound(Generic v) {
List vs = $bounds();
if (vs == null) $bounds(vs = new ArrayList<>());
vs.add(v);
return $self();
}
default List bounds() {
return $bounds();
}
default S bounds(List v) {
$bounds(v);
return $self();
}
@Override
default void $validate() {
if ($bounds() == null)
$bounds(emptyList());
}
default S bound(Class> simple) {
assert simple.getTypeParameters().length == 0 : "type parameters should be zero";
return addBound(Generic.OfNonGenericType.ForLoadedType.of(simple));
}
default S bound(Class> raw, UnaryOperator build) {
assert raw.getTypeParameters().length != 0 : "type parameters is empty";
return addBound(build.apply(Generic.Builder.of(raw)).build());
}
abstract class Base> implements Bounds {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $bounds;
}
}
interface DeclaringClass> extends Make {
TypeDescription $declaringClass();
void $declaringClass(TypeDescription v);
default TypeDescription declaringClass() {
return $declaringClass();
}
default S declaringClass(TypeDescription v) {
$declaringClass(v);
return $self();
}
@Override
default void $validate() {
if ($declaringClass() == null) throw new IllegalStateException("missing DeclaringClass");
}
default S declaringClass(Class> simple) {
assert simple.getTypeParameters().length == 0 : "type parameters should be zero";
return declaringClass(TypeDescription.ForLoadedType.of(simple));
}
abstract class Base> implements DeclaringClass {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected TypeDescription $declaringClass;
}
interface Generic> extends Make {
TypeDescription.Generic $declaringClass();
void $declaringClass(TypeDescription.Generic v);
default TypeDescription.Generic declaringClass() {
return $declaringClass();
}
default S declaringClass(TypeDescription.Generic v) {
$declaringClass(v);
return $self();
}
@Override
default void $validate() {
if ($declaringClass() == null) throw new IllegalStateException("missing DeclaringClass");
}
default S declaringClass(Class> simple) {
assert simple.getTypeParameters().length == 0 : "type parameters should be zero";
return declaringClass(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(simple));
}
default S declaringClass(Class> raw, UnaryOperator build) {
return declaringClass(build.apply(TypeDescription.Generic.Builder.of(raw)).build());
}
abstract class Base> implements Generic {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected TypeDescription.Generic $declaringClass;
}
}
}
interface ExceptionTypes> extends Make {
void $exceptionTypes(List v);
List $exceptionTypes();
default S addExceptionType(TypeDescription v) {
List vs = $exceptionTypes();
if (vs == null) $exceptionTypes(vs = new ArrayList<>());
vs.add(v);
return $self();
}
default List exceptionTypes() {
return $exceptionTypes();
}
default S exceptionTypes(List v) {
$exceptionTypes(v);
return $self();
}
@Override
default void $validate() {
if ($exceptionTypes() == null)
$exceptionTypes(emptyList());
}
default S exceptionType(Class> simple) {
return addExceptionType(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(simple).asErasure());
}
abstract class Base> implements ExceptionTypes {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $exceptionTypes;
}
interface Generic> extends Make {
void $exceptionTypes(List v);
List $exceptionTypes();
default S addExceptionType(TypeDescription.Generic v) {
List vs = $exceptionTypes();
if (vs == null) $exceptionTypes(vs = new ArrayList<>());
vs.add(v);
return $self();
}
default List exceptionTypes() {
return $exceptionTypes();
}
default S exceptionTypes(List v) {
$exceptionTypes(v);
return $self();
}
@Override
default void $validate() {
if ($exceptionTypes() == null)
$exceptionTypes(emptyList());
}
default S exceptionType(Class> simple) {
return addExceptionType(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(simple));
}
default S exceptionType(Class> raw, UnaryOperator build) {
return addExceptionType(build.apply(TypeDescription.Generic.Builder.of(raw)).build());
}
abstract class Base> implements Generic {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $exceptionTypes;
}
}
}
interface ReturnType> extends Make {
Generic $returnType();
void $returnType(Generic v);
default Generic returnType() {
return $returnType();
}
default S returnType(Generic v) {
$returnType(v);
return $self();
}
@Override
default void $validate() {
if ($returnType() == null) $returnType(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(void.class));
}
default S returnType(Class> simple) {
return returnType(Generic.OfNonGenericType.ForLoadedType.of(simple));
}
default S returnType(Class> raw, UnaryOperator build) {
return returnType(build.apply(Generic.Builder.of(raw)).build());
}
abstract class Base> implements ReturnType {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected Generic $returnType;
}
}
interface Type> extends Make {
TypeDescription $type();
void $type(TypeDescription v);
default TypeDescription type() {
return $type();
}
default S type(TypeDescription v) {
$type(v);
return $self();
}
default S type(Class> v) {
return type(TypeDescription.ForLoadedType.of(v));
}
@Override
default void $validate() {
if ($type() == null) $type(TypeDescription.ForLoadedType.of(void.class));
}
abstract class Base> implements Type {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected TypeDescription $type;
}
interface Generic> extends Make {
TypeDescription.Generic $type();
void $type(TypeDescription.Generic v);
default TypeDescription.Generic type() {
return $type();
}
default S type(TypeDescription.Generic v) {
$type(v);
return $self();
}
@Override
default void $validate() {
if ($type() == null) $type(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(void.class));
}
default S type(Class> v) {
return type(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(v));
}
default S type(Class> raw, UnaryOperator build) {
return type(build.apply(TypeDescription.Generic.Builder.of(raw)).build());
}
abstract class Base> implements Generic {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected TypeDescription.Generic $type;
}
}
}
interface SuperClass> extends Make {
TypeDescription $superClass();
void $superClass(TypeDescription v);
default TypeDescription superClass() {
return $superClass();
}
default S superClass(TypeDescription v) {
$superClass(v);
return $self();
}
@Override
default void $validate() {
if ($superClass() == null) $superClass(TypeDescription.ForLoadedType.of(Object.class));
}
default S superClass(Class> v) {
return superClass(TypeDescription.ForLoadedType.of(v));
}
abstract class Base> implements Type {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected TypeDescription $superClass;
}
interface Generic> extends Make {
TypeDescription.Generic $superClass();
void $superClass(TypeDescription.Generic v);
default TypeDescription.Generic superClass() {
return $superClass();
}
default S superClass(TypeDescription.Generic v) {
$superClass(v);
return $self();
}
@Override
default void $validate() {
if ($superClass() == null) $superClass(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(void.class));
}
default S superClass(Class> v) {
return superClass(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(v));
}
default S superClass(Class> raw, UnaryOperator build) {
return superClass(build.apply(TypeDescription.Generic.Builder.of(raw)).build());
}
}
}
interface Implements> extends Make {
void $implements(List v);
List $implements();
default S addImplement(TypeDescription v) {
List vs = $implements();
if (vs == null) $implements(vs = new ArrayList<>());
vs.add(v);
return $self();
}
default List interfaces() {
return $implements();
}
default S interfaces(List v) {
$implements(v);
return $self();
}
default S implement(Class> simple) {
assert simple.getTypeParameters().length == 0 : "type parameters should be zero";
return addImplement(TypeDescription.ForLoadedType.of(simple));
}
default S implement(Class> raw, UnaryOperator build) {
assert raw.getTypeParameters().length != 0 : "type parameters is empty";
return addImplement(build.apply(TypeDescription.Generic.Builder.of(raw)).build().asErasure());
}
@Override
default void $validate() {
if ($implements() == null)
$implements(emptyList());
}
default S implement(TypeDescription... implement) {
List v = $implements();
if (v == null) $implements(v = new ArrayList<>());
v.addAll(Arrays.asList(implement));
return $self();
}
default S implement(List implement) {
List v = $implements();
if (v == null) $implements(v = new ArrayList<>());
v.addAll(implement);
return $self();
}
abstract class Base> implements Implements {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $implements;
}
interface Generic> extends Make {
void $implements(List v);
List $implements();
default S addImplement(TypeDescription.Generic v) {
List vs = $implements();
if (vs == null) $implements(vs = new ArrayList<>());
vs.add(v);
return $self();
}
default List interfaces() {
return $implements();
}
default S interfaces(List v) {
$implements(v);
return $self();
}
default S implement(Class> simple) {
assert simple.getTypeParameters().length == 0 : "type parameters should be zero";
return addImplement(TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(simple));
}
default S implement(Class> raw, UnaryOperator build) {
assert raw.getTypeParameters().length != 0 : "type parameters is empty";
return addImplement(build.apply(TypeDescription.Generic.Builder.of(raw)).build());
}
@Override
default void $validate() {
if ($implements() == null)
$implements(emptyList());
}
default S implement(TypeDescription.Generic... implement) {
List v = $implements();
if (v == null) $implements(v = new ArrayList<>());
v.addAll(Arrays.asList(implement));
return $self();
}
default S implement(List implement) {
List v = $implements();
if (v == null) $implements(v = new ArrayList<>());
v.addAll(implement);
return $self();
}
}
}
interface ParameterTypes> extends Make {
void $parameterTypes(List v);
List $parameterTypes();
default S addParameterType(TypeDescription v) {
List vs = $parameterTypes();
if (vs == null) $parameterTypes(vs = new ArrayList<>());
vs.add(v);
return $self();
}
default List parameterTypes() {
return $parameterTypes();
}
default S parameterTypes(List v) {
$parameterTypes(v);
return $self();
}
@Override
default void $validate() {
if ($parameterTypes() == null)
$parameterTypes(emptyList());
}
abstract class Base> implements ParameterTypes {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $parameterTypes;
}
}
//endregion
//region FieldDescription.Token
interface FieldToken> extends
Modifiers
, Annotations
, Type.Generic
, Name
, Make {
@Override
default void $validate() {
//Private
Modifiers.super.$validate();
Name.super.$validate();
Type.Generic.super.$validate();
}
default FieldDescription.Token fieldToken() {
return new FieldDescription.Token(name(), modifiers(), type(), annotations());
}
}
interface FieldTokenMake extends FieldToken {
default FieldDescription.Token make() {
$validate();
return fieldToken();
}
class Impl implements FieldTokenMake {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected String $name;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected int $modifiers;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $annotations;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected Generic $type;
@Override
public Impl $self() {
return this;
}
}
}
static FieldTokenMake fieldToken() {
return new FieldTokenMake.Impl();
}
static FieldTokenMake fieldToken(FieldDescription.Token v) {
return new FieldTokenMake.Impl()
.annotations(v.getAnnotations())
.modifiers(v.getModifiers())
.type(v.getType())
.name(v.getName())
;
}
//endregion
//region FieldDescription
interface FieldMake extends FieldToken, DeclaringClass {
@Override
default void $validate() {
FieldToken.super.$validate();
DeclaringClass.super.$validate();
}
default FieldDescription make() {
$validate();
return new FieldDescription.Latent(declaringClass(), fieldToken());
}
class Impl implements FieldMake {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected String $name;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected int $modifiers;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $annotations;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected TypeDescription.Generic $type;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected TypeDescription $declaringClass;
@Override
public Impl $self() {
return this;
}
}
}
static FieldMake field() {
return new FieldMake.Impl();
}
static FieldMake field(FieldDescription desc) {
return new FieldMake.Impl()
.declaringClass(desc.getDeclaringType().asErasure())
.annotations(desc.getDeclaredAnnotations())
.modifiers(desc.getModifiers())
.type(desc.getType())
.name(desc.getName());
}
//endregion
//region ParameterDescription.Token
interface ParameterToken> extends
Modifiers
, Name
, Annotations
, Type.Generic
, Make {
@Override
default void $validate() {
Type.Generic.super.$validate();
if (name() == null) $name("");
}
default ParameterDescription.Token parameterToken() {
return new ParameterDescription.Token(type(), annotations(), name(), maybe());
}
interface Many> extends Make {
List $parameters();
void $parameters(List v);
default S addParameter(ParameterDescription.Token v) {
List vs = $parameters();
if (vs == null) $parameters(vs = new ArrayList<>());
vs.add(v);
return $self();
}
default List parameters() {
return $parameters();
}
default S parameters(List v) {
$parameters(v);
return $self();
}
default S parameter(ParameterDescription.Token v) {
return addParameter(v);
}
default S parameter(UnaryOperator v) {
return addParameter(v.apply(Make.parameter()).make());
}
@Override
default void $validate() {
if ($parameters() == null) $parameters(emptyList());
}
}
}
interface ParameterTokenMake extends ParameterToken {
default ParameterDescription.Token make() {
$validate();
return parameterToken();
}
class Impl implements ParameterTokenMake {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected String $name;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected Generic $type;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $annotations;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected int $modifiers;
@Override
public ParameterTokenMake $self() {
return this;
}
}
}
static ParameterTokenMake parameter() {
return new ParameterTokenMake.Impl();
}
static ParameterTokenMake parameter(ParameterDescription.Token desc) {
return new ParameterTokenMake.Impl()
.modifiers(desc.getModifiers() == null ? 0 : desc.getModifiers())
.name(desc.getName())
.type(desc.getType())
.annotations(desc.getAnnotations());
}
//endregion
//region TypeVariableToken
interface TypeVariable> extends Make
, Name
, Bounds
, Annotations {
@Override
default void $validate() {
Name.super.$validate();
}
default TypeVariableToken typeVariable() {
return new TypeVariableToken($name(), $bounds(), $annotations());
}
interface Many> extends Make {
void $typeVariables(List val);
List $typeVariables();
@Override
default void $validate() {
if ($typeVariables() == null) $typeVariables(emptyList());
}
default S addTypeVariable(TypeVariableToken val) {
List v = $typeVariables();
if (v == null) $typeVariables(v = new ArrayList<>());
v.add(val);
return $self();
}
default List typeVariables() {
return $typeVariables();
}
default S typeVariables(List v) {
$typeVariables(v);
return $self();
}
default S typeVariable(TypeVariableToken val) {
return addTypeVariable(val);
}
default S typeVariable(UnaryOperator val) {
return addTypeVariable(val.apply(Make.typeVariable()).make());
}
}
}
interface TypeVariableMake extends TypeVariable {
default TypeVariableToken make() {
$validate();
return typeVariable();
}
class Impl implements TypeVariableMake {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $annotations;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected String $name;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $bounds;
@Override
public TypeVariableMake $self() {
return this;
}
}
}
static TypeVariableMake typeVariable() {
return new TypeVariableMake.Impl();
}
static TypeVariableMake typeVariable(TypeVariableToken desc) {
return new TypeVariableMake.Impl()
.annotations(desc.getAnnotations())
.bounds(desc.getBounds())
.name(desc.getSymbol());
}
//endregion
//region MethodDescription.Token
interface MethodToken> extends Make
, Name
, Modifiers
, TypeVariable.Many
, ExceptionTypes.Generic
, Annotations
, ReturnType
, ParameterToken.Many {
ElementMatcher.Junction IS_THROWABLE = ElementMatchers.hasSuperType(ElementMatchers.is(Throwable.class));
@Override
default void $validate() {
Modifiers.super.$validate();
Name.super.$validate();
Annotations.super.$validate();
ReturnType.super.$validate();
ParameterToken.Many.super.$validate();
TypeVariable.Many.super.$validate();
ExceptionTypes.Generic.super.$validate();
List exceptionTypes = $exceptionTypes();
if (exceptionTypes != null && !exceptionTypes.stream().map(TypeDefinition::asErasure).allMatch(IS_THROWABLE::matches))
throw new AssertionError("have invalid exception type in " + exceptionTypes);
AnnotationValue, ?> defaultValue = defaultValue();
if (defaultValue != null && AnnotationValue.Sort.of($returnType().asErasure()) != defaultValue.getSort())
throw new AssertionError("invalid defaultValue with " + defaultValue);
if (defaultValue != null && defaultValue.getSort() == AnnotationValue.Sort.NONE) defaultValue(null);
}
S defaultValue(AnnotationValue, ?> val);
S receiverType(Generic val);
AnnotationValue, ?> defaultValue();
Generic receiverType();
default MethodDescription.Token methodToken() {
return new MethodDescription.Token(
name(),
modifiers(),
typeVariables(),
returnType(),
parameters(),
exceptionTypes(),
annotations(),
defaultValue(),
receiverType()
);
}
}
interface MethodTokenMake extends MethodToken {
@Override
MethodTokenMake receiverType(Generic val);
@Override
AnnotationValue, ?> defaultValue();
default MethodDescription.Token make() {
$validate();
return methodToken();
}
class Impl implements MethodTokenMake {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private int $modifiers;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private String $name;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private Generic $returnType;
@Getter
@Accessors(fluent = true, chain = true)
protected AnnotationValue, ?> defaultValue;
@Getter
@Accessors(fluent = true, chain = true)
protected Generic receiverType;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $annotations;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $exceptionTypes;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $typeVariables;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $parameters;
@Override
public MethodTokenMake $self() {
return this;
}
@Override
public MethodTokenMake defaultValue(AnnotationValue, ?> val) {
defaultValue = val;
return this;
}
@Override
public MethodTokenMake receiverType(Generic val) {
receiverType = val;
return this;
}
}
}
static MethodTokenMake methodToken() {
return new MethodTokenMake.Impl();
}
static MethodTokenMake methodToken(MethodDescription.Token desc) {
return new MethodTokenMake.Impl()
.modifiers(desc.getModifiers())
.annotations(desc.getAnnotations())
.returnType(desc.getReturnType())
.name(desc.getName())
.parameters(desc.getParameterTokens())
.typeVariables(desc.getTypeVariableTokens())
.exceptionTypes(desc.getExceptionTypes())
.defaultValue(desc.getDefaultValue())
.receiverType(desc.getReceiverType());
}
//endregion
//region MethodDescription
interface MethodMake extends Make, MethodToken, DeclaringClass {
@Override
default void $validate() {
DeclaringClass.super.$validate();
MethodToken.super.$validate();
}
default MethodDescription make() {
$validate();
return new MethodDescription.Latent(
$declaringClass(), methodToken());
}
class Impl implements MethodMake {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private int $modifiers;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private String $name;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private TypeDescription.Generic $returnType;
@Getter
@Accessors(fluent = true, chain = true)
protected AnnotationValue, ?> defaultValue;
@Getter
@Accessors(fluent = true, chain = true)
protected TypeDescription.Generic receiverType;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $annotations;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $exceptionTypes;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $typeVariables;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private List $parameters;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
private TypeDescription $declaringClass;
@Override
public MethodMake $self() {
return this;
}
@Override
public MethodMake defaultValue(AnnotationValue, ?> val) {
defaultValue = val;
return this;
}
@Override
public MethodMake receiverType(TypeDescription.Generic val) {
receiverType = val;
return this;
}
}
}
static MethodMake method() {
return new MethodMake.Impl();
}
static MethodMake method(MethodDescription desc) {
return new MethodMake.Impl()
.declaringClass(desc.getDeclaringType().asErasure())
.modifiers(desc.getModifiers())
.annotations(desc.getDeclaredAnnotations())
.returnType(desc.getReturnType())
.name(desc.getName())
.parameters(desc.getParameters().asTokenList(none()))
.typeVariables(desc.getTypeVariables().asTokenList(none()))
.exceptionTypes(desc.getExceptionTypes())
.defaultValue(desc.getDefaultValue())
.receiverType(desc.getReceiverType());
}
//endregion
//region TypeDescription
interface TypeMake extends Make
, Modifiers
, Identifier
, SuperClass.Generic
, Implements.Generic {
@Override
default void $validate() {
Modifiers.super.$validate();
Identifier.super.$validate();
Implements.Generic.super.$validate();
}
default TypeDescription make() {
$validate();
return new TypeDescription.Latent(identifier(), modifiers(), superClass(), interfaces());
}
class Impl implements TypeMake {
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected Generic $superClass;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected String $identifier;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected int $modifiers;
@Getter
@Setter
@Accessors(fluent = true, chain = false)
protected List $implements;
@Override
public TypeMake $self() {
return this;
}
}
}
static TypeMake type() {
return new TypeMake.Impl();
}
static TypeMake type(TypeDescription desc) {
return new TypeMake.Impl()
.modifiers(desc.getModifiers())
.identifier(desc.getName())
.superClass(desc.getSuperClass())
.implement(desc.getInterfaces());
}
//endregion
//region TypeDescription.Generic
static Generic.Builder generic(Generic desc) {
return Generic.Builder.of(desc);
}
static Generic.Builder generic(java.lang.reflect.Type desc) {
return Generic.Builder.of(desc);
}
static Generic.Builder generic(Class> rawType) {
return Generic.Builder.rawType(rawType);
}
static Generic.Builder generic(TypeDescription type, Generic owner) {
return Generic.Builder.rawType(type, owner);
}
static Generic.Builder generic(String symbol) {
return Generic.Builder.typeVariable(symbol);
}
static Generic.Builder generic(Class> rawType, java.lang.reflect.Type... parameter) {
return Generic.Builder.parameterizedType(rawType, parameter);
}
static Generic.Builder generic(TypeDescription rawType, TypeDefinition... parameter) {
return Generic.Builder.parameterizedType(rawType, parameter);
}
static Generic.Builder generic(TypeDescription rawType, List parameters) {
return Generic.Builder.parameterizedType(rawType, parameters);
}
//endregion
//region AnnotationDescription
static AnnotationDescription.Builder annotation(Class extends Annotation> type) {
return AnnotationDescription.Builder.ofType(type);
}
static AnnotationDescription.Builder annotation(TypeDescription type) {
return AnnotationDescription.Builder.ofType(type);
}
//endregion
}