Skip to content

Commit

Permalink
Optimize InjectionSiteFactory#getInjectionSites().
Browse files Browse the repository at this point in the history
RELNOTES=N/A
PiperOrigin-RevId: 590323796
  • Loading branch information
bcorso authored and Dagger Team committed Dec 12, 2023
1 parent 45af1ed commit 5f8b76c
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ ImmutableSortedSet<InjectionSite> getInjectionSites(XType type) {
XTypeElement typeElement = currentType.get().getTypeElement();
enclosingTypeElementOrder.put(typeElement, enclosingTypeElementOrder.size());
for (XElement enclosedElement : typeElement.getEnclosedElements()) {
enclosedElementOrder.put(enclosedElement, enclosedElementOrder.size());
injectionSiteVisitor
.visit(enclosedElement, currentType.get())
.ifPresent(injectionSites::add);
.ifPresent(
injectionSite -> {
enclosedElementOrder.put(enclosedElement, enclosedElementOrder.size());
injectionSites.add(injectionSite);
});
}
}
return ImmutableSortedSet.copyOf(
Expand Down
46 changes: 40 additions & 6 deletions java/dagger/internal/codegen/xprocessing/XTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -388,12 +388,46 @@ private static class KnownTypeNames {
* {@link Optional} is returned if there is no non-{@link Object} superclass.
*/
public static Optional<XType> nonObjectSuperclass(XType type) {
return isDeclared(type)
? type.getSuperTypes().stream()
.filter(supertype -> !supertype.getTypeName().equals(TypeName.OBJECT))
.filter(supertype -> isDeclared(supertype) && supertype.getTypeElement().isClass())
.collect(toOptional())
: Optional.empty();
if (!isDeclared(type)) {
return Optional.empty();
}
// We compare elements (rather than TypeName) here because its more efficient on the heap.
XTypeElement objectElement = objectElement(getProcessingEnv(type));
XTypeElement typeElement = type.getTypeElement();
if (!typeElement.isClass() || typeElement.equals(objectElement)) {
return Optional.empty();
}
XType superClass = typeElement.getSuperClass();
if (!isDeclared(superClass)) {
return Optional.empty();
}
XTypeElement superClassElement = superClass.getTypeElement();
if (!superClassElement.isClass() || superClassElement.equals(objectElement)) {
return Optional.empty();
}
// TODO(b/310954522): XType#getSuperTypes() is less efficient (especially on the heap) as it
// requires creating XType for not just superclass but all super interfaces as well, so we go
// through a bit of effort here to avoid that call unless its absolutely necessary since
// nonObjectSuperclass is called quite a bit via InjectionSiteFactory. However, we should
// eventually optimize this on the XProcessing side instead, e.g. maybe separating
// XType#getSuperClass() into a separate method.
return superClass.getTypeArguments().isEmpty()
? Optional.of(superClass)
: type.getSuperTypes().stream()
.filter(XTypes::isDeclared)
.filter(supertype -> supertype.getTypeElement().isClass())
.filter(supertype -> !supertype.getTypeElement().equals(objectElement))
.collect(toOptional());
}

private static XTypeElement objectElement(XProcessingEnv processingEnv) {
switch (processingEnv.getBackend()) {
case JAVAC:
return processingEnv.requireTypeElement(TypeName.OBJECT);
case KSP:
return processingEnv.requireTypeElement("kotlin.Any");
}
throw new AssertionError("Unexpected backend: " + processingEnv.getBackend());
}

/**
Expand Down

0 comments on commit 5f8b76c

Please sign in to comment.