1 /* 2 * Copyright (C) 2024 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 java.nio.charset.StandardCharsets.UTF_8; 20 21 import androidx.room.compiler.processing.XElement; 22 import androidx.room.compiler.processing.XFiler; 23 import androidx.room.compiler.processing.XProcessingEnv; 24 import com.google.common.collect.ImmutableList; 25 import com.google.common.collect.ImmutableSet; 26 import com.squareup.javapoet.ClassName; 27 import dagger.android.processor.BaseProcessingStep; 28 import java.io.BufferedWriter; 29 import java.io.IOException; 30 import java.io.OutputStream; 31 import java.io.OutputStreamWriter; 32 import java.nio.file.Path; 33 34 /** 35 * A annotation processing step to generate dagger-android's specific proguard needs. This is only 36 * intended to run over the dagger-android project itself, as the alternative is to create an 37 * intermediary java_library for proguard rules to be consumed by the project. 38 * 39 * <p>Basic structure looks like this: 40 * 41 * <pre><code> 42 * resources/META-INF/com.android.tools/proguard/dagger-android.pro 43 * resources/META-INF/com.android.tools/r8/dagger-android.pro 44 * resources/META-INF/proguard/dagger-android.pro 45 * </code></pre> 46 */ 47 public final class ProguardProcessingStep extends BaseProcessingStep { 48 private final XProcessingEnv processingEnv; 49 ProguardProcessingStep(XProcessingEnv processingEnv)50 ProguardProcessingStep(XProcessingEnv processingEnv) { 51 this.processingEnv = processingEnv; 52 } 53 54 static final ClassName GENERATE_RULES_ANNOTATION_NAME = 55 ClassName.get("dagger.android.internal", "GenerateAndroidInjectionProguardRules"); 56 57 @Override annotationClassNames()58 public ImmutableSet<ClassName> annotationClassNames() { 59 return ImmutableSet.of(GENERATE_RULES_ANNOTATION_NAME); 60 } 61 62 @Override process(XElement element, ImmutableSet<ClassName> annotationNames)63 public void process(XElement element, ImmutableSet<ClassName> annotationNames) { 64 XFiler 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(XFiler filer, String intermediatePath, String contents)77 private void writeFile(XFiler filer, String intermediatePath, String contents) { 78 try (OutputStream outputStream = 79 filer.writeResource( 80 Path.of("META-INF/" + intermediatePath + "/dagger-android.pro"), 81 ImmutableList.<XElement>of(), 82 XFiler.Mode.Isolating); 83 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, UTF_8))) { 84 writer.write(contents); 85 } catch (IOException e) { 86 throw new IllegalStateException(e); 87 } 88 } 89 } 90