Skip to content

Commit

Permalink
Introduce SignatureBuilder API
Browse files Browse the repository at this point in the history
  • Loading branch information
mkouba committed Jan 6, 2023
1 parent 602dc3a commit 8787f16
Show file tree
Hide file tree
Showing 7 changed files with 959 additions and 1 deletion.
93 changes: 93 additions & 0 deletions src/main/java/io/quarkus/gizmo/ClassSignatureBuilderImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package io.quarkus.gizmo;

import java.util.ArrayList;
import java.util.List;

import org.jboss.jandex.DotName;

import io.quarkus.gizmo.SignatureBuilder.ClassSignatureBuilder;
import io.quarkus.gizmo.Type.ClassType;
import io.quarkus.gizmo.Type.ParameterizedType;
import io.quarkus.gizmo.Type.TypeVariable;

class ClassSignatureBuilderImpl implements ClassSignatureBuilder {

private Type superClass = Type.classType(DotName.OBJECT_NAME);
private List<TypeVariable> typeParameters = new ArrayList<>();
private List<Type> superInterfaces = new ArrayList<>();

@Override
public String build() {
StringBuilder signature = new StringBuilder();

// type params
if (!typeParameters.isEmpty()) {
signature.append('<');
for (TypeVariable typeParameter : typeParameters) {
typeParameter.appendTypeParameterToSignature(signature);
}
signature.append('>');
}

// superclass
signature.append(superClass.toSignature());

// interfaces
if (!superInterfaces.isEmpty()) {
for (Type superInterface : superInterfaces) {
signature.append(superInterface.toSignature());
}
}
return signature.toString();
}

@Override
public ClassSignatureBuilder addTypeParameter(TypeVariable typeParameter) {
typeParameters.add(typeParameter);
return this;
}

@Override
public ClassSignatureBuilder setSuperClass(ClassType superClass) {
this.superClass = superClass;
return this;
}

@Override
public ClassSignatureBuilder setSuperClass(ParameterizedType superClass) {
if (containsWildcard(superClass)) {
throw new IllegalArgumentException("A super type may not specify a wilcard");
}
this.superClass = superClass;
return this;
}

@Override
public ClassSignatureBuilder addSuperInterface(ClassType interfaceType) {
superInterfaces.add(interfaceType);
return this;
}

@Override
public ClassSignatureBuilder addSuperInterface(ParameterizedType interfaceType) {
if (containsWildcard(interfaceType)) {
throw new IllegalArgumentException("A super type may not specify a wilcard");
}
superInterfaces.add(interfaceType);
return this;
}

private boolean containsWildcard(Type type) {
if (type.isWildcard()) {
return true;
} else if (type.isParameterizedType()) {
for (Type typeArgument : type.asParameterizedType().typeArguments) {
if (containsWildcard(typeArgument)) {
return true;
}
}
}
return false;
}

}
22 changes: 22 additions & 0 deletions src/main/java/io/quarkus/gizmo/FieldSignatureBuilderImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.gizmo;

import java.util.Objects;

import io.quarkus.gizmo.SignatureBuilder.FieldSignatureBuilder;

class FieldSignatureBuilderImpl implements FieldSignatureBuilder {

private Type type;

@Override
public String build() {
return type.toSignature();
}

@Override
public FieldSignatureBuilder setType(Type type) {
this.type = Objects.requireNonNull(type);
return this;
}

}
80 changes: 80 additions & 0 deletions src/main/java/io/quarkus/gizmo/MethodSignatureBuilderImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package io.quarkus.gizmo;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import io.quarkus.gizmo.SignatureBuilder.MethodSignatureBuilder;
import io.quarkus.gizmo.Type.ClassType;
import io.quarkus.gizmo.Type.TypeVariable;

class MethodSignatureBuilderImpl implements MethodSignatureBuilder {

private Type returnType = Type.voidType();
private List<Type> parameterTypes = new ArrayList<>();
private List<TypeVariable> typeParameters = new ArrayList<>();
private List<Type> exceptions = new ArrayList<>();

@Override
public String build() {
StringBuilder signature = new StringBuilder();

// type params
if (!typeParameters.isEmpty()) {
signature.append('<');
for (TypeVariable typeParameter : typeParameters) {
typeParameter.appendTypeParameterToSignature(signature);
}
signature.append('>');
}

// params
signature.append('(');
for (Type parameterType : parameterTypes) {
signature.append(parameterType.toSignature());
}
signature.append(')');

// return type
signature.append(returnType.toSignature());

// exceptions
if (!exceptions.isEmpty()) {
for (Type exceptionType : exceptions) {
signature.append('^').append(exceptionType.toSignature());
}
}
return signature.toString();
}

@Override
public MethodSignatureBuilder addTypeParameter(TypeVariable typeParameter) {
typeParameters.add(Objects.requireNonNull(typeParameter));
return this;
}

@Override
public MethodSignatureBuilder setReturnType(Type returnType) {
this.returnType = Objects.requireNonNull(returnType);
return this;
}

@Override
public MethodSignatureBuilder addParameter(Type parameterType) {
this.parameterTypes.add(Objects.requireNonNull(parameterType));
return this;
}

@Override
public MethodSignatureBuilder addException(ClassType exceptionType) {
this.exceptions.add(Objects.requireNonNull(exceptionType));
return this;
}

@Override
public MethodSignatureBuilder addException(TypeVariable exceptionType) {
this.exceptions.add(Objects.requireNonNull(exceptionType));
return this;
}

}
62 changes: 62 additions & 0 deletions src/main/java/io/quarkus/gizmo/SignatureBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.quarkus.gizmo;

import io.quarkus.gizmo.Type.ClassType;
import io.quarkus.gizmo.Type.ParameterizedType;
import io.quarkus.gizmo.Type.TypeVariable;

/**
* Builds a signature as defined in JVMS 17, chapter "4.7.9.1. Signatures".
*
* @see SignatureElement#setSignature(String)
*/
public interface SignatureBuilder {

static ClassSignatureBuilder forClass() {
return new ClassSignatureBuilderImpl();
}

static MethodSignatureBuilder forMethod() {
return new MethodSignatureBuilderImpl();
}

static FieldSignatureBuilder forField() {
return new FieldSignatureBuilderImpl();
}

/**
* @return the signature
*/
String build();

interface ClassSignatureBuilder extends SignatureBuilder {

ClassSignatureBuilder addTypeParameter(TypeVariable typeParameter);

ClassSignatureBuilder setSuperClass(ClassType superClass);

ClassSignatureBuilder setSuperClass(ParameterizedType superClass);

ClassSignatureBuilder addSuperInterface(ClassType interfaceType);

ClassSignatureBuilder addSuperInterface(ParameterizedType interfaceType);
}

interface MethodSignatureBuilder extends SignatureBuilder {

MethodSignatureBuilder addTypeParameter(TypeVariable typeParameter);

MethodSignatureBuilder setReturnType(Type returnType);

MethodSignatureBuilder addParameter(Type parameter);

MethodSignatureBuilder addException(ClassType exceptionType);

MethodSignatureBuilder addException(TypeVariable exceptionType);
}

interface FieldSignatureBuilder extends SignatureBuilder {

FieldSignatureBuilder setType(Type type);
}

}
9 changes: 8 additions & 1 deletion src/main/java/io/quarkus/gizmo/SignatureElement.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
package io.quarkus.gizmo;

/**
* An element that has a signature attribute
* An element that has a signature attribute.
*/
public interface SignatureElement<S> {

String getSignature();

/**
* Use the convenient {@link SignatureBuilder} to build signatures for classes, methods and fields.
*
* @param signature The signature as defined in JVMS 17, chapter "4.7.9.1. Signatures"
* @return the element
* @see SignatureBuilder
*/
S setSignature(String signature);
}
Loading

0 comments on commit 8787f16

Please sign in to comment.