Skip to content

Commit

Permalink
Move identifiernamestring to proguard config.
Browse files Browse the repository at this point in the history
This moves the `identifiernamestring` directly to the shipped proguard
config. R8 is the default now, so this should be safe to enable by
default at this point but the flag is not yet updated in this change.

This change is important also because the current implementation was not
compatible with incremental annotation processing, and would force full
rebuilds if stringKeys() was enabled. This was because it did not report
originating elements. Since it's also a hardcoded construct and not
attached to a particular element, it would have nothing to originate
from even if we did wanted to add them.

Closes #1720

RELNOTES=Generate 'identifiernamestring' r8 rule by default.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=291056440
  • Loading branch information
ZacSweers authored and danysantiago committed Jan 28, 2020
1 parent f45213e commit 6a0ce58
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 116 deletions.
6 changes: 1 addition & 5 deletions java/dagger/android/AndroidInjectionKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@
* #value() value} of the annotation is the canonical name of the class that will be passed to
* {@link AndroidInjector#inject(Object)}.
*
* <p>All key strings will be obfuscated by ProGuard/R8/AppReduce if the named class is obfuscated.
*
* <p>
* You should only use this annotation if you are using a version of ProGuard/R8/AppReduce that
* supports the {@code -identifiernamestring} flag.
* <p>All key strings will be obfuscated by ProGuard/R8 if the named class is obfuscated.
*/
@Beta
@MapKey
Expand Down
4 changes: 3 additions & 1 deletion java/dagger/android/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ android_library(
srcs = SRCS,
javacopts = SOURCE_7_TARGET_7 + DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
manifest = "AndroidManifest.xml",
proguard_specs = ["proguard.cfg"],
plugins = [
"//java/dagger/android/internal/proguard:plugin",
],
tags = ["maven_coordinates=com.google.dagger:dagger-android:" + POM_VERSION],
deps = [
"//:dagger_with_compiler",
Expand Down
1 change: 1 addition & 0 deletions java/dagger/android/internal/AndroidInjectionKeys.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* An internal implementation detail of Dagger's generated code. This is not guaranteed to remain
* consistent from version to version.
*/
@GenerateAndroidInjectionProguardRules
public final class AndroidInjectionKeys {
/**
* Accepts the fully qualified name of a class that is injected with {@code dagger.android}.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2020 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.android.internal;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* Our proguard rules generator needs one annotation to hook into for it to run, so we use this
* internally on {@link dagger.android.internal.AndroidInjectionKeys} as a throwaway for it to run.
* It has no other purpose.
*/
@Target(TYPE)
@Retention(SOURCE)
@interface GenerateAndroidInjectionProguardRules {}
36 changes: 36 additions & 0 deletions java/dagger/android/internal/proguard/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Copyright (C) 2020 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.

# Description:
# Internal Proguard Processor

load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX", "DOCLINT_REFERENCES")

package(default_visibility = ["//:src"])

java_library(
name = "proguard-processor",
srcs = ["ProguardProcessor.java"],
javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
deps = [
"@google_bazel_common//third_party/java/auto:service",
],
)

java_plugin(
name = "plugin",
generates_api = 1,
processor_class = "dagger.android.internal.proguard.ProguardProcessor",
deps = [":proguard-processor"],
)
98 changes: 98 additions & 0 deletions java/dagger/android/internal/proguard/ProguardProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (C) 2020 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.android.internal.proguard;

import static javax.tools.StandardLocation.CLASS_OUTPUT;

import com.google.auto.service.AutoService;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;

/**
* An {@linkplain Processor annotation processor} to generate dagger-android's specific proguard
* needs. This is only intended to run over the dagger-android project itself, as the alternative is
* to create an intermediary java_library for proguard rules to be consumed by the project.
*
* <p>Basic structure looks like this:
*
* <pre><code>
* resources/META-INF/com.android.tools/proguard/dagger-android.pro
* resources/META-INF/com.android.tools/r8/dagger-android.pro
* resources/META-INF/proguard/dagger-android.pro
* </code></pre>
*/
@AutoService(Processor.class)
@SupportedAnnotationTypes(ProguardProcessor.GENERATE_RULES_ANNOTATION_NAME)
public final class ProguardProcessor extends AbstractProcessor {

static final String GENERATE_RULES_ANNOTATION_NAME =
"dagger.android.internal.GenerateAndroidInjectionProguardRules";

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
roundEnv
.getElementsAnnotatedWith(
processingEnv.getElementUtils().getTypeElement(GENERATE_RULES_ANNOTATION_NAME))
.forEach(element -> generate());

return false;
}

private void generate() {
Filer filer = processingEnv.getFiler();
StringBuilder rulesBuilder = new StringBuilder();

String proguardRules =
rulesBuilder.append("-dontwarn com.google.errorprone.annotations.**\n").toString();

String r8Rules =
rulesBuilder
.append("-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {\n")
.append(" java.lang.String of(java.lang.String);\n")
.append("}\n")
.toString();

writeFile(filer, "com.android.tools/proguard", proguardRules);
writeFile(filer, "com.android.tools/r8", r8Rules);
writeFile(filer, "proguard", proguardRules);
}

private static void writeFile(Filer filer, String intermediatePath, String contents) {
try (Writer writer =
filer
.createResource(
CLASS_OUTPUT, "", "META-INF/" + intermediatePath + "/dagger-android.pro")
.openWriter()) {
writer.write(contents);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}

@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}
28 changes: 0 additions & 28 deletions java/dagger/android/processor/AndroidProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,18 @@
package dagger.android.processor;

import static javax.tools.Diagnostic.Kind.ERROR;
import static javax.tools.StandardLocation.CLASS_OUTPUT;
import static net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.ISOLATING;

import com.google.auto.common.BasicAnnotationProcessor;
import com.google.auto.service.AutoService;
import com.google.common.base.Ascii;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.googlejavaformat.java.filer.FormattingFiler;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
Expand Down Expand Up @@ -97,29 +92,6 @@ private boolean useStringKeys() {
}
}

@Override
protected void postRound(RoundEnvironment roundEnv) {
if (roundEnv.processingOver() && useStringKeys()) {
try (Writer writer = createProguardFile()){
writer.write(
Joiner.on("\n")
.join(
"-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {",
" java.lang.String of(java.lang.String);",
"}"));
} catch (IOException e) {
e.printStackTrace();
}
}
}

private Writer createProguardFile() throws IOException {
return processingEnv
.getFiler()
.createResource(CLASS_OUTPUT, "", "META-INF/proguard/dagger.android.AndroidInjectionKeys")
.openWriter();
}

@Override
public Set<String> getSupportedOptions() {
return ImmutableSet.of(FLAG_EXPERIMENTAL_USE_STRING_KEYS);
Expand Down
1 change: 0 additions & 1 deletion java/dagger/android/proguard.cfg

This file was deleted.

56 changes: 56 additions & 0 deletions javatests/dagger/android/AndroidProguardTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2020 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.android;

import static com.google.common.truth.Truth.assertThat;

import dagger.android.internal.AndroidInjectionKeys;
import java.net.URL;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;

@RunWith(RobolectricTestRunner.class)
public class AndroidProguardTest {

@Test
public void checkLegacyProguardRules() {
URL resUrl =
AndroidInjectionKeys.class
.getClassLoader()
.getResource("META-INF/proguard/dagger-android.pro");
assertThat(resUrl).isNotNull();
}

@Test
public void checkProguardRules() {
URL resUrl =
AndroidInjectionKeys.class
.getClassLoader()
.getResource("META-INF/com.android.tools/proguard/dagger-android.pro");
assertThat(resUrl).isNotNull();
}

@Test
public void checkR8Rules() {
URL resUrl =
AndroidInjectionKeys.class
.getClassLoader()
.getResource("META-INF/com.android.tools/r8/dagger-android.pro");
assertThat(resUrl).isNotNull();
}
}
81 changes: 0 additions & 81 deletions javatests/dagger/android/processor/AndroidProcessorTest.java

This file was deleted.

0 comments on commit 6a0ce58

Please sign in to comment.