Add a check in ImplementsValidator to catch shadow methods in Robolectric missing a @Implementation tag when it should be present.
PiperOrigin-RevId: 440949783
diff --git a/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java b/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java
index 9f46769..b834a2a 100644
--- a/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java
+++ b/processor/src/main/java/org/robolectric/annotation/processing/validator/ImplementsValidator.java
@@ -3,6 +3,7 @@
import static org.robolectric.annotation.processing.validator.ImplementationValidator.METHODS_ALLOWED_TO_BE_PUBLIC;
import com.google.auto.common.AnnotationValues;
+import com.google.auto.common.MoreElements;
import com.sun.source.tree.ImportTree;
import com.sun.source.util.Trees;
import java.util.ArrayList;
@@ -210,7 +211,7 @@
private void validateShadowMethods(TypeElement sdkClassElem, TypeElement shadowClassElem,
int classMinSdk, int classMaxSdk, boolean looseSignatures) {
for (Element memberElement : ElementFilter.methodsIn(shadowClassElem.getEnclosedElements())) {
- ExecutableElement methodElement = (ExecutableElement) memberElement;
+ ExecutableElement methodElement = MoreElements.asExecutable(memberElement);
// equals, hashCode, and toString are exempt, because of Robolectric's weird special behavior
if (METHODS_ALLOWED_TO_BE_PUBLIC.contains(methodElement.getSimpleName().toString())) {
@@ -218,6 +219,11 @@
}
verifySdkMethod(sdkClassElem, methodElement, classMinSdk, classMaxSdk, looseSignatures);
+ if (shadowClassElem.getQualifiedName().toString().startsWith("org.robolectric")
+ && !methodElement.getModifiers().contains(Modifier.ABSTRACT)) {
+ checkForMissingImplementationAnnotation(
+ sdkClassElem, methodElement, classMinSdk, classMaxSdk, looseSignatures);
+ }
String methodName = methodElement.getSimpleName().toString();
if (methodName.equals(CONSTRUCTOR_METHOD_NAME)
@@ -257,6 +263,40 @@
}
}
+ /**
+ * For the given {@link ExecutableElement}, check to see if it should have a {@link
+ * Implementation} tag but is missing one
+ */
+ private void checkForMissingImplementationAnnotation(
+ TypeElement sdkClassElem,
+ ExecutableElement methodElement,
+ int classMinSdk,
+ int classMaxSdk,
+ boolean looseSignatures) {
+
+ if (sdkCheckMode == SdkCheckMode.OFF) {
+ return;
+ }
+
+ Implementation implementation = methodElement.getAnnotation(Implementation.class);
+ if (implementation == null) {
+ Kind kind = sdkCheckMode == SdkCheckMode.WARN ? Kind.WARNING : Kind.ERROR;
+ Problems problems = new Problems(kind);
+
+ for (SdkStore.Sdk sdk : sdkStore.sdksMatching(implementation, classMinSdk, classMaxSdk)) {
+ String problem = sdk.verifyMethod(sdkClassElem, methodElement, looseSignatures);
+ if (problem == null) {
+ problems.add(
+ "Missing @Implementation on method " + methodElement.getSimpleName(), sdk.sdkInt);
+ }
+ }
+
+ if (problems.any()) {
+ problems.recount(messager, methodElement);
+ }
+ }
+ }
+
private void captureJavadoc(TypeElement elem) {
List<String> imports = new ArrayList<>();
try {
diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java
index 889d639..aadbf80 100644
--- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java
+++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDownloadManager.java
@@ -70,6 +70,7 @@
return result;
}
+ @Implementation
protected long addCompletedDownload(
String title,
String description,