Skip to content

Commit

Permalink
Add Ksp Processor for Dagger Android ProguardProcessor.
Browse files Browse the repository at this point in the history
RELNOTES=Add Ksp Processor for Dagger Android ProguardProcessor.
PiperOrigin-RevId: 600594616
  • Loading branch information
wanyingd1996 authored and Dagger Team committed Jan 22, 2024
1 parent 1503f1f commit e71de27
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 50 deletions.
11 changes: 10 additions & 1 deletion java/dagger/android/internal/proguard/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,19 @@ package(default_visibility = ["//:src"])

java_library(
name = "proguard-processor",
srcs = ["ProguardProcessor.java"],
srcs = [
"KspProguardProcessor.java",
"ProguardProcessingStep.java",
"ProguardProcessor.java",
],
javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
deps = [
"//java/dagger/android/processor:base_processing_step",
"//java/dagger/internal/codegen/xprocessing",
"//third_party/java/auto:service",
"//third_party/java/guava/collect",
"//third_party/java/javapoet",
"@maven//:com_google_devtools_ksp_symbol_processing_api",
],
)

Expand Down
69 changes: 69 additions & 0 deletions java/dagger/android/internal/proguard/KspProguardProcessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2024 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 androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XProcessingEnvConfig;
import androidx.room.compiler.processing.XProcessingStep;
import androidx.room.compiler.processing.ksp.KspBasicAnnotationProcessor;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableList;
import com.google.devtools.ksp.processing.SymbolProcessor;
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment;
import com.google.devtools.ksp.processing.SymbolProcessorProvider;

/**
* An 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>
*/
public final class KspProguardProcessor extends KspBasicAnnotationProcessor {
private static final XProcessingEnvConfig PROCESSING_ENV_CONFIG =
new XProcessingEnvConfig.Builder().build();
private XProcessingEnv env;

private KspProguardProcessor(SymbolProcessorEnvironment symbolProcessorEnvironment) {
super(symbolProcessorEnvironment, PROCESSING_ENV_CONFIG);
}

@Override
public void initialize(XProcessingEnv env) {
this.env = env;
}

@Override
public Iterable<XProcessingStep> processingSteps() {
return ImmutableList.of(new ProguardProcessingStep(env));
}

/** Provides the {@link KspProguardProcessor}. */
@AutoService(SymbolProcessorProvider.class)
public static final class Provider implements SymbolProcessorProvider {
@Override
public SymbolProcessor create(SymbolProcessorEnvironment symbolProcessorEnvironment) {
return new KspProguardProcessor(symbolProcessorEnvironment);
}
}
}
89 changes: 89 additions & 0 deletions java/dagger/android/internal/proguard/ProguardProcessingStep.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (C) 2024 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 java.nio.charset.StandardCharsets.UTF_8;

import androidx.room.compiler.processing.XElement;
import androidx.room.compiler.processing.XFiler;
import androidx.room.compiler.processing.XProcessingEnv;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.ClassName;
import dagger.android.processor.BaseProcessingStep;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.file.Path;

/**
* A annotation processing step 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>
*/
public final class ProguardProcessingStep extends BaseProcessingStep {
private final XProcessingEnv processingEnv;

ProguardProcessingStep(XProcessingEnv processingEnv) {
this.processingEnv = processingEnv;
}

static final ClassName GENERATE_RULES_ANNOTATION_NAME =
ClassName.get("dagger.android.internal", "GenerateAndroidInjectionProguardRules");

@Override
public ImmutableSet<ClassName> annotationClassNames() {
return ImmutableSet.of(GENERATE_RULES_ANNOTATION_NAME);
}

@Override
public void process(XElement element, ImmutableSet<ClassName> annotationNames) {
XFiler filer = processingEnv.getFiler();

String errorProneRule = "-dontwarn com.google.errorprone.annotations.**\n";
String androidInjectionKeysRule =
"-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {\n"
+ " java.lang.String of(java.lang.String);\n"
+ "}\n";

writeFile(filer, "com.android.tools/proguard", errorProneRule);
writeFile(filer, "com.android.tools/r8", errorProneRule + androidInjectionKeysRule);
writeFile(filer, "proguard", errorProneRule);
}

private void writeFile(XFiler filer, String intermediatePath, String contents) {
try (OutputStream outputStream =
filer.writeResource(
Path.of("META-INF/" + intermediatePath + "/dagger-android.pro"),
ImmutableList.<XElement>of(),
XFiler.Mode.Isolating);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, UTF_8))) {
writer.write(contents);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
57 changes: 11 additions & 46 deletions java/dagger/android/internal/proguard/ProguardProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,13 @@

package dagger.android.internal.proguard;

import static javax.tools.StandardLocation.CLASS_OUTPUT;

import androidx.room.compiler.processing.XProcessingEnv;
import androidx.room.compiler.processing.XProcessingStep;
import androidx.room.compiler.processing.javac.JavacBasicAnnotationProcessor;
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 com.google.common.collect.ImmutableList;
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
Expand All @@ -44,46 +38,17 @@
* </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";
public final class ProguardProcessor extends JavacBasicAnnotationProcessor {
private XProcessingEnv env;

@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();

String errorProneRule = "-dontwarn com.google.errorprone.annotations.**\n";
String androidInjectionKeysRule =
"-identifiernamestring class dagger.android.internal.AndroidInjectionKeys {\n"
+ " java.lang.String of(java.lang.String);\n"
+ "}\n";

writeFile(filer, "com.android.tools/proguard", errorProneRule);
writeFile(filer, "com.android.tools/r8", errorProneRule + androidInjectionKeysRule);
writeFile(filer, "proguard", errorProneRule);
public void initialize(XProcessingEnv env) {
this.env = env;
}

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 Iterable<XProcessingStep> processingSteps() {
return ImmutableList.of(new ProguardProcessingStep(env));
}

@Override
Expand Down
20 changes: 18 additions & 2 deletions java/dagger/android/processor/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,29 @@ filegroup(
srcs = glob(["*.java"]),
)

java_library(
name = "base_processing_step",
srcs = ["BaseProcessingStep.java"],
deps = [
"//java/dagger/internal/codegen/extension",
"//java/dagger/internal/codegen/xprocessing",
"//third_party/java/guava/base",
"//third_party/java/guava/collect",
"//third_party/java/javapoet",
],
)

java_library(
name = "processor",
srcs = [":srcs"],
srcs = glob(
["*.java"],
exclude = ["BaseProcessingStep.java"],
),
javacopts = DOCLINT_HTML_AND_SYNTAX + DOCLINT_REFERENCES,
tags = ["maven_coordinates=com.google.dagger:dagger-android-processor:" + POM_VERSION],
deps = [
":base_processing_step",
"//java/dagger:core",
"//java/dagger/internal/codegen/extension",
"//java/dagger/internal/codegen/xprocessing",
"//java/dagger/spi",
"//third_party/java/auto:service",
Expand All @@ -58,6 +73,7 @@ gen_maven_artifact(
artifact_target = ":processor",
artifact_target_libs = [
"//java/dagger/internal/codegen/xprocessing",
"//java/dagger/android/processor:base_processing_step",
],
artifact_target_maven_deps = [
"com.google.dagger:dagger",
Expand Down
2 changes: 1 addition & 1 deletion java/dagger/android/processor/BaseProcessingStep.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
* A {@link XProcessingStep} that processes one element at a time and defers any for which {@link
* TypeNotPresentException} is thrown.
*/
abstract class BaseProcessingStep implements XProcessingStep {
public abstract class BaseProcessingStep implements XProcessingStep {
@Override
public final ImmutableSet<String> annotations() {
return annotationClassNames().stream().map(ClassName::canonicalName).collect(toImmutableSet());
Expand Down

0 comments on commit e71de27

Please sign in to comment.