Skip to content

Commit

Permalink
Implement isSubsignature() with XProcessing API
Browse files Browse the repository at this point in the history
RELNOTES=N/A
PiperOrigin-RevId: 546857277
  • Loading branch information
kuanyingchou authored and Dagger Team committed Jul 10, 2023
1 parent 1420b68 commit 9fbef13
Show file tree
Hide file tree
Showing 2 changed files with 468 additions and 10 deletions.
62 changes: 52 additions & 10 deletions java/dagger/internal/codegen/xprocessing/XExecutableTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,73 @@

import static androidx.room.compiler.processing.compat.XConverters.getProcessingEnv;
import static androidx.room.compiler.processing.compat.XConverters.toJavac;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
import static java.util.stream.Collectors.joining;

import androidx.room.compiler.codegen.XTypeNameKt;
import androidx.room.compiler.processing.XConstructorType;
import androidx.room.compiler.processing.XExecutableElement;
import androidx.room.compiler.processing.XExecutableType;
import androidx.room.compiler.processing.XMethodElement;
import androidx.room.compiler.processing.XMethodType;
import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XType;
import com.google.common.collect.ImmutableList;
import com.squareup.javapoet.TypeName;

/** A utility class for {@link XExecutableType} helper methods. */
// TODO(bcorso): Consider moving these methods into XProcessing library.
public final class XExecutableTypes {

// TODO(b/271177444): Remove this method once XProcessing supports this feature.
public static boolean isSubsignature(XMethodElement method1, XMethodElement method2) {
return isSubsignature(
method1.getExecutableType(), method2.getExecutableType(), getProcessingEnv(method1));
// TODO(b/271177465): Remove this method once XProcessing supports this feature.
public static boolean isSubsignature(XExecutableElement method1, XExecutableElement method2) {
XProcessingEnv processingEnv = getProcessingEnv(method1);
switch (processingEnv.getBackend()) {
case JAVAC:
return isSubsignatureJavac(method1, method2, processingEnv);
case KSP:
return isSubsignatureKsp(method1, method2);
}
throw new AssertionError("Unexpected backend: " + processingEnv.getBackend());
}

// TODO(b/271177465): Remove this method once XProcessing supports this feature.
public static boolean isSubsignature(
XExecutableType type1, XExecutableType type2, XProcessingEnv processingEnv) {
return toJavac(processingEnv)
private static boolean isSubsignatureKsp(XExecutableElement method1, XExecutableElement method2) {
if (method1.getParameters().size() != method2.getParameters().size()) {
return false;
}
ImmutableList<TypeName> method1Parameters = getParameters(method1);
ImmutableList<TypeName> method1TypeParameters = getTypeParameters(method1);
ImmutableList<TypeName> method2TypeParameters = getTypeParameters(method2);
return (method1TypeParameters.equals(method2TypeParameters)
&& method1Parameters.equals(getParameters(method2)))
|| (method1TypeParameters
.isEmpty() // "The erasure of the signature of a generic method has no type
// parameters."
&& method1Parameters.equals(
method2.getExecutableType().getParameterTypes().stream()
.map(XTypes::erasedTypeName)
.collect(toImmutableList())));
}

private static ImmutableList<TypeName> getParameters(XExecutableElement method) {
return method.getExecutableType().getParameterTypes().stream()
.map(XType::asTypeName)
.map(XTypeNameKt::toJavaPoet)
.collect(toImmutableList());
}

private static ImmutableList<TypeName> getTypeParameters(XExecutableElement method) {
return method.getTypeParameters().stream()
.map(it -> it.getBounds().get(0))
.map(XType::asTypeName)
.map(XTypeNameKt::toJavaPoet)
.collect(toImmutableList());
}

private static boolean isSubsignatureJavac(
XExecutableElement method1, XExecutableElement method2, XProcessingEnv env) {
return toJavac(env)
.getTypeUtils() // ALLOW_TYPES_ELEMENTS
.isSubsignature(toJavac(type1), toJavac(type2));
.isSubsignature(toJavac(method1.getExecutableType()), toJavac(method2.getExecutableType()));
}

public static boolean isConstructorType(XExecutableType executableType) {
Expand Down

0 comments on commit 9fbef13

Please sign in to comment.