1 /* 2 * Copyright (C) 2020 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.android.internal.proguard; 18 19 import static javax.tools.StandardLocation.CLASS_OUTPUT; 20 21 import com.google.auto.service.AutoService; 22 import java.io.IOException; 23 import java.io.Writer; 24 import java.util.Set; 25 import javax.annotation.processing.AbstractProcessor; 26 import javax.annotation.processing.Filer; 27 import javax.annotation.processing.Processor; 28 import javax.annotation.processing.RoundEnvironment; 29 import javax.annotation.processing.SupportedAnnotationTypes; 30 import javax.lang.model.SourceVersion; 31 import javax.lang.model.element.TypeElement; 32 33 /** 34 * An {@linkplain Processor annotation processor} to generate dagger-android's specific proguard 35 * needs. This is only intended to run over the dagger-android project itself, as the alternative is 36 * to create an intermediary java_library for proguard rules to be consumed by the project. 37 * 38 * <p>Basic structure looks like this: 39 * 40 * <pre><code> 41 * resources/META-INF/com.android.tools/proguard/dagger-android.pro 42 * resources/META-INF/com.android.tools/r8/dagger-android.pro 43 * resources/META-INF/proguard/dagger-android.pro 44 * </code></pre> 45 */ 46 @AutoService(Processor.class) 47 @SupportedAnnotationTypes(ProguardProcessor.GENERATE_RULES_ANNOTATION_NAME) 48 public final class ProguardProcessor extends AbstractProcessor { 49 50 static final String GENERATE_RULES_ANNOTATION_NAME = 51 "dagger.android.internal.GenerateAndroidInjectionProguardRules"; 52 53 @Override process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)54 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 55 roundEnv 56 .getElementsAnnotatedWith( 57 processingEnv.getElementUtils().getTypeElement(GENERATE_RULES_ANNOTATION_NAME)) 58 .forEach(element -> generate()); 59 60 return false; 61 } 62 generate()63 private void generate() { 64 Filer filer = processingEnv.getFiler(); 65 66 String errorProneRule = "-dontwarn com.google.errorprone.annotations.**\n"; 67 String androidInjectionKeysRule = 68 "-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {\n" 69 + " java.lang.String of(java.lang.String);\n" 70 + "}\n"; 71 72 writeFile(filer, "com.android.tools/proguard", errorProneRule); 73 writeFile(filer, "com.android.tools/r8", errorProneRule + androidInjectionKeysRule); 74 writeFile(filer, "proguard", errorProneRule); 75 } 76 writeFile(Filer filer, String intermediatePath, String contents)77 private static void writeFile(Filer filer, String intermediatePath, String contents) { 78 try (Writer writer = 79 filer 80 .createResource( 81 CLASS_OUTPUT, "", "META-INF/" + intermediatePath + "/dagger-android.pro") 82 .openWriter()) { 83 writer.write(contents); 84 } catch (IOException e) { 85 throw new IllegalStateException(e); 86 } 87 } 88 89 @Override getSupportedSourceVersion()90 public SourceVersion getSupportedSourceVersion() { 91 return SourceVersion.latestSupported(); 92 } 93 } 94