From 576b616638a9ae799476e80994f232bb110f51df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 12:11:11 +0100 Subject: [PATCH 01/12] Swap annotation and visibility to match other code --- .../src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java b/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java index 188a0dab..b895e1cb 100644 --- a/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java +++ b/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java @@ -16,7 +16,7 @@ final class UnlinkedJustInTimeBinding extends UnlinkedBinding { private final Class cls; private final Constructor constructor; // Type arguments might be used as types for this binding's parameterized constructor parameters. - @Nullable private Type[] concreteTypeArguments; + private @Nullable Type[] concreteTypeArguments; UnlinkedJustInTimeBinding( Class cls, Constructor constructor, @Nullable Type[] concreteTypeArguments) { From 68e4b95bf2feac79368fd8bb5493eb31aa1e8ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 00:31:34 +0100 Subject: [PATCH 02/12] Fix lint warnings in integration test --- integration-tests/android/src/main/AndroidManifest.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/integration-tests/android/src/main/AndroidManifest.xml b/integration-tests/android/src/main/AndroidManifest.xml index ad8ab484..5a595e1f 100644 --- a/integration-tests/android/src/main/AndroidManifest.xml +++ b/integration-tests/android/src/main/AndroidManifest.xml @@ -1,11 +1,15 @@ From 472480b037e07d3c31f552d96d9ff5dee2c25ef0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 00:32:04 +0100 Subject: [PATCH 03/12] Fix Android Java annotation processor warning in integration test Fixes :integration-tests:android:javaPreCompileCodegenDebugUnitTest "Annotation processors must be explicitly declared now. The following dependencies on the compile classpath are found to contain annotation processor. Please add them to the testAnnotationProcessor configuration. See https://developer.android.com/r/tools/annotation-processor-error-message.html for more details." --- integration-tests/android/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/android/build.gradle b/integration-tests/android/build.gradle index 9aa37e0e..d37ce122 100644 --- a/integration-tests/android/build.gradle +++ b/integration-tests/android/build.gradle @@ -11,6 +11,7 @@ android { versionCode 1 versionName '1' + javaCompileOptions.annotationProcessorOptions.includeCompileClasspath = false } compileOptions { From 6da8209988148e05a49499c8e11ef871b9ab1ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 00:45:35 +0100 Subject: [PATCH 04/12] Specify Java compiler encoding explicitly to prevent using system default. Fixes :integration-tests:upstream:compileTestJava "Cycles.java:35: error: unmappable character for encoding Cp1252" --- build.gradle | 2 ++ integration-tests/upstream/build.gradle | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 5f3fc4ed..a5bb064c 100644 --- a/build.gradle +++ b/build.gradle @@ -101,6 +101,8 @@ subprojects { } tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' + options.errorprone { disableWarningsInGeneratedCode = true excludedPaths = ".*/build/generated/.*" diff --git a/integration-tests/upstream/build.gradle b/integration-tests/upstream/build.gradle index 38f182a4..1d96a7d0 100644 --- a/integration-tests/upstream/build.gradle +++ b/integration-tests/upstream/build.gradle @@ -106,3 +106,7 @@ def ensureDaggerSubmodule = tasks.create('ensureDaggerSubmodule') { } } compileTestJava.dependsOn(ensureDaggerSubmodule) + +tasks.withType(JavaCompile).configureEach { + options.encoding = 'UTF-8' +} From 69d8b9eb61a597e958fcfcdad1a93ae2b08abfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 00:31:18 +0100 Subject: [PATCH 05/12] Fix rawtypes warning in reflect-lint --- .../main/java/dagger/reflect/lint/WrongRetentionDetector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reflect-lint/src/main/java/dagger/reflect/lint/WrongRetentionDetector.java b/reflect-lint/src/main/java/dagger/reflect/lint/WrongRetentionDetector.java index 61262121..d92acdf7 100644 --- a/reflect-lint/src/main/java/dagger/reflect/lint/WrongRetentionDetector.java +++ b/reflect-lint/src/main/java/dagger/reflect/lint/WrongRetentionDetector.java @@ -134,7 +134,7 @@ private static String getQualifiedNameForValueKotlin( @NotNull JavaContext context, @Nullable UExpression annotationValue) { final Object evaluatedAnnotationValue = ConstantEvaluator.evaluate(context, annotationValue); if (evaluatedAnnotationValue instanceof kotlin.Pair) { - final kotlin.Pair value = (kotlin.Pair) evaluatedAnnotationValue; + final kotlin.Pair value = (kotlin.Pair) evaluatedAnnotationValue; final String qualifiedName = (value.getFirst() + "." + value.getSecond()); return qualifiedName.replace("/", "."); } From b7952541b759afcab0d4787cbc08c31cd7ecaeea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 11:17:13 +0100 Subject: [PATCH 06/12] Fix rawtypes warnings in UnlinkedJustInTimeBinding --- .../main/java/dagger/reflect/UnlinkedJustInTimeBinding.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java b/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java index b895e1cb..9601e043 100644 --- a/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java +++ b/reflect/src/main/java/dagger/reflect/UnlinkedJustInTimeBinding.java @@ -45,7 +45,7 @@ public LinkedBinding link(Linker linker, Scope scope) { private Type getTypeKeyForParameter(Type parameterType) { if (isTypeVariable(parameterType)) { - return matchTypeToConcreteType((TypeVariable) parameterType); + return matchTypeToConcreteType((TypeVariable) parameterType); } else if (hasParameterizedTypeVariable(parameterType)) { return findKeyForParameterizedType((ParameterizedType) parameterType); } @@ -87,7 +87,7 @@ private Type[] matchingParameterizedType(Type[] typeArguments) { Type[] matchedTypeArguments = new Type[typeArguments.length]; for (int i = 0; i < typeArguments.length; i++) { if (isTypeVariable(typeArguments[i])) { - matchedTypeArguments[i] = matchTypeToConcreteType((TypeVariable) typeArguments[i]); + matchedTypeArguments[i] = matchTypeToConcreteType((TypeVariable) typeArguments[i]); } else { matchedTypeArguments[i] = typeArguments[i]; } @@ -103,7 +103,7 @@ private Type[] matchingParameterizedType(Type[] typeArguments) { * @param typeToLookup The parameterized type placeholder to lookup. * @return The matching concrete type for the placeholder. */ - private Type matchTypeToConcreteType(TypeVariable typeToLookup) { + private Type matchTypeToConcreteType(TypeVariable typeToLookup) { if (concreteTypeArguments == null) { throw new IllegalStateException( "No concrete type arguments for " + cls + " but needed for " + typeToLookup); From 6327f671eecf9eeb19116a3fe581abe25f347826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 11:38:25 +0100 Subject: [PATCH 07/12] Fix unchecked warnings in UnlinkedSetBinding by suppressing and explaining --- .../java/dagger/reflect/UnlinkedSetBinding.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/reflect/src/main/java/dagger/reflect/UnlinkedSetBinding.java b/reflect/src/main/java/dagger/reflect/UnlinkedSetBinding.java index d94b9f28..8f419d90 100644 --- a/reflect/src/main/java/dagger/reflect/UnlinkedSetBinding.java +++ b/reflect/src/main/java/dagger/reflect/UnlinkedSetBinding.java @@ -18,13 +18,22 @@ final class UnlinkedSetBinding extends UnlinkedBinding { public LinkedBinding link(Linker linker, Scope scope) { List> linkedElementBindings = new ArrayList<>(elementBindings.size()); for (Binding elementBinding : elementBindings) { - linkedElementBindings.add((LinkedBinding) elementBinding.link(linker, scope)); + @SuppressWarnings("unchecked") + LinkedBinding binding = (LinkedBinding) elementBinding.link(linker, scope); + linkedElementBindings.add(binding); } + List>> linkedElementsBindings = new ArrayList<>(elementsBindings.size()); for (Binding elementsBinding : elementsBindings) { - linkedElementsBindings.add((LinkedBinding>) elementsBinding.link(linker, scope)); + @SuppressWarnings("unchecked") + LinkedBinding> bindings = + (LinkedBinding>) elementsBinding.link(linker, scope); + linkedElementsBindings.add(bindings); } + + // `elementBinding` and `elementBindings` came from the same key so we can use Object as T; + // hence their types will match, this is why unchecked warnings are OK above. return new LinkedSetBinding<>(linkedElementBindings, linkedElementsBindings); } From 5f9528b6eb135de5b59b4596fd2021233c00376f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 11:40:12 +0100 Subject: [PATCH 08/12] Fix unchecked warnings in UnlinkedMapOfProviderBinding by using which is what the link() returns The two objects in Map> would be K and V anyway (as seen in LinkedMapOfValueBinding). Changed covariant return type to match interface declaration and all other implementations of this interface. --- .../java/dagger/reflect/UnlinkedMapOfProviderBinding.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/reflect/src/main/java/dagger/reflect/UnlinkedMapOfProviderBinding.java b/reflect/src/main/java/dagger/reflect/UnlinkedMapOfProviderBinding.java index a22d1fe8..22d4f26a 100644 --- a/reflect/src/main/java/dagger/reflect/UnlinkedMapOfProviderBinding.java +++ b/reflect/src/main/java/dagger/reflect/UnlinkedMapOfProviderBinding.java @@ -13,11 +13,10 @@ final class UnlinkedMapOfProviderBinding extends UnlinkedBinding { } @Override - public LinkedBinding>> link(Linker linker, Scope scope) { - Map> mapOfProviders = new LinkedHashMap<>(entryBindings.size()); + public LinkedBinding link(Linker linker, Scope scope) { + Map> mapOfProviders = new LinkedHashMap<>(entryBindings.size()); for (Map.Entry entryBinding : entryBindings.entrySet()) { - LinkedBinding binding = - (LinkedBinding) entryBinding.getValue().link(linker, scope); + LinkedBinding binding = entryBinding.getValue().link(linker, scope); mapOfProviders.put(entryBinding.getKey(), binding); } return new LinkedInstanceBinding<>(mapOfProviders); From 5bb00195082741bb115fc763156ec07aadf0173d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Mon, 5 Aug 2019 22:56:23 +0100 Subject: [PATCH 09/12] Fix unchecked warnings in UnlinkedMapOfValueBinding by suppression. When Scope constructs these objects it gives it the right key. --- .../src/main/java/dagger/reflect/UnlinkedMapOfValueBinding.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reflect/src/main/java/dagger/reflect/UnlinkedMapOfValueBinding.java b/reflect/src/main/java/dagger/reflect/UnlinkedMapOfValueBinding.java index 92c6a153..def63329 100644 --- a/reflect/src/main/java/dagger/reflect/UnlinkedMapOfValueBinding.java +++ b/reflect/src/main/java/dagger/reflect/UnlinkedMapOfValueBinding.java @@ -13,6 +13,8 @@ final class UnlinkedMapOfValueBinding extends UnlinkedBinding { @Override public LinkedBinding link(Linker linker, Scope scope) { + // Assume that mapOfProviderKey is Map> and linker returns the correct Binding. + @SuppressWarnings("unchecked") LinkedBinding>> mapOfProviderBinding = (LinkedBinding>>) linker.get(mapOfProviderKey); return new LinkedMapOfValueBinding<>(mapOfProviderBinding); From 858090569e9d2de944df7cb98b097f86283d0ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 12:05:37 +0100 Subject: [PATCH 10/12] Extract generic method to isolate type-safe code --- .../ReflectiveJustInTimeLookupFactory.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java b/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java index 20e2b3af..72bc1491 100644 --- a/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java +++ b/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java @@ -28,17 +28,7 @@ final class ReflectiveJustInTimeLookupFactory implements JustInTimeLookup.Factor return null; // Array types can't be just-in-time satisfied. } - Constructor[] constructors = cls.getDeclaredConstructors(); - Constructor target = null; - for (Constructor constructor : constructors) { - if (constructor.getAnnotation(Inject.class) != null) { - if (target != null) { - throw new IllegalStateException( - cls.getCanonicalName() + " defines multiple @Inject-annotations constructors"); - } - target = (Constructor) constructor; - } - } + Constructor target = findSingleInjectConstructor(cls); if (target == null) { return null; // Types without an @Inject constructor cannot be just-in-time satisfied. } @@ -47,4 +37,21 @@ final class ReflectiveJustInTimeLookupFactory implements JustInTimeLookup.Factor Binding binding = new UnlinkedJustInTimeBinding<>(cls, target, typeArguments); return new JustInTimeLookup(scope, binding); } + + private static @Nullable Constructor findSingleInjectConstructor(Class cls) { + // Not modifying it, safe to use generics; see Class#getConstructors() for more info. + @SuppressWarnings("unchecked") + Constructor[] constructors = (Constructor[]) cls.getDeclaredConstructors(); + Constructor target = null; + for (Constructor constructor : constructors) { + if (constructor.getAnnotation(Inject.class) != null) { + if (target != null) { + throw new IllegalStateException( + cls.getCanonicalName() + " defines multiple @Inject-annotations constructors"); + } + target = constructor; + } + } + return target; + } } From 1b3687aeb63a97441269f4ff62c2ac759d2d9559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Sat, 3 Aug 2019 12:14:48 +0100 Subject: [PATCH 11/12] Extract generic method to isolate type-safe code --- .../ReflectiveJustInTimeLookupFactory.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java b/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java index 72bc1491..40bba4a0 100644 --- a/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java +++ b/reflect/src/main/java/dagger/reflect/ReflectiveJustInTimeLookupFactory.java @@ -17,18 +17,27 @@ final class ReflectiveJustInTimeLookupFactory implements JustInTimeLookup.Factor } Type type = key.type(); - Class cls; + return getJustInTimeLookup(type); + } + + private @Nullable JustInTimeLookup getJustInTimeLookup(Type type) { + Class cls; Type[] typeArguments = null; if (type instanceof ParameterizedType) { - cls = (Class) ((ParameterizedType) type).getRawType(); + // Assume that "representing the class or interface that declared this type" is a Class. + @SuppressWarnings("unchecked") + Class rawType = (Class) ((ParameterizedType) type).getRawType(); + cls = rawType; typeArguments = ((ParameterizedType) type).getActualTypeArguments(); } else if (type instanceof Class) { - cls = (Class) type; + @SuppressWarnings("unchecked") + Class directClass = (Class) type; + cls = directClass; } else { return null; // Array types can't be just-in-time satisfied. } - Constructor target = findSingleInjectConstructor(cls); + Constructor target = findSingleInjectConstructor(cls); if (target == null) { return null; // Types without an @Inject constructor cannot be just-in-time satisfied. } From 1efaa5293e48123358781e6067cebf83574c3e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B3bert=20Papp=20=28TWiStErRob=29?= Date: Fri, 8 Feb 2019 22:15:37 +0000 Subject: [PATCH 12/12] Enable javac lint --- build.gradle | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/build.gradle b/build.gradle index a5bb064c..e90dab41 100644 --- a/build.gradle +++ b/build.gradle @@ -120,6 +120,24 @@ subprojects { assertsEnabled = true } } + + options.compilerArgs += [ + // enable all warnings + '-Xlint:all', + // hide warning: No processor claimed any of these annotations: dagger.*,org.junit.Test + '-Xlint:-processing', + // hide warning: MethodParameters attribute introduced in version 52.0 class files is ignored in version 51.0 class files + '-Xlint:-classfile', + // hide warning: auxiliary class C in full/path/to/C.java should not be accessed from outside its own source file + '-Xlint:-auxiliaryclass' + ] + + if (project.findProperty("strict.compilation") == "true") { + options.compilerArgs += [ + // strict compilation, treat all warnings as errors, including errorprone + '-Werror' + ] + } } plugins.withId('java-library') {