forked from google/dagger
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AndroidProcessor.java
132 lines (122 loc) · 4.99 KB
/
AndroidProcessor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Copyright (C) 2017 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.processor;
import static javax.tools.Diagnostic.Kind.ERROR;
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.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.googlejavaformat.java.filer.FormattingFiler;
import java.util.Set;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
/**
* An {@linkplain javax.annotation.processing.Processor annotation processor} to verify usage of
* {@code dagger.android} code.
*
* <p>Additionally, if {@code -Adagger.android.experimentalUseStringKeys} is passed to the
* compilation, a file will be generated to support obfuscated injected Android types used with
* {@code @AndroidInjectionKey}. The fact that this is generated is deliberate: not all versions of
* ProGuard/R8 support {@code -identifiernamestring}, so we can't include a ProGuard file in the
* dagger-android artifact Instead, we generate the file in {@code META-INF/proguard} only when
* users enable the flag. They should only be enabling it if their shrinker supports those files,
* and any version that does so will also support {@code -identifiernamestring}. This was added to
* R8 in <a href="https://r8.googlesource.com/r8/+/389123dfcc11e6dda0eec31ab62e1b7eb0da80d2">May
* 2018</a>.
*/
@IncrementalAnnotationProcessor(ISOLATING)
@AutoService(Processor.class)
public final class AndroidProcessor extends BasicAnnotationProcessor {
private static final String FLAG_EXPERIMENTAL_USE_STRING_KEYS =
"dagger.android.experimentalUseStringKeys";
private static final String FLAG_FORMAT_GENERATED_SOURCES =
"dagger.formatGeneratedSource";
@Override
protected Iterable<? extends Step> steps() {
Filer filer;
if (formatGeneratedSources()) {
filer = new FormattingFiler(processingEnv.getFiler());
} else {
filer = processingEnv.getFiler();
}
Messager messager = processingEnv.getMessager();
Elements elements = processingEnv.getElementUtils();
Types types = processingEnv.getTypeUtils();
return ImmutableList.of(
new AndroidMapKeyValidator(elements, types, messager),
new ContributesAndroidInjectorGenerator(
new AndroidInjectorDescriptor.Validator(messager),
useStringKeys(),
filer,
elements,
processingEnv.getSourceVersion()));
}
private boolean useStringKeys() {
if (!processingEnv.getOptions().containsKey(FLAG_EXPERIMENTAL_USE_STRING_KEYS)) {
return false;
}
String flagValue = processingEnv.getOptions().get(FLAG_EXPERIMENTAL_USE_STRING_KEYS);
if (flagValue == null || Ascii.equalsIgnoreCase(flagValue, "true")) {
return true;
} else if (Ascii.equalsIgnoreCase(flagValue, "false")) {
return false;
} else {
processingEnv
.getMessager()
.printMessage(
ERROR,
String.format(
"Unknown flag value: %s. %s must be set to either 'true' or 'false'.",
flagValue, FLAG_EXPERIMENTAL_USE_STRING_KEYS));
return false;
}
}
private boolean formatGeneratedSources() {
if (!processingEnv.getOptions().containsKey(FLAG_FORMAT_GENERATED_SOURCES)) {
return false;
}
String flagValue = processingEnv.getOptions().get(FLAG_FORMAT_GENERATED_SOURCES);
if (Ascii.equalsIgnoreCase(flagValue, "enabled")) {
return true;
} else if (flagValue == null || Ascii.equalsIgnoreCase(flagValue, "disabled")) {
return false;
} else {
processingEnv
.getMessager()
.printMessage(
ERROR,
String.format(
"Unknown flag value: %s. %s must be set to either 'enabled' or 'disabled'.",
flagValue, FLAG_FORMAT_GENERATED_SOURCES));
return false;
}
}
@Override
public Set<String> getSupportedOptions() {
return ImmutableSet.of(FLAG_EXPERIMENTAL_USE_STRING_KEYS);
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}