Skip to content

Commit

Permalink
Migrate dagger.spi.model.Scope to use Dagger wrapper types.
Browse files Browse the repository at this point in the history
I've also migrated some Class usages to ClassName.

The new model is meant to work with both Javac and KSP, so we are migrating the model to reference wrapped types, e.g.:

  Element -> DaggerElement
  TypeElement -> DaggerTypeElement
  AnnotationMirror -> DaggerAnnotation
  etc...

RELNOTES=N/A
PiperOrigin-RevId: 382564696
  • Loading branch information
bcorso authored and Dagger Team committed Jul 1, 2021
1 parent 3d93625 commit 30fa0f3
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 53 deletions.
23 changes: 14 additions & 9 deletions java/dagger/internal/codegen/base/Scopes.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,18 @@

package dagger.internal.codegen.base;

import static com.google.common.collect.Iterables.getOnlyElement;
import static dagger.internal.codegen.base.DiagnosticFormatting.stripCommonTypePrefixes;
import static dagger.internal.codegen.extension.DaggerCollectors.toOptional;
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;

import com.google.auto.common.AnnotationMirrors;
import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.ClassName;
import dagger.internal.codegen.javapoet.TypeNames;
import dagger.internal.codegen.langmodel.DaggerElements;
import dagger.producers.ProductionScope;
import dagger.spi.model.DaggerAnnotation;
import dagger.spi.model.Scope;
import java.lang.annotation.Annotation;
import java.util.Optional;
import javax.inject.Singleton;
import javax.lang.model.element.Element;
Expand All @@ -35,29 +37,30 @@ public final class Scopes {

/** Returns a representation for {@link ProductionScope @ProductionScope} scope. */
public static Scope productionScope(DaggerElements elements) {
return scope(elements, ProductionScope.class);
return scope(elements, TypeNames.PRODUCTION_SCOPE);
}

/** Returns a representation for {@link Singleton @Singleton} scope. */
public static Scope singletonScope(DaggerElements elements) {
return scope(elements, Singleton.class);
return scope(elements, TypeNames.SINGLETON);
}

/**
* Creates a {@link Scope} object from the {@link javax.inject.Scope}-annotated annotation type.
*/
private static Scope scope(
DaggerElements elements, Class<? extends Annotation> scopeAnnotationClass) {
return Scope.scope(SimpleAnnotationMirror.of(elements.getTypeElement(scopeAnnotationClass)));
private static Scope scope(DaggerElements elements, ClassName scopeAnnotationClassName) {
return Scope.scope(
DaggerAnnotation.fromJava(
SimpleAnnotationMirror.of(
elements.getTypeElement(scopeAnnotationClassName.canonicalName()))));
}

/**
* Returns at most one associated scoped annotation from the source code element, throwing an
* exception if there are more than one.
*/
public static Optional<Scope> uniqueScopeOf(Element element) {
// TODO(ronshapiro): Use MoreCollectors.toOptional() once we can use guava-jre
return Optional.ofNullable(getOnlyElement(scopesOf(element), null));
return scopesOf(element).stream().collect(toOptional());
}

/**
Expand All @@ -72,8 +75,10 @@ public static String getReadableSource(Scope scope) {

/** Returns all of the associated scopes for a source code element. */
public static ImmutableSet<Scope> scopesOf(Element element) {
// TODO(bcorso): Replace Scope class reference with class name once auto-common is updated.
return AnnotationMirrors.getAnnotatedAnnotations(element, javax.inject.Scope.class)
.stream()
.map(DaggerAnnotation::fromJava)
.map(Scope::scope)
.collect(toImmutableSet());
}
Expand Down
4 changes: 4 additions & 0 deletions java/dagger/internal/codegen/javapoet/TypeNames.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,12 @@ public final class TypeNames {
ClassName.get("dagger.producers.internal", "SetOfProducedProducer");
public static final ClassName SET_PRODUCER =
ClassName.get("dagger.producers.internal", "SetProducer");
public static final ClassName PRODUCTION_SCOPE =
ClassName.get("dagger.producers", "ProductionScope");

// Other classnames
public static final ClassName SINGLETON = ClassName.get("javax.inject", "Singleton");
public static final ClassName SCOPE = ClassName.get("javax.inject", "Scope");
public static final ClassName INJECT = ClassName.get("javax.inject", "Inject");
public static final ClassName LIST = ClassName.get("java.util", "List");
public static final ClassName SET = ClassName.get("java.util", "Set");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ private void checkScopes() {
}
verifyNotNull(error);
for (Scope scope : scopes) {
report.addError(error, element, scope.scopeAnnotation());
report.addError(error, element, scope.scopeAnnotation().java());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ private static DependencyRequest fromSpiModel(dagger.spi.model.DependencyRequest
}

private static Scope fromSpiModel(dagger.spi.model.Scope scope) {
return Scope.scope(scope.scopeAnnotation());
return Scope.scope(scope.scopeAnnotation().java());
}

private static ComponentPath fromSpiModel(dagger.spi.model.ComponentPath path) {
Expand Down
6 changes: 3 additions & 3 deletions java/dagger/internal/codegen/validation/InjectValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ && isAnnotationPresent(constructorElement, AssistedInject.class)) {
}

for (Scope scope : scopesOf(constructorElement)) {
builder.addError(scopeErrorMsg, constructorElement, scope.scopeAnnotation());
builder.addError(scopeErrorMsg, constructorElement, scope.scopeAnnotation().java());
}

for (VariableElement parameter : constructorElement.getParameters()) {
Expand Down Expand Up @@ -229,14 +229,14 @@ && isAnnotationPresent(constructorElement, AssistedInject.class)) {
builder.addError(
"A type with an @AssistedInject-annotated constructor cannot be scoped",
enclosingElement,
scope.scopeAnnotation());
scope.scopeAnnotation().java());
}
} else if (scopes.size() > 1) {
for (Scope scope : scopes) {
builder.addError(
"A single binding may not declare more than one @Scope",
enclosingElement,
scope.scopeAnnotation());
scope.scopeAnnotation().java());
}
}

Expand Down
13 changes: 12 additions & 1 deletion java/dagger/spi/model/DaggerAnnotation.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
package dagger.spi.model;

import com.google.auto.common.AnnotationMirrors;
import com.google.auto.common.MoreTypes;
import com.google.auto.value.AutoValue;
import com.google.common.base.Equivalence;
import com.google.common.base.Preconditions;
import com.google.devtools.ksp.symbol.KSAnnotation;
import com.squareup.javapoet.ClassName;
import javax.annotation.Nullable;
import javax.lang.model.element.AnnotationMirror;

Expand All @@ -43,6 +45,15 @@ public static DaggerAnnotation fromKsp(KSAnnotation ksAnnotation) {
@Nullable
abstract Equivalence.Wrapper<AnnotationMirror> annotationMirror();

public DaggerTypeElement annotationTypeElement() {
return DaggerTypeElement.fromJava(
MoreTypes.asTypeElement(annotationMirror().get().getAnnotationType()));
}

public ClassName className() {
return annotationTypeElement().className();
}

@Nullable
public AnnotationMirror java() {
return annotationMirror().get();
Expand All @@ -53,6 +64,6 @@ public AnnotationMirror java() {

@Override
public final String toString() {
return java().toString();
return (ksp() != null ? ksp() : java()).toString();
}
}
43 changes: 43 additions & 0 deletions java/dagger/spi/model/DaggerElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2021 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.spi.model;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.devtools.ksp.symbol.KSDeclaration;
import javax.annotation.Nullable;
import javax.lang.model.element.Element;

/** Wrapper type for an element. */
@AutoValue
public abstract class DaggerElement {

public static DaggerElement fromJava(Element element) {
return new AutoValue_DaggerElement(Preconditions.checkNotNull(element), null);
}

@Nullable
public abstract Element java();

@Nullable
public abstract KSDeclaration ksp();

@Override
public final String toString() {
return (ksp() != null ? ksp() : java()).toString();
}
}
43 changes: 43 additions & 0 deletions java/dagger/spi/model/DaggerExecutableElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2021 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.spi.model;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.devtools.ksp.symbol.KSFunctionDeclaration;
import javax.annotation.Nullable;
import javax.lang.model.element.ExecutableElement;

/** Wrapper type for an executable element. */
@AutoValue
public abstract class DaggerExecutableElement {

public static DaggerExecutableElement fromJava(ExecutableElement element) {
return new AutoValue_DaggerExecutableElement(Preconditions.checkNotNull(element), null);
}

@Nullable
public abstract ExecutableElement java();

@Nullable
public abstract KSFunctionDeclaration ksp();

@Override
public final String toString() {
return (ksp() != null ? ksp() : java()).toString();
}
}
2 changes: 1 addition & 1 deletion java/dagger/spi/model/DaggerType.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ public TypeMirror java() {

@Override
public final String toString() {
return java().toString();
return (ksp() != null ? ksp() : java()).toString();
}
}
54 changes: 54 additions & 0 deletions java/dagger/spi/model/DaggerTypeElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (C) 2021 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.spi.model;

import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions;
import com.google.devtools.ksp.symbol.KSClassDeclaration;
import com.squareup.javapoet.ClassName;
import javax.annotation.Nullable;
import javax.lang.model.element.TypeElement;

/** Wrapper type for a type element. */
@AutoValue
public abstract class DaggerTypeElement {

public static DaggerTypeElement fromJava(TypeElement element) {
return new AutoValue_DaggerTypeElement(Preconditions.checkNotNull(element), null);
}

@Nullable
public abstract TypeElement java();

@Nullable
public abstract KSClassDeclaration ksp();

public ClassName className() {
if (ksp() != null) {
// TODO(bcorso): Add support for KSP. Consider using xprocessing types internally since that
// already has support for KSP class names?
throw new UnsupportedOperationException("Method className() is not yet supported in KSP.");
} else {
return ClassName.get(java());
}
}

@Override
public final String toString() {
return (ksp() != null ? ksp() : java()).toString();
}
}
Loading

0 comments on commit 30fa0f3

Please sign in to comment.