aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉamonn McManus <emcmanus@google.com>2021-07-09 10:18:55 -0700
committerGoogle Java Core Libraries <java-libraries-firehose+copybara@google.com>2021-07-09 10:19:26 -0700
commitf09743cc4496c356671f8fff255ac7afdfaf7ad4 (patch)
tree0b3aa275f187c49aa86daf195d71506fbdf4e5df
parent895a4d514fe0aa39a7d48973b6c95e2b3fde7542 (diff)
downloadauto-f09743cc4496c356671f8fff255ac7afdfaf7ad4.tar.gz
Annotate `com.google.auto.factory` for null hygiene.
RELNOTES=n/a PiperOrigin-RevId: 383872394
-rw-r--r--factory/src/main/java/com/google/auto/factory/package-info.java17
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java6
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java16
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java3
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java7
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java3
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java16
-rw-r--r--factory/src/main/java/com/google/auto/factory/processor/package-info.java1
8 files changed, 51 insertions, 18 deletions
diff --git a/factory/src/main/java/com/google/auto/factory/package-info.java b/factory/src/main/java/com/google/auto/factory/package-info.java
new file mode 100644
index 00000000..ea1ddd88
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/package-info.java
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * 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 com.google.auto.factory;
+
diff --git a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java
index 0769b4f0..889d8e41 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java
@@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.getOnlyElement;
+import static java.util.Objects.requireNonNull;
import static javax.lang.model.element.ElementKind.PACKAGE;
import static javax.lang.model.util.ElementFilter.typesIn;
import static javax.tools.Diagnostic.Kind.ERROR;
@@ -111,8 +112,9 @@ abstract class AutoFactoryDeclaration {
Mirrors.simplifyAnnotationValueMap(elements.getElementValuesWithDefaults(mirror));
checkState(values.size() == 4);
- // className value is a string, so we can just call toString
- AnnotationValue classNameValue = values.get("className");
+ // className value is a string, so we can just call toString. We know values.get("className")
+ // is non-null because @AutoFactory has an annotation element of that name.
+ AnnotationValue classNameValue = requireNonNull(values.get("className"));
String className = classNameValue.getValue().toString();
if (!className.isEmpty() && !isValidIdentifier(className)) {
messager.printMessage(
diff --git a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java
index bfe795a2..82349f21 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java
@@ -29,6 +29,7 @@ import com.google.common.collect.Iterables;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -132,12 +133,17 @@ public final class AutoFactoryProcessor extends AbstractProcessor {
.asMap()
.forEach(
(factoryName, methodDescriptors) -> {
+ if (methodDescriptors.isEmpty()) {
+ // This shouldn't happen, but check anyway to avoid an exception for
+ // methodDescriptors.iterator().next() below.
+ return;
+ }
// The sets of classes that are mentioned in the `extending` and `implementing`
// elements, respectively, of the @AutoFactory annotations for this factory.
ImmutableSet.Builder<TypeMirror> extending = newTypeSetBuilder();
ImmutableSortedSet.Builder<TypeMirror> implementing = newTypeSetBuilder();
boolean publicType = false;
- Boolean allowSubclasses = null;
+ Set<Boolean> allowSubclassesSet = new HashSet<>();
boolean skipCreation = false;
for (FactoryMethodDescriptor methodDescriptor : methodDescriptors) {
extending.add(methodDescriptor.declaration().extendingType().asType());
@@ -146,10 +152,8 @@ public final class AutoFactoryProcessor extends AbstractProcessor {
implementing.add(implementingType.asType());
}
publicType |= methodDescriptor.publicMethod();
- if (allowSubclasses == null) {
- allowSubclasses = methodDescriptor.declaration().allowSubclasses();
- } else if (!allowSubclasses.equals(
- methodDescriptor.declaration().allowSubclasses())) {
+ allowSubclassesSet.add(methodDescriptor.declaration().allowSubclasses());
+ if (allowSubclassesSet.size() > 1) {
skipCreation = true;
messager.printMessage(
Kind.ERROR,
@@ -159,6 +163,8 @@ public final class AutoFactoryProcessor extends AbstractProcessor {
methodDescriptor.declaration().valuesMap().get("allowSubclasses"));
}
}
+ // The set can't be empty because we eliminated methodDescriptors.isEmpty() above.
+ boolean allowSubclasses = allowSubclassesSet.iterator().next();
if (!skipCreation) {
try {
factoryWriter.writeFactory(
diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java
index 1a180caf..019295f6 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java
@@ -62,7 +62,8 @@ abstract class FactoryDescriptor {
abstract ImmutableMap<Key, ProviderField> providers();
final AutoFactoryDeclaration declaration() {
- return Iterables.getFirst(methodDescriptors(), null).declaration();
+ // There is always at least one method descriptor.
+ return methodDescriptors().iterator().next().declaration();
}
private static class UniqueNameSet {
diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java
index dea42edc..70a21ea2 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java
@@ -18,6 +18,7 @@ package com.google.auto.factory.processor;
import static com.google.auto.common.MoreElements.isAnnotationPresent;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.partitioningBy;
import static javax.lang.model.element.Modifier.ABSTRACT;
import static javax.lang.model.element.Modifier.PUBLIC;
@@ -128,10 +129,12 @@ final class FactoryDescriptorGenerator {
Map<Boolean, List<VariableElement>> parameterMap =
constructor.getParameters().stream()
.collect(partitioningBy(parameter -> isAnnotationPresent(parameter, Provided.class)));
+ // The map returned by partitioningBy always has entries for both key values but our
+ // null-checker isn't yet smart enough to know that.
ImmutableSet<Parameter> providedParameters =
- Parameter.forParameterList(parameterMap.get(true), types);
+ Parameter.forParameterList(requireNonNull(parameterMap.get(true)), types);
ImmutableSet<Parameter> passedParameters =
- Parameter.forParameterList(parameterMap.get(false), types);
+ Parameter.forParameterList(requireNonNull(parameterMap.get(false)), types);
return FactoryMethodDescriptor.builder(declaration)
.name("create")
.returnType(classElement.asType())
diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java
index 512f85ac..b7f9c3e4 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java
@@ -19,6 +19,7 @@ import static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotatio
import static com.squareup.javapoet.MethodSpec.constructorBuilder;
import static com.squareup.javapoet.MethodSpec.methodBuilder;
import static com.squareup.javapoet.TypeSpec.classBuilder;
+import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import static javax.lang.model.element.Modifier.FINAL;
@@ -174,7 +175,7 @@ final class FactoryWriter {
checkNotNull = false;
}
} else {
- ProviderField provider = descriptor.providers().get(parameter.key());
+ ProviderField provider = requireNonNull(descriptor.providers().get(parameter.key()));
argument = CodeBlock.of(provider.name());
if (parameter.isProvider()) {
// Providers are checked for nullness in the Factory's constructor.
diff --git a/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java b/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java
index 57b38615..bd88f837 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java
@@ -26,6 +26,7 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementKindVisitor6;
+import org.checkerframework.checker.nullness.qual.Nullable;
final class ProvidedChecker {
private final Messager messager;
@@ -38,28 +39,29 @@ final class ProvidedChecker {
checkArgument(
isAnnotationPresent(element, Provided.class), "%s not annoated with @Provided", element);
element.accept(
- new ElementKindVisitor6<Void, Void>() {
+ new ElementKindVisitor6<@Nullable Void, @Nullable Void>() {
@Override
- protected Void defaultAction(Element e, Void p) {
+ protected @Nullable Void defaultAction(Element e, @Nullable Void p) {
throw new AssertionError("Provided can only be applied to parameters");
}
@Override
- public Void visitVariableAsParameter(final VariableElement providedParameter, Void p) {
+ public @Nullable Void visitVariableAsParameter(
+ VariableElement providedParameter, @Nullable Void p) {
providedParameter
.getEnclosingElement()
.accept(
- new ElementKindVisitor6<Void, Void>() {
+ new ElementKindVisitor6<@Nullable Void, @Nullable Void>() {
@Override
- protected Void defaultAction(Element e, Void p) {
+ protected @Nullable Void defaultAction(Element e, @Nullable Void p) {
raiseError(
providedParameter, "@%s may only be applied to constructor parameters");
return null;
}
@Override
- public Void visitExecutableAsConstructor(
- ExecutableElement constructor, Void p) {
+ public @Nullable Void visitExecutableAsConstructor(
+ ExecutableElement constructor, @Nullable Void p) {
if (!(annotatedWithAutoFactory(constructor)
|| annotatedWithAutoFactory(constructor.getEnclosingElement()))) {
raiseError(
diff --git a/factory/src/main/java/com/google/auto/factory/processor/package-info.java b/factory/src/main/java/com/google/auto/factory/processor/package-info.java
index 4d5b0c01..4a7c4b10 100644
--- a/factory/src/main/java/com/google/auto/factory/processor/package-info.java
+++ b/factory/src/main/java/com/google/auto/factory/processor/package-info.java
@@ -16,3 +16,4 @@
* {@link com.google.auto.factory.AutoFactory} API.
*/
package com.google.auto.factory.processor;
+