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

dagger.internal.codegen.xprocessing.XProcessingEnvs Maven / Gradle / Ivy

There is a newer version: 2.52
Show newest version
/*
 * Copyright (C) 2022 The Dagger Authors.
 *
 * 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 dagger.internal.codegen.xprocessing;

import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv;
import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static androidx.room.compiler.processing.compat.XConverters.toXProcessing;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Iterables.getOnlyElement;

import androidx.room.compiler.processing.XMethodElement;
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XType;
import androidx.room.compiler.processing.XTypeElement;
import androidx.room.compiler.processing.compat.XConverters;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import java.util.Optional;
import javax.lang.model.SourceVersion;
import javax.lang.model.type.TypeKind;

/** A utility class for {@link XProcessingEnvs} helper methods. */
// TODO(bcorso): Consider moving these methods into XProcessing library.
public final class XProcessingEnvs {
  /** Returns {@code true} if the sources are being compiled on a javac and the version is <= 8. */
  public static boolean isPreJava8SourceVersion(XProcessingEnv processingEnv) {
    Optional javaSourceVersion = javaSourceVersion(processingEnv);
    return javaSourceVersion.isPresent()
        && javaSourceVersion.get().compareTo(SourceVersion.RELEASE_8) < 0;
  }

  /**
   * Returns an optional containing the java source version if the current sources are being
   * compiled with javac, or else returns an empty optional.
   */
  private static Optional javaSourceVersion(XProcessingEnv processingEnv) {
    switch (processingEnv.getBackend()) {
      case JAVAC:
        return Optional.of(toJavac(processingEnv).getSourceVersion());
      case KSP:
        return Optional.empty();
    }
    throw new AssertionError("Unexpected backend: " + processingEnv.getBackend());
  }

  /**
   * Returns {@code true} if {@code overrider} overrides {@code overridden} from within {@code type}
   */
  public static boolean javacOverrides(
      XMethodElement overrider,
      XMethodElement overridden,
      XTypeElement type) {
    XProcessingEnv processingEnv = getProcessingEnv(type);
    switch (processingEnv.getBackend()) {
      case JAVAC:
        // TODO(bcorso): Investigate why XMethodElement#overrides() throws exception in some cases.
        return toJavac(processingEnv)
            .getElementUtils() // ALLOW_TYPES_ELEMENTS
            .overrides(toJavac(overrider), toJavac(overridden), toJavac(type));
      case KSP:
        // For KSP, just use the standard overrides since the issues above are specific to javac.
        return overrider.overrides(overridden, type);
    }
    throw new AssertionError("Unexpected backend: " + processingEnv.getBackend());
  }

  /** Returns a new unbounded wildcard type argument, i.e. {@code }. */
  public static XType getUnboundedWildcardType(XProcessingEnv processingEnv) {
    switch (processingEnv.getBackend()) {
      case JAVAC:
        return toXProcessing(
            toJavac(processingEnv)
                .getTypeUtils() // ALLOW_TYPES_ELEMENTS
                .getWildcardType(null, null),
            processingEnv);
      case KSP:
        // In KSP, the equivalent of an unbounded wildcard type is the star projection. However,
        // there's currently no way to create a star projection type directly. Instead, we create a
        // List type, get its star projection, and then grab the type argument from that.
        return XConverters.toXProcessing(
                XConverters.toKS(processingEnv.requireType("java.util.List")).starProjection(),
                processingEnv)
            .getTypeArguments()
            .get(0);
    }
    throw new AssertionError("Unexpected backend: " + processingEnv.getBackend());
  }

  /**
   * Returns {@code type}'s single type argument.
   *
   * 

For example, if {@code type} is {@code List} this will return {@code Number}. * * @throws IllegalArgumentException if {@code type} is not a declared type or has zero or more * than one type arguments. */ public static XType unwrapType(XType type) { XType unwrapped = unwrapTypeOrDefault(type, null); checkArgument(unwrapped != null, "%s is a raw type", type); return unwrapped; } /** * Returns {@code type}'s single type argument, if one exists, or {@link Object} if not. * *

For example, if {@code type} is {@code List} this will return {@code Number}. * * @throws IllegalArgumentException if {@code type} is not a declared type or has more than one * type argument. */ public static XType unwrapTypeOrObject(XType type, XProcessingEnv processingEnv) { return unwrapTypeOrDefault(type, processingEnv.requireType(TypeName.OBJECT)); } private static XType unwrapTypeOrDefault(XType type, XType defaultType) { XTypeElement typeElement = type.getTypeElement(); checkArgument( !typeElement.getType().getTypeArguments().isEmpty(), "%s does not have a type parameter", typeElement.getQualifiedName()); return getOnlyElement(type.getTypeArguments(), defaultType); } /** Returns a primitive int {@link XType}. */ public static XType getPrimitiveIntType(XProcessingEnv processingEnv) { return toXProcessing( toJavac(processingEnv) .getTypeUtils() // ALLOW_TYPES_ELEMENTS .getPrimitiveType(TypeKind.INT), processingEnv); } /** Returns the type this method is enclosed in. */ public static XType wrapType(ClassName wrapper, XType type, XProcessingEnv processingEnv) { return processingEnv.getDeclaredType(processingEnv.requireTypeElement(wrapper), type); } private XProcessingEnvs() {} }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy