All Downloads are FREE. Search and download functionalities are using the official Maven repository.

br.com.objectos.way.code.ProcessingEnvironmentWrapper Maven / Gradle / Ivy

There is a newer version: 0.6.0
Show newest version
/*
 * Copyright 2014 Objectos, Fábrica de Software LTDA.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package br.com.objectos.way.code;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.tools.Diagnostic.Kind;

/**
 * @author [email protected] (Marcio Endo)
 */
public class ProcessingEnvironmentWrapper {

  private final ProcessingEnvironment environment;

  protected ProcessingEnvironmentWrapper(ProcessingEnvironment environment) {
    this.environment = environment;
  }

  public static ProcessingEnvironmentWrapper wrapperOf(ProcessingEnvironment environment) {
    Class actualType = environment.getClass();
    Package actualPackage = actualType.getPackage();
    String packageName = actualPackage.getName();

    return packageName.startsWith("org.eclipse")
        ? new ProcessingEnvironmentWrapperJdt(environment)
        : new ProcessingEnvironmentWrapper(environment);
  }

  public List getAllAnnotationMirrors(Element element) {
    return environment.getElementUtils().getAllAnnotationMirrors(element);
  }

  public Map getElementValuesWithDefaults(
      AnnotationMirror annotation) {
    return environment.getElementUtils().getElementValuesWithDefaults(annotation);
  }

  public List getEnclosedElements(TypeElement element) {
    return element.getEnclosedElements();
  }

  public NameInfo getNameInfo(TypeMirror mirror) {
    List nameList = new ArrayList<>();

    Element element = asElement(mirror);
    recurseNameInfo(nameList, element);

    return NameInfo.nameOf(nameList);
  }

  public Optional getPackageInfoOf(TypeMirror type) {
    Optional res = Optional.empty();

    Element element = asElement(type);
    if (element != null) {
      PackageElement packageElement = getPackageOf(element);
      PackageInfo packageInfo = PackageInfoPackageElement.wrap(packageElement);
      res = Optional.of(packageInfo);
    }

    return res;
  }

  public PackageElement getPackageOf(Element element) {
    return environment.getElementUtils().getPackageOf(element);
  }

  public PackageElement getPackageOf(TypeMirror mirror) {
    Element element = asElement(mirror);
    return getPackageOf(element);
  }

  public String getQualifiedName(TypeMirror mirror) {
    Element element = asElement(mirror);
    Name packageName = getPackageOf(mirror).getQualifiedName();
    return packageName + "." + element.getSimpleName();
  }

  public TypeElement getTypeElement(String qualifiedName) {
    return environment.getElementUtils().getTypeElement(qualifiedName);
  }

  public TypeMirror getTypeMirror(Class maybeSuperType) {
    TypeMirrorGetter getter = TypeMirrorGetter.of(maybeSuperType);
    return getter.get(environment.getElementUtils(), environment.getTypeUtils());
  }

  public List getTypeParameterInfoListOf(TypeMirror type) {
    List list = new ArrayList<>();
    return type.accept(new TypeParameterInfoListVisitor(), list);
  }

  public TypeParameterInfoMap getTypeParameterInfoMapOf(TypeMirror type) {
    Element element = asElement(type);
    TypeElement typeElement = TypeElement.class.cast(element);
    TypeParameterInfoMap elementMap = getTypeParameterInfoMapOf(typeElement);
    List valueList = getTypeParameterInfoListOf(type);
    return new TypeParameterInfoMapMirror(valueList, elementMap.list());
  }

  public TypeParameterInfoMap getTypeParameterInfoMapOf(TypeElement element) {
    List parameters = element.getTypeParameters();
    List list = parameters.stream()
        .map(TypeParameterElemenToTypeParameterInfo.get(processingEnv()))
        .collect(Collectors.toList());
    return TypeParameterInfoMap.mapOf(list);
  }

  public boolean isSubType(TypeElement element, Class maybeSuperType) {
    TypeMirror typeMirror = element.asType();
    return isSubType(typeMirror, maybeSuperType);
  }

  public boolean isSubType(TypeMirror t1, Class maybeSuperType) {
    TypeMirror t2 = getTypeMirror(maybeSuperType);

    TypeMirror raw1 = rawTypeMirror(t1);
    TypeMirror raw2 = rawTypeMirror(t2);

    return environment.getTypeUtils().isSubtype(raw1, raw2);
  }

  public Element asElement(TypeMirror mirror) {
    return environment.getTypeUtils().asElement(mirror);
  }

  public void compilationError(String message, Element element) {
    environment.getMessager().printMessage(Kind.ERROR, message, element);
  }

  public TypeInfo toTypeInfo(TypeElement element) {
    return TypeInfoTypeElement.wrap(this, element);
  }

  void addSimpleName(List nameList, Element element) {
    Name simpleName = element.getSimpleName();
    nameList.add(simpleName.toString());
  }

  protected TypeMirror rawTypeMirror(TypeMirror type) {
    TypeMirror res = type;

    if (TypeKind.DECLARED.equals(type.getKind())) {
      DeclaredType declaredType = DeclaredType.class.cast(type);

      int genericsCount = declaredType.getTypeArguments().size();

      TypeMirror[] types = new TypeMirror[genericsCount];
      for (int i = 0; i < genericsCount; i++) {
        types[i] = environment.getTypeUtils().getWildcardType(null, null);
      }

      TypeElement typeElement = (TypeElement) asElement(declaredType);
      res = environment.getTypeUtils().getDeclaredType(typeElement, types);
    }

    return res;
  }

  private ProcessingEnvironmentWrapper processingEnv() {
    return this;
  }

  private void recurseNameInfo(List nameList, Element element) {
    Element enclosingElement = element.getEnclosingElement();
    if (enclosingElement == null) {
      addSimpleName(nameList, element);
      return;
    }

    ElementKind kind = enclosingElement.getKind();
    if (ElementKind.PACKAGE.equals(kind)) {
      addSimpleName(nameList, element);
      return;
    }

    recurseNameInfo(nameList, enclosingElement);
    addSimpleName(nameList, element);
  }

  private class TypeParameterInfoListVisitor
      extends
      SimpleTypeVisitor6, List> {

    @Override
    public List visitDeclared(DeclaredType t, List p) {
      List typeArguments = t.getTypeArguments();

      for (TypeMirror typeArgument : typeArguments) {
        TypeParameterInfo typeParameterInfo = TypeParameterInfoTypeMirror.wrap(processingEnv(), typeArgument);
        p.add(typeParameterInfo);
      }

      return p;
    }

    @Override
    protected List defaultAction(TypeMirror e, List p) {
      return p;
    }

  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy