Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
660 changes: 164 additions & 496 deletions src/main/java/io/vertx/codegen/ClassModel.java

Large diffs are not rendered by default.

17 changes: 14 additions & 3 deletions src/main/java/io/vertx/codegen/CodeGenProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@
import java.io.Writer;
import java.lang.annotation.Annotation;
import java.util.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -236,11 +247,11 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
}
// Generate files
generatedFiles.values().forEach(generated -> {
// todo: need to rewrite "/" according to platform file separator
boolean shouldWarningsBeSuppressed = false;
File file;
if (generated.uri.startsWith("/")) {
file = new File(generated.uri);
Path path = Paths.get(generated.uri);
if (path.isAbsolute()) {
file = path.toFile();
} else if (outputDirectory != null) {
file = new File(outputDirectory, generated.uri);
} else {
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/io/vertx/codegen/CompanionHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.vertx.codegen;

import io.vertx.codegen.annotations.GenIgnore;

import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;

import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet;
import static javax.lang.model.element.ElementKind.CLASS;
import static javax.lang.model.element.ElementKind.FIELD;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.STATIC;

/**
* @author Евгений Уткин ([email protected])
*/
public class CompanionHelper {

public static Optional<TypeElement> getCompanion(Element rootElt) {
List<? extends Element> enclosedElements = rootElt.getEnclosedElements();

Map<TypeMirror, ? extends Element> companionCandidates = enclosedElements
.stream()
.filter((Element companionCandidate) -> companionCandidate.getKind() == CLASS)
.collect(toMap(Element::asType, Function.identity()));

Set<TypeMirror> fieldCompanionCandidate = enclosedElements
.stream()
.filter((Element elt) -> elt.getKind() == FIELD && elt.getModifiers().containsAll(asList(STATIC, FINAL)))
.map(Element::asType).collect(toSet());

companionCandidates.keySet().retainAll(fieldCompanionCandidate);

if (companionCandidates.size() > 1) {
throw new RuntimeException();
}
Iterator<? extends Element> iter = companionCandidates.values().iterator();
if (iter.hasNext()) {
return Optional.of(iter.next())
.map(TypeElement.class::cast)
.filter(elt -> elt.getAnnotation(GenIgnore.class) == null);
}
return Optional.empty();
}

}
34 changes: 33 additions & 1 deletion src/main/java/io/vertx/codegen/MethodInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,21 @@

import io.vertx.codegen.doc.Doc;
import io.vertx.codegen.doc.Text;
import io.vertx.codegen.type.AnnotationValueInfo;
import io.vertx.codegen.type.ClassKind;
import io.vertx.codegen.type.ClassTypeInfo;
import io.vertx.codegen.type.ParameterizedTypeInfo;
import io.vertx.codegen.type.TypeInfo;
import io.vertx.codegen.type.TypeVariableInfo;

import java.util.*;
import javax.lang.model.element.Name;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
* @author <a href="http://tfox.org">Tim Fox</a>
Expand All @@ -45,6 +53,8 @@ public class MethodInfo implements Comparable<MethodInfo> {
private List<ParamInfo> params;
private boolean deprecated;
private Text deprecatedDesc;
private Name companion;
private List<AnnotationValueInfo> annotations;

public MethodInfo(Set<ClassTypeInfo> ownerTypes, String name,
TypeInfo returnType, Text returnDescription, boolean fluent, boolean cacheReturn,
Expand Down Expand Up @@ -285,6 +295,19 @@ public MethodInfo setDefaultMethod(boolean defaultMethod) {
return this;
}

public String getCompanion() {
return Objects.toString(companion);
}

public MethodInfo setCompanion(Name companionObjectName) {
this.companion = companionObjectName;
return this;
}

public boolean isCompanionMethod() {
return companion != null;
}

/**
*
* @return {@code true} if the method has a {@code @Deprecated} annotation
Expand Down Expand Up @@ -319,6 +342,15 @@ public MethodInfo setTypeParams(List<TypeParamInfo.Method> typeParams) {
return this;
}

public List<AnnotationValueInfo> getAnnotations() {
return annotations;
}

public MethodInfo setAnnotations(List<AnnotationValueInfo> annotations) {
this.annotations = annotations;
return this;
}

public void mergeTypeParams(List<TypeParamInfo.Method> mergedTypeParams) throws IllegalArgumentException {
int l = Math.min(typeParams.size(), mergedTypeParams.size());
if (typeParams.subList(0, l).equals(mergedTypeParams.subList(0, l))) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.vertx.codegen.service.method.checker;

import io.vertx.codegen.type.ApiTypeInfo;
import io.vertx.codegen.type.ClassKind;
import io.vertx.codegen.type.ParameterizedTypeInfo;
import io.vertx.codegen.type.TypeInfo;

import javax.lang.model.element.ExecutableElement;

/**
* @author Евгений Уткин ([email protected])
*/
public class AllowParameterizedVertxGenInterfaceChecker implements Checker {

public static Checker getInstance() {
return new AllowParameterizedVertxGenInterfaceChecker();
}

@Override
public boolean check(ExecutableElement elt, TypeInfo type, boolean allowAnyJavaType) {
if (type.getKind() == ClassKind.API) {
if (type.isParameterized()) {
ParameterizedTypeInfo parameterized = (ParameterizedTypeInfo) type;
for (TypeInfo paramType : parameterized.getArgs()) {
ClassKind kind = paramType.getKind();
if (!(paramType instanceof ApiTypeInfo || paramType.isVariable() || kind == ClassKind.VOID
|| kind.basic || kind.json || kind == ClassKind.DATA_OBJECT || kind == ClassKind.ENUM)) {
return false;
}
if (paramType.isNullable()) {
return false;
}
}
return true;
} else {
return true;
}
}
return false;
}
}
15 changes: 15 additions & 0 deletions src/main/java/io/vertx/codegen/service/method/checker/Checker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.vertx.codegen.service.method.checker;

import io.vertx.codegen.type.TypeInfo;

import javax.lang.model.element.ExecutableElement;

/**
* @author Евгений Уткин ([email protected])
*/
@FunctionalInterface
public interface Checker {

boolean check(ExecutableElement elt, TypeInfo type, boolean allowAnyJavaType);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.vertx.codegen.service.method.checker;

import io.vertx.codegen.type.ClassKind;
import io.vertx.codegen.type.TypeInfo;

import javax.lang.model.element.ExecutableElement;

/**
* @author Евгений Уткин ([email protected])
*/
public class LegalArgumentContainerParamChecker implements Checker {

private final Checker vertxGenInterfaceChecker;

public static Checker getInstance() {
return new LegalArgumentContainerParamChecker();
}

public LegalArgumentContainerParamChecker(Checker vertxGenInterfaceChecker) {
this.vertxGenInterfaceChecker = vertxGenInterfaceChecker;
}

public LegalArgumentContainerParamChecker() {
this.vertxGenInterfaceChecker = NotAllowParameterizedVertxGenInterfaceChecker.getInstance();
}

@Override
public boolean check(ExecutableElement elt, TypeInfo type, boolean allowAnyJavaType) {
ClassKind argumentKind = type.getKind();
return argumentKind.basic
|| argumentKind.json
|| vertxGenInterfaceChecker.check(elt, type, false)
|| argumentKind == ClassKind.OBJECT
|| (allowAnyJavaType && argumentKind == ClassKind.OTHER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.vertx.codegen.service.method.checker;

import io.vertx.codegen.type.ClassKind;
import io.vertx.codegen.type.TypeInfo;

import javax.lang.model.element.ExecutableElement;

/**
* @author Евгений Уткин ([email protected])
*/
public class LegalArgumentContainerReturnChecker implements Checker {

public static Checker getInstance() {
return new LegalArgumentContainerReturnChecker();
}

@Override
public boolean check(ExecutableElement elt, TypeInfo type, boolean allowAnyJavaType) {
ClassKind argumentKind = type.getKind();
return argumentKind.basic
|| argumentKind.json
|| argumentKind == ClassKind.OBJECT
|| (allowAnyJavaType && argumentKind == ClassKind.OTHER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.vertx.codegen.service.method.checker;

import io.vertx.codegen.type.ClassKind;
import io.vertx.codegen.type.TypeInfo;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.util.Elements;

/**
* @author Евгений Уткин ([email protected])
*/
public class LegalCallbackValueTypeChecker implements Checker {

private final Checker legalNonCallableReturnType;

public static Checker getInstance(Elements elementUtils) {
return new LegalCallbackValueTypeChecker(elementUtils);
}

public LegalCallbackValueTypeChecker(Checker legalNonCallableReturnType) {
this.legalNonCallableReturnType = legalNonCallableReturnType;
}

public LegalCallbackValueTypeChecker(Elements elementUtils) {
this.legalNonCallableReturnType = LegalNonCallableReturnTypeChecker.getInstance(elementUtils);
}

@Override
public boolean check(ExecutableElement elt, TypeInfo type, boolean allowAnyJavaType) {
if (type.getKind() == ClassKind.VOID) {
return true;
}
return legalNonCallableReturnType.check(elt, type, allowAnyJavaType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.vertx.codegen.service.method.checker;

import io.vertx.codegen.type.ClassKind;
import io.vertx.codegen.type.ParameterizedTypeInfo;
import io.vertx.codegen.type.TypeInfo;
import io.vertx.codegen.type.TypeVariableInfo;

import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeParameterElement;

/**
* @author Евгений Уткин ([email protected])
*/
public class LegalClassTypeParamChecker implements Checker {

public static Checker getInstance() {
return new LegalClassTypeParamChecker();
}

@Override
public boolean check(ExecutableElement elt, TypeInfo type, boolean allowAnyJavaType) {
if (type.getKind() == ClassKind.CLASS_TYPE && type.isParameterized()) {
ParameterizedTypeInfo parameterized = (ParameterizedTypeInfo) type;
TypeInfo arg = parameterized.getArg(0);
if (arg.isVariable()) {
TypeVariableInfo variable = (TypeVariableInfo) arg;
for (TypeParameterElement typeParamElt : elt.getTypeParameters()) {
if (typeParamElt.getSimpleName().toString().equals(variable.getName())) {
return true;
}
}
}
}
return false;
}
}
Loading