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

net.autobuilder.core.Util Maven / Gradle / Ivy

package net.autobuilder.core;

import static java.lang.Character.isLowerCase;
import static java.lang.Character.isUpperCase;
import static java.lang.Character.toLowerCase;
import static java.lang.Character.toUpperCase;
import static java.util.Collections.emptySet;
import static javax.lang.model.element.Modifier.FINAL;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.WildcardTypeName;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.SimpleTypeVisitor8;

final class Util {

  private static final SimpleTypeVisitor8 SUBTYPE =
      new SimpleTypeVisitor8() {
        @Override
        public TypeName visitDeclared(DeclaredType declaredType, Void _null) {
          if (declaredType.asElement().getModifiers().contains(FINAL)) {
            return TypeName.get(declaredType);
          }
          return WildcardTypeName.subtypeOf(TypeName.get(declaredType));
        }

        @Override
        public TypeName visitTypeVariable(TypeVariable typeVariable, Void _null) {
          return WildcardTypeName.subtypeOf(TypeName.get(typeVariable));
        }
      };

  private static final SimpleTypeVisitor8 AS_DECLARED =
      new SimpleTypeVisitor8() {
        @Override
        public DeclaredType visitDeclared(DeclaredType declaredType, Void _null) {
          return declaredType;
        }
      };

  private final ProcessingEnvironment processingEnv;

  Util(ProcessingEnvironment processingEnv) {
    this.processingEnv = processingEnv;
  }

  static TypeName[] typeArgumentSubtypes(VariableElement variableElement) {
    DeclaredType declaredType = variableElement.asType().accept(AS_DECLARED, null);
    if (declaredType == null) {
      throw new AssertionError();
    }
    return declaredType.getTypeArguments()
        .stream()
        .map(Util::subtypeOf)
        .toArray(TypeName[]::new);
  }

  private static TypeName subtypeOf(TypeMirror typeMirror) {
    TypeName typeName = typeMirror.accept(SUBTYPE, null);
    return typeName != null ? typeName : TypeName.get(typeMirror);
  }

  static String upcase(String s) {
    if (s.isEmpty() || isUpperCase(s.charAt(0))) {
      return s;
    }
    return toUpperCase(s.charAt(0)) + s.substring(1);
  }

  static String downcase(String s) {
    if (s.isEmpty() || isLowerCase(s.charAt(0))) {
      return s;
    }
    return toLowerCase(s.charAt(0)) + s.substring(1);
  }

  static  Collector, Boolean> isDistinct() {
    return new Collector, Boolean>() {
      @Override
      public Supplier> supplier() {
        return ArrayList::new;
      }

      @Override
      public BiConsumer, E> accumulator() {
        return List::add;
      }

      @Override
      public BinaryOperator> combiner() {
        return (left, right) -> {
          left.addAll(right);
          return left;
        };
      }

      @Override
      public Function, Boolean> finisher() {
        return elements -> {
          Set set = new HashSet<>();
          for (E element : elements) {
            if (!set.add(element)) {
              return false;
            }
          }
          return true;
        };
      }

      @Override
      public Set characteristics() {
        return emptySet();
      }
    };
  }

  static Collector, CodeBlock> joinCodeBlocks(String delimiter) {
    return new Collector, CodeBlock>() {
      @Override
      public Supplier> supplier() {
        return ArrayList::new;
      }

      @Override
      public BiConsumer, CodeBlock> accumulator() {
        return List::add;
      }

      @Override
      public BinaryOperator> combiner() {
        return (left, right) -> {
          left.addAll(right);
          return left;
        };
      }

      @Override
      public Function, CodeBlock> finisher() {
        return blocks -> {
          CodeBlock.Builder builder = CodeBlock.builder();
          if (blocks.isEmpty()) {
            return builder.build();
          }
          builder.add(blocks.get(0));
          blocks.stream().skip(1).forEach(block ->
              builder.add(delimiter).add(block));
          return builder.build();
        };
      }

      @Override
      public Set characteristics() {
        return emptySet();
      }
    };
  }

  TypeElement typeElement(ClassName className) {
    return processingEnv.getElementUtils().getTypeElement(
        className.toString());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy