blob: 003811ac3e132777f0973533ee4248c964a37f05 [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18 "android/soong/android"
19 "android/soong/java/config"
20 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080021 "path/filepath"
Nan Zhang46130972018-06-04 11:28:01 -070022 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080023 "strings"
24
25 "github.com/google/blueprint"
26)
27
28var (
29 javadoc = pctx.AndroidStaticRule("javadoc",
30 blueprint.RuleParams{
31 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070032 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang40b41b42018-10-02 16:11:17 -070033 `${config.SoongJavacWrapper} ${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070034 `$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
Nan Zhang581fd212018-01-10 16:06:12 -080035 `-d $outDir -quiet && ` +
36 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080037 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds && ` +
38 `rm -rf "$srcJarDir"`,
39
Nan Zhang581fd212018-01-10 16:06:12 -080040 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070041 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080042 "${config.JavadocCmd}",
43 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080044 },
Nan Zhang40b41b42018-10-02 16:11:17 -070045 CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
46 Rspfile: "$out.rsp",
47 RspfileContent: "$in",
48 Restat: true,
Nan Zhang581fd212018-01-10 16:06:12 -080049 },
Nan Zhangaf322cc2018-06-19 15:15:38 -070050 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhang1598a9e2018-09-04 17:14:32 -070051 "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "docZip", "postDoclavaCmds")
Nan Zhang61819ce2018-05-04 18:49:16 -070052
53 apiCheck = pctx.AndroidStaticRule("apiCheck",
54 blueprint.RuleParams{
55 Command: `( ${config.ApiCheckCmd} -JXmx1024m -J"classpath $classpath" $opts ` +
56 `$apiFile $apiFileToCheck $removedApiFile $removedApiFileToCheck ` +
Jiyong Parkeeb8a642018-05-12 22:21:20 +090057 `&& touch $out ) || (echo -e "$msg" ; exit 38)`,
Nan Zhang61819ce2018-05-04 18:49:16 -070058 CommandDeps: []string{
59 "${config.ApiCheckCmd}",
60 },
61 },
62 "classpath", "opts", "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck", "msg")
63
64 updateApi = pctx.AndroidStaticRule("updateApi",
65 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070066 Command: `( ( cp -f $srcApiFile $destApiFile && cp -f $srcRemovedApiFile $destRemovedApiFile ) ` +
Nan Zhang61819ce2018-05-04 18:49:16 -070067 `&& touch $out ) || (echo failed to update public API ; exit 38)`,
68 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070069 "srcApiFile", "destApiFile", "srcRemovedApiFile", "destRemovedApiFile")
Nan Zhang79614d12018-04-19 18:03:39 -070070
71 metalava = pctx.AndroidStaticRule("metalava",
72 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070073 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
74 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070075 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang357466b2018-04-17 17:38:36 -070076 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -080077 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070078 `$opts && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080079 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
Jerome Gaillard0b09ad72019-10-10 19:29:11 +010080 `(if $writeSdkValues; then ${config.SoongZipCmd} -write_if_changed -d -o $metadataZip ` +
81 `-C $metadataDir -D $metadataDir; fi) && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080082 `rm -rf "$srcJarDir"`,
Nan Zhang79614d12018-04-19 18:03:39 -070083 CommandDeps: []string{
84 "${config.ZipSyncCmd}",
85 "${config.JavaCmd}",
86 "${config.MetalavaJar}",
Nan Zhang79614d12018-04-19 18:03:39 -070087 "${config.SoongZipCmd}",
88 },
89 Rspfile: "$out.rsp",
90 RspfileContent: "$in",
91 Restat: true,
92 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070093 "outDir", "srcJarDir", "stubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
Jerome Gaillard0b09ad72019-10-10 19:29:11 +010094 "classpathArgs", "sourcepathArgs", "opts", "writeSdkValues", "metadataZip", "metadataDir")
Nan Zhang2760dfc2018-08-24 17:32:54 +000095
96 metalavaApiCheck = pctx.AndroidStaticRule("metalavaApiCheck",
97 blueprint.RuleParams{
98 Command: `( rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` +
99 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
100 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -0800101 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800102 `$opts && touch $out && rm -rf "$srcJarDir") || ` +
Nan Zhang2760dfc2018-08-24 17:32:54 +0000103 `( echo -e "$msg" ; exit 38 )`,
104 CommandDeps: []string{
105 "${config.ZipSyncCmd}",
106 "${config.JavaCmd}",
107 "${config.MetalavaJar}",
108 },
109 Rspfile: "$out.rsp",
110 RspfileContent: "$in",
111 },
Nan Zhang1598a9e2018-09-04 17:14:32 -0700112 "srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg")
113
Pete Gillin581d6082018-10-22 15:55:04 +0100114 nullabilityWarningsCheck = pctx.AndroidStaticRule("nullabilityWarningsCheck",
115 blueprint.RuleParams{
116 Command: `( diff $expected $actual && touch $out ) || ( echo -e "$msg" ; exit 38 )`,
117 },
118 "expected", "actual", "msg")
119
Nan Zhang1598a9e2018-09-04 17:14:32 -0700120 dokka = pctx.AndroidStaticRule("dokka",
121 blueprint.RuleParams{
122 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
123 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
124 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
125 `${config.JavaCmd} -jar ${config.DokkaJar} $srcJarDir ` +
126 `$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
127 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800128 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
129 `rm -rf "$srcJarDir"`,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700130 CommandDeps: []string{
131 "${config.ZipSyncCmd}",
132 "${config.DokkaJar}",
133 "${config.MetalavaJar}",
134 "${config.SoongZipCmd}",
135 },
136 Restat: true,
137 },
138 "outDir", "srcJarDir", "stubsDir", "srcJars", "classpathArgs", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -0800139)
140
141func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -0800142 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700143 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800144
Nan Zhang581fd212018-01-10 16:06:12 -0800145 android.RegisterModuleType("droiddoc", DroiddocFactory)
146 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -0700147 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800148 android.RegisterModuleType("javadoc", JavadocFactory)
149 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700150
151 android.RegisterModuleType("droidstubs", DroidstubsFactory)
152 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800153}
154
Colin Crossa1ce2a02018-06-20 15:19:39 -0700155var (
156 srcsLibTag = dependencyTag{name: "sources from javalib"}
157)
158
Nan Zhang581fd212018-01-10 16:06:12 -0800159type JavadocProperties struct {
160 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
161 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -0800162 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800163
164 // list of directories rooted at the Android.bp file that will
165 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800166 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800167
168 // list of source files that should not be used to build the Java module.
169 // This is most useful in the arch/multilib variants to remove non-common files
170 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800171 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800172
Nan Zhangb2b33de2018-02-23 11:18:47 -0800173 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800174 Libs []string `android:"arch_variant"`
175
Paul Duffin2fbbfb82019-02-13 12:49:33 +0000176 // don't build against the default libraries (bootclasspath, ext, and framework for device
177 // targets)
Nan Zhang5994b622018-09-21 16:39:51 -0700178 No_standard_libs *bool
179
Paul Duffin2fbbfb82019-02-13 12:49:33 +0000180 // don't build against the framework libraries (ext, and framework for device targets)
Nan Zhange66c7272018-03-06 12:59:27 -0800181 No_framework_libs *bool
182
Nan Zhangb2b33de2018-02-23 11:18:47 -0800183 // the java library (in classpath) for documentation that provides java srcs and srcjars.
184 Srcs_lib *string
185
186 // the base dirs under srcs_lib will be scanned for java srcs.
187 Srcs_lib_whitelist_dirs []string
188
189 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
190 Srcs_lib_whitelist_pkgs []string
191
Nan Zhang581fd212018-01-10 16:06:12 -0800192 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800193 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800194
195 // if not blank, set to the version of the sdk to compile against
196 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900197
198 Aidl struct {
199 // Top level directories to pass to aidl tool
200 Include_dirs []string
201
202 // Directories rooted at the Android.bp file to pass to aidl tool
203 Local_include_dirs []string
204 }
Nan Zhang357466b2018-04-17 17:38:36 -0700205
206 // If not blank, set the java version passed to javadoc as -source
207 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700208
209 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800210 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700211
212 // user customized droiddoc args.
213 // Available variables for substitution:
214 //
215 // $(location <label>): the path to the arg_files with name <label>
216 Args *string
217
218 // names of the output files used in args that will be generated
219 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800220}
221
Nan Zhang61819ce2018-05-04 18:49:16 -0700222type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900223 // path to the API txt file that the new API extracted from source code is checked
224 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800225 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700226
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900227 // path to the API txt file that the new @removed API extractd from source code is
228 // checked against. The path can be local to the module or from other module (via
229 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800230 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700231
Adrian Roos4937c4a2019-08-12 17:54:09 +0200232 // If not blank, path to the baseline txt file for approved API check violations.
233 Baseline_file *string `android:"path"`
234
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900235 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700236 Args *string
237}
238
Nan Zhang581fd212018-01-10 16:06:12 -0800239type DroiddocProperties struct {
240 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800241 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800242
Nan Zhanga40da042018-08-01 12:48:00 -0700243 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800244 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800245
246 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800247 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800248
249 // proofread file contains all of the text content of the javadocs concatenated into one file,
250 // suitable for spell-checking and other goodness.
Colin Cross27b922f2019-03-04 22:35:41 -0800251 Proofread_file *string `android:"path"`
Nan Zhang581fd212018-01-10 16:06:12 -0800252
253 // a todo file lists the program elements that are missing documentation.
254 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800255 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800256
257 // directory under current module source that provide additional resources (images).
258 Resourcesdir *string
259
260 // resources output directory under out/soong/.intermediates.
261 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800262
Nan Zhange2ba5d42018-07-11 15:16:55 -0700263 // if set to true, collect the values used by the Dev tools and
264 // write them in files packaged with the SDK. Defaults to false.
265 Write_sdk_values *bool
266
267 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800268 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700269
270 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800271 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700272
Nan Zhang581fd212018-01-10 16:06:12 -0800273 // a list of files under current module source dir which contains known tags in Java sources.
274 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800275 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700276
277 // the tag name used to distinguish if the API files belong to public/system/test.
278 Api_tag_name *string
279
280 // the generated public API filename by Doclava.
281 Api_filename *string
282
David Brazdilfbe4cc32018-05-31 13:56:46 +0100283 // the generated public Dex API filename by Doclava.
284 Dex_api_filename *string
285
Nan Zhang28c68b92018-03-13 16:17:01 -0700286 // the generated private API filename by Doclava.
287 Private_api_filename *string
288
289 // the generated private Dex API filename by Doclava.
290 Private_dex_api_filename *string
291
292 // the generated removed API filename by Doclava.
293 Removed_api_filename *string
294
David Brazdilaac0c3c2018-04-24 16:23:29 +0100295 // the generated removed Dex API filename by Doclava.
296 Removed_dex_api_filename *string
297
Mathew Inwood76c3de12018-06-22 15:28:11 +0100298 // mapping of dex signatures to source file and line number. This is a temporary property and
299 // will be deleted; you probably shouldn't be using it.
300 Dex_mapping_filename *string
301
Nan Zhang28c68b92018-03-13 16:17:01 -0700302 // the generated exact API filename by Doclava.
303 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700304
Nan Zhang66dc2362018-08-14 20:41:04 -0700305 // the generated proguard filename by Doclava.
306 Proguard_filename *string
307
Nan Zhang853f4202018-04-12 16:55:56 -0700308 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
309 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700310
311 Check_api struct {
312 Last_released ApiToCheck
313
314 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900315
316 // do not perform API check against Last_released, in the case that both two specified API
317 // files by Last_released are modules which don't exist.
318 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700319 }
Nan Zhang79614d12018-04-19 18:03:39 -0700320
Nan Zhang1598a9e2018-09-04 17:14:32 -0700321 // if set to true, generate docs through Dokka instead of Doclava.
322 Dokka_enabled *bool
323}
324
325type DroidstubsProperties struct {
326 // the tag name used to distinguish if the API files belong to public/system/test.
327 Api_tag_name *string
328
Nan Zhang199645c2018-09-19 12:40:06 -0700329 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700330 Api_filename *string
331
Nan Zhang199645c2018-09-19 12:40:06 -0700332 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700333 Dex_api_filename *string
334
Nan Zhang199645c2018-09-19 12:40:06 -0700335 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700336 Private_api_filename *string
337
Nan Zhang199645c2018-09-19 12:40:06 -0700338 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700339 Private_dex_api_filename *string
340
Nan Zhang199645c2018-09-19 12:40:06 -0700341 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700342 Removed_api_filename *string
343
Nan Zhang199645c2018-09-19 12:40:06 -0700344 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700345 Removed_dex_api_filename *string
346
Nan Zhang9c69a122018-08-22 10:22:08 -0700347 // mapping of dex signatures to source file and line number. This is a temporary property and
348 // will be deleted; you probably shouldn't be using it.
349 Dex_mapping_filename *string
350
Nan Zhang199645c2018-09-19 12:40:06 -0700351 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700352 Exact_api_filename *string
353
Nan Zhang199645c2018-09-19 12:40:06 -0700354 // the generated proguard filename by Metalava.
355 Proguard_filename *string
356
Nan Zhang1598a9e2018-09-04 17:14:32 -0700357 Check_api struct {
358 Last_released ApiToCheck
359
360 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900361
362 // do not perform API check against Last_released, in the case that both two specified API
363 // files by Last_released are modules which don't exist.
364 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700365 }
Nan Zhang79614d12018-04-19 18:03:39 -0700366
367 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800368 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700369
370 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700371 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700372
Pete Gillin77167902018-09-19 18:16:26 +0100373 // a list of top-level directories containing files to merge qualifier annotations (i.e. those intended to be included in the stubs written) from.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700374 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700375
Pete Gillin77167902018-09-19 18:16:26 +0100376 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
377 Merge_inclusion_annotations_dirs []string
378
Pete Gillinc382a562018-11-14 18:45:46 +0000379 // a file containing a list of classes to do nullability validation for.
380 Validate_nullability_from_list *string
381
Pete Gillin581d6082018-10-22 15:55:04 +0100382 // a file containing expected warnings produced by validation of nullability annotations.
383 Check_nullability_warnings *string
384
Nan Zhang1598a9e2018-09-04 17:14:32 -0700385 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
386 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700387
388 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
389 Api_levels_annotations_enabled *bool
390
391 // the dirs which Metalava extracts API levels annotations from.
392 Api_levels_annotations_dirs []string
393
394 // if set to true, collect the values used by the Dev tools and
395 // write them in files packaged with the SDK. Defaults to false.
396 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700397
398 // If set to true, .xml based public API file will be also generated, and
399 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
400 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800401}
402
Nan Zhanga40da042018-08-01 12:48:00 -0700403//
404// Common flags passed down to build rule
405//
406type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700407 bootClasspathArgs string
408 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700409 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700410 dokkaClasspathArgs string
411 aidlFlags string
Colin Cross9bdfaf02019-04-18 10:56:44 -0700412 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700413
Nan Zhanga40da042018-08-01 12:48:00 -0700414 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700415 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700416 postDoclavaCmds string
417
Nan Zhang9c69a122018-08-22 10:22:08 -0700418 metalavaStubsFlags string
419 metalavaAnnotationsFlags string
Nan Zhangdee152b2018-12-26 16:06:37 -0800420 metalavaMergeAnnoDirFlags string
Neil Fullerb2f14ec2018-10-21 22:13:19 +0100421 metalavaInclusionAnnotationsFlags string
Nan Zhang9c69a122018-08-22 10:22:08 -0700422 metalavaApiLevelsAnnotationsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700423
Nan Zhang71bbe632018-09-17 14:32:21 -0700424 metalavaApiToXmlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700425}
426
427func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
428 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
429 android.InitDefaultableModule(module)
430}
431
Luca Stefanicf7b2932019-09-01 21:49:45 +0200432func apiCheckEnabled(ctx android.ModuleContext, apiToCheck ApiToCheck, apiVersionTag string) bool {
433 if ctx.Config().IsEnvTrue("WITHOUT_CHECK_API") {
434 return false
435 } else if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700436 return true
437 } else if String(apiToCheck.Api_file) != "" {
438 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
439 } else if String(apiToCheck.Removed_api_file) != "" {
440 panic("for " + apiVersionTag + " api_file has to be non-empty!")
441 }
442
443 return false
444}
445
Inseob Kim38449af2019-02-28 14:24:05 +0900446func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
447 api_file := String(apiToCheck.Api_file)
448 removed_api_file := String(apiToCheck.Removed_api_file)
449
450 api_module := android.SrcIsModule(api_file)
451 removed_api_module := android.SrcIsModule(removed_api_file)
452
453 if api_module == "" || removed_api_module == "" {
454 return
455 }
456
457 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
458 return
459 }
460
461 apiToCheck.Api_file = nil
462 apiToCheck.Removed_api_file = nil
463}
464
Nan Zhang1598a9e2018-09-04 17:14:32 -0700465type ApiFilePath interface {
466 ApiFilePath() android.Path
467}
468
469func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
470 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
471 ctx.Build(pctx, android.BuildParams{
472 Rule: updateApi,
473 Description: "Update API",
474 Output: output,
475 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
476 destApiFile, destRemovedApiFile),
477 Args: map[string]string{
478 "destApiFile": destApiFile.String(),
479 "srcApiFile": srcApiFile.String(),
480 "destRemovedApiFile": destRemovedApiFile.String(),
481 "srcRemovedApiFile": srcRemovedApiFile.String(),
482 },
483 })
484}
485
Nan Zhanga40da042018-08-01 12:48:00 -0700486//
487// Javadoc
488//
Nan Zhang581fd212018-01-10 16:06:12 -0800489type Javadoc struct {
490 android.ModuleBase
491 android.DefaultableModuleBase
492
493 properties JavadocProperties
494
495 srcJars android.Paths
496 srcFiles android.Paths
497 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700498 argFiles android.Paths
499
500 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800501
Nan Zhangccff0f72018-03-08 17:26:16 -0800502 docZip android.WritablePath
503 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800504}
505
Nan Zhangb2b33de2018-02-23 11:18:47 -0800506func (j *Javadoc) Srcs() android.Paths {
507 return android.Paths{j.stubsSrcJar}
508}
509
Nan Zhang581fd212018-01-10 16:06:12 -0800510func JavadocFactory() android.Module {
511 module := &Javadoc{}
512
513 module.AddProperties(&module.properties)
514
515 InitDroiddocModule(module, android.HostAndDeviceSupported)
516 return module
517}
518
519func JavadocHostFactory() android.Module {
520 module := &Javadoc{}
521
522 module.AddProperties(&module.properties)
523
524 InitDroiddocModule(module, android.HostSupported)
525 return module
526}
527
Nan Zhanga40da042018-08-01 12:48:00 -0700528var _ android.SourceFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800529
Colin Cross83bb3162018-06-25 15:48:06 -0700530func (j *Javadoc) sdkVersion() string {
531 return String(j.properties.Sdk_version)
532}
533
534func (j *Javadoc) minSdkVersion() string {
535 return j.sdkVersion()
536}
537
Dan Willemsen419290a2018-10-31 15:28:47 -0700538func (j *Javadoc) targetSdkVersion() string {
539 return j.sdkVersion()
540}
541
Nan Zhang581fd212018-01-10 16:06:12 -0800542func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
543 if ctx.Device() {
Nan Zhang5994b622018-09-21 16:39:51 -0700544 if !Bool(j.properties.No_standard_libs) {
545 sdkDep := decodeSdkDep(ctx, sdkContext(j))
546 if sdkDep.useDefaultLibs {
547 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
548 if ctx.Config().TargetOpenJDK9() {
549 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
550 }
551 if !Bool(j.properties.No_framework_libs) {
552 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
553 }
554 } else if sdkDep.useModule {
555 if ctx.Config().TargetOpenJDK9() {
556 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
557 }
558 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700559 }
Nan Zhang581fd212018-01-10 16:06:12 -0800560 }
561 }
562
Colin Cross42d48b72018-08-29 14:10:52 -0700563 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700564 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700565 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700566 }
Nan Zhang581fd212018-01-10 16:06:12 -0800567}
568
Nan Zhangb2b33de2018-02-23 11:18:47 -0800569func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
570 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
571 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900572 // convert foo.bar.baz to foo/bar/baz
573 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
574 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800575 if _, found := whitelistPathPrefixes[prefix]; !found {
576 whitelistPathPrefixes[prefix] = true
577 }
578 }
579 }
580}
581
Nan Zhanga40da042018-08-01 12:48:00 -0700582func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
583 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900584
Colin Cross9bdfaf02019-04-18 10:56:44 -0700585 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900586
587 return flags
588}
589
590func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross9bdfaf02019-04-18 10:56:44 -0700591 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900592
593 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
594 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
595
596 var flags []string
Colin Cross9bdfaf02019-04-18 10:56:44 -0700597 var deps android.Paths
598
Jiyong Park1e440682018-05-23 18:42:04 +0900599 if aidlPreprocess.Valid() {
600 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross9bdfaf02019-04-18 10:56:44 -0700601 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900602 } else {
603 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
604 }
605
606 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
607 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
608 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
609 flags = append(flags, "-I"+src.String())
610 }
611
Colin Cross9bdfaf02019-04-18 10:56:44 -0700612 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900613}
614
615func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700616 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900617
618 outSrcFiles := make(android.Paths, 0, len(srcFiles))
619
620 for _, srcFile := range srcFiles {
621 switch srcFile.Ext() {
622 case ".aidl":
Colin Cross9bdfaf02019-04-18 10:56:44 -0700623 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900624 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900625 case ".sysprop":
626 javaFile := genSysprop(ctx, srcFile)
627 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900628 default:
629 outSrcFiles = append(outSrcFiles, srcFile)
630 }
631 }
632
633 return outSrcFiles
634}
635
Nan Zhang581fd212018-01-10 16:06:12 -0800636func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
637 var deps deps
638
Colin Cross83bb3162018-06-25 15:48:06 -0700639 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800640 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700641 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800642 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700643 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800644 }
645
646 ctx.VisitDirectDeps(func(module android.Module) {
647 otherName := ctx.OtherModuleName(module)
648 tag := ctx.OtherModuleDependencyTag(module)
649
Colin Cross2d24c1b2018-05-23 10:59:18 -0700650 switch tag {
651 case bootClasspathTag:
652 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800653 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700654 } else {
655 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
656 }
657 case libTag:
658 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800659 case SdkLibraryDependency:
660 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700661 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900662 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700663 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800664 checkProducesJars(ctx, dep)
665 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800666 default:
667 ctx.ModuleErrorf("depends on non-java module %q", otherName)
668 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700669 case srcsLibTag:
670 switch dep := module.(type) {
671 case Dependency:
672 srcs := dep.(SrcDependency).CompiledSrcs()
673 whitelistPathPrefixes := make(map[string]bool)
674 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
675 for _, src := range srcs {
676 if _, ok := src.(android.WritablePath); ok { // generated sources
677 deps.srcs = append(deps.srcs, src)
678 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700679 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700680 if strings.HasPrefix(src.Rel(), k) {
681 deps.srcs = append(deps.srcs, src)
682 break
683 }
684 }
685 }
686 }
687 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
688 default:
689 ctx.ModuleErrorf("depends on non-java module %q", otherName)
690 }
Nan Zhang357466b2018-04-17 17:38:36 -0700691 case systemModulesTag:
692 if deps.systemModules != nil {
693 panic("Found two system module dependencies")
694 }
695 sm := module.(*SystemModules)
696 if sm.outputFile == nil {
697 panic("Missing directory for system module dependency")
698 }
699 deps.systemModules = sm.outputFile
Nan Zhang581fd212018-01-10 16:06:12 -0800700 }
701 })
702 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
703 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800704 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700705 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900706 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800707
708 // srcs may depend on some genrule output.
709 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800710 j.srcJars = append(j.srcJars, deps.srcJars...)
711
Nan Zhang581fd212018-01-10 16:06:12 -0800712 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800713 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800714
715 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800716 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800717
Nan Zhang9c69a122018-08-22 10:22:08 -0700718 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800719 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
720 }
721 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800722
Colin Cross8a497952019-03-05 22:25:09 -0800723 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000724 argFilesMap := map[string]string{}
725 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700726
Paul Duffin99e4a502019-02-11 15:38:42 +0000727 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800728 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000729 if _, exists := argFilesMap[label]; !exists {
730 argFilesMap[label] = strings.Join(paths.Strings(), " ")
731 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700732 } else {
733 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000734 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700735 }
736 }
737
738 var err error
739 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
740 if strings.HasPrefix(name, "location ") {
741 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000742 if paths, ok := argFilesMap[label]; ok {
743 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700744 } else {
Paul Duffin99e4a502019-02-11 15:38:42 +0000745 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
746 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700747 }
748 } else if name == "genDir" {
749 return android.PathForModuleGen(ctx).String(), nil
750 }
751 return "", fmt.Errorf("unknown variable '$(%s)'", name)
752 })
753
754 if err != nil {
755 ctx.PropertyErrorf("args", "%s", err.Error())
756 }
757
Nan Zhang581fd212018-01-10 16:06:12 -0800758 return deps
759}
760
761func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
762 j.addDeps(ctx)
763}
764
765func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
766 deps := j.collectDeps(ctx)
767
768 var implicits android.Paths
769 implicits = append(implicits, deps.bootClasspath...)
770 implicits = append(implicits, deps.classpath...)
771
Nan Zhang1598a9e2018-09-04 17:14:32 -0700772 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700773
Colin Cross83bb3162018-06-25 15:48:06 -0700774 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700775 if len(deps.bootClasspath) > 0 {
776 var systemModules classpath
777 if deps.systemModules != nil {
778 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800779 }
Colin Cross997262f2018-06-19 22:49:39 -0700780 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
781 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800782 }
783 if len(deps.classpath.Strings()) > 0 {
784 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
785 }
786
787 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700788 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800789
Nan Zhangaf322cc2018-06-19 15:15:38 -0700790 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800791
Nan Zhang1598a9e2018-09-04 17:14:32 -0700792 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
793
Nan Zhang581fd212018-01-10 16:06:12 -0800794 ctx.Build(pctx, android.BuildParams{
795 Rule: javadoc,
796 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800797 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800798 ImplicitOutput: j.docZip,
799 Inputs: j.srcFiles,
800 Implicits: implicits,
801 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700802 "outDir": android.PathForModuleOut(ctx, "out").String(),
803 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
804 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800805 "srcJars": strings.Join(j.srcJars.Strings(), " "),
806 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700807 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800808 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700809 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800810 "docZip": j.docZip.String(),
811 },
812 })
813}
814
Nan Zhanga40da042018-08-01 12:48:00 -0700815//
816// Droiddoc
817//
818type Droiddoc struct {
819 Javadoc
820
821 properties DroiddocProperties
822 apiFile android.WritablePath
823 dexApiFile android.WritablePath
824 privateApiFile android.WritablePath
825 privateDexApiFile android.WritablePath
826 removedApiFile android.WritablePath
827 removedDexApiFile android.WritablePath
828 exactApiFile android.WritablePath
829 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700830 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700831
832 checkCurrentApiTimestamp android.WritablePath
833 updateCurrentApiTimestamp android.WritablePath
834 checkLastReleasedApiTimestamp android.WritablePath
835
Nan Zhanga40da042018-08-01 12:48:00 -0700836 apiFilePath android.Path
837}
838
Nan Zhanga40da042018-08-01 12:48:00 -0700839func DroiddocFactory() android.Module {
840 module := &Droiddoc{}
841
842 module.AddProperties(&module.properties,
843 &module.Javadoc.properties)
844
845 InitDroiddocModule(module, android.HostAndDeviceSupported)
846 return module
847}
848
849func DroiddocHostFactory() android.Module {
850 module := &Droiddoc{}
851
852 module.AddProperties(&module.properties,
853 &module.Javadoc.properties)
854
855 InitDroiddocModule(module, android.HostSupported)
856 return module
857}
858
859func (d *Droiddoc) ApiFilePath() android.Path {
860 return d.apiFilePath
861}
862
Nan Zhang581fd212018-01-10 16:06:12 -0800863func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
864 d.Javadoc.addDeps(ctx)
865
Inseob Kim38449af2019-02-28 14:24:05 +0900866 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
867 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
868 }
869
Nan Zhang79614d12018-04-19 18:03:39 -0700870 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800871 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
872 }
Nan Zhang581fd212018-01-10 16:06:12 -0800873}
874
Nan Zhang66dc2362018-08-14 20:41:04 -0700875func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
876 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700877 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800878
Nan Zhanga40da042018-08-01 12:48:00 -0700879 *implicits = append(*implicits, deps.bootClasspath...)
880 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800881
Nan Zhangc94f9d82018-06-26 10:02:26 -0700882 if len(deps.bootClasspath.Strings()) > 0 {
883 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700884 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700885 }
Nan Zhanga40da042018-08-01 12:48:00 -0700886 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700887 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700888 dokkaClasspath := classpath{}
889 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
890 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
891 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700892
Nan Zhang9c69a122018-08-22 10:22:08 -0700893 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
894 // based stubs generation.
895 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
896 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
897 // the correct package name base path.
898 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
899 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
900 } else {
901 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
902 }
Nan Zhang581fd212018-01-10 16:06:12 -0800903
Nan Zhanga40da042018-08-01 12:48:00 -0700904 return flags, nil
905}
Nan Zhang581fd212018-01-10 16:06:12 -0800906
Nan Zhanga40da042018-08-01 12:48:00 -0700907func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700908 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800909
Nan Zhanga40da042018-08-01 12:48:00 -0700910 *implicits = append(*implicits, jsilver)
911 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700912
Nan Zhang46130972018-06-04 11:28:01 -0700913 var date string
914 if runtime.GOOS == "darwin" {
915 date = `date -r`
916 } else {
917 date = `date -d`
918 }
919
Nan Zhang443fa522018-08-20 20:58:28 -0700920 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
921 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
922 // 1.9 language features.
923 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700924 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800925 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang79614d12018-04-19 18:03:39 -0700926 `-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700927
Nan Zhanga40da042018-08-01 12:48:00 -0700928 if String(d.properties.Custom_template) == "" {
929 // TODO: This is almost always droiddoc-templates-sdk
930 ctx.PropertyErrorf("custom_template", "must specify a template")
931 }
932
933 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700934 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700935 *implicits = append(*implicits, t.deps...)
936 args = args + " -templatedir " + t.dir.String()
937 } else {
938 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
939 }
940 })
941
942 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800943 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800944 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800945 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700946 }
947
948 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800949 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800950 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800951 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700952 }
953
954 if len(d.properties.Html_dirs) > 2 {
955 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
956 }
957
Colin Cross8a497952019-03-05 22:25:09 -0800958 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700959 *implicits = append(*implicits, knownTags...)
960
961 for _, kt := range knownTags {
962 args = args + " -knowntags " + kt.String()
963 }
964
965 for _, hdf := range d.properties.Hdf {
966 args = args + " -hdf " + hdf
967 }
968
969 if String(d.properties.Proofread_file) != "" {
970 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
971 args = args + " -proofread " + proofreadFile.String()
972 }
973
974 if String(d.properties.Todo_file) != "" {
975 // tricky part:
976 // we should not compute full path for todo_file through PathForModuleOut().
977 // the non-standard doclet will get the full path relative to "-o".
978 args = args + " -todo " + String(d.properties.Todo_file)
979 }
980
981 if String(d.properties.Resourcesdir) != "" {
982 // TODO: should we add files under resourcesDir to the implicits? It seems that
983 // resourcesDir is one sub dir of htmlDir
984 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
985 args = args + " -resourcesdir " + resourcesDir.String()
986 }
987
988 if String(d.properties.Resourcesoutdir) != "" {
989 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
990 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
991 }
992 return args
993}
994
Nan Zhang1598a9e2018-09-04 17:14:32 -0700995func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
996 implicitOutputs *android.WritablePaths) string {
997 var doclavaFlags string
Luca Stefanicf7b2932019-09-01 21:49:45 +0200998 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
999 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001000 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001001 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1002 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001003 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1004 d.apiFilePath = d.apiFile
1005 }
1006
Luca Stefanicf7b2932019-09-01 21:49:45 +02001007 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1008 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001009 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001010 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1011 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001012 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1013 }
1014
1015 if String(d.properties.Private_api_filename) != "" {
1016 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1017 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001018 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1019 }
1020
1021 if String(d.properties.Dex_api_filename) != "" {
1022 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1023 doclavaFlags += " -dexApi " + d.dexApiFile.String()
1024 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1025 }
1026
1027 if String(d.properties.Private_dex_api_filename) != "" {
1028 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1029 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001030 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1031 }
1032
1033 if String(d.properties.Removed_dex_api_filename) != "" {
1034 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1035 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001036 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1037 }
1038
1039 if String(d.properties.Exact_api_filename) != "" {
1040 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1041 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001042 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1043 }
1044
1045 if String(d.properties.Dex_mapping_filename) != "" {
1046 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1047 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001048 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1049 }
1050
Nan Zhang66dc2362018-08-14 20:41:04 -07001051 if String(d.properties.Proguard_filename) != "" {
1052 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1053 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -07001054 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1055 }
1056
Nan Zhanga40da042018-08-01 12:48:00 -07001057 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001058 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001059 }
1060
1061 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001062 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001063 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001064
1065 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001066}
1067
1068func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1069 var cmds string
1070 if String(d.properties.Static_doc_index_redirect) != "" {
1071 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1072 "static_doc_index_redirect")
1073 *implicits = append(*implicits, static_doc_index_redirect)
1074 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001075 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001076 }
1077
1078 if String(d.properties.Static_doc_properties) != "" {
1079 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1080 "static_doc_properties")
1081 *implicits = append(*implicits, static_doc_properties)
1082 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001083 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001084 }
1085 return cmds
1086}
1087
Nan Zhang1598a9e2018-09-04 17:14:32 -07001088func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1089 implicitOutputs android.WritablePaths,
1090 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1091 ctx.Build(pctx, android.BuildParams{
1092 Rule: javadoc,
1093 Description: "Doclava",
1094 Output: d.Javadoc.stubsSrcJar,
1095 Inputs: d.Javadoc.srcFiles,
1096 Implicits: implicits,
1097 ImplicitOutputs: implicitOutputs,
1098 Args: map[string]string{
1099 "outDir": android.PathForModuleOut(ctx, "out").String(),
1100 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1101 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1102 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1103 "opts": opts,
1104 "bootclasspathArgs": bootclasspathArgs,
1105 "classpathArgs": classpathArgs,
1106 "sourcepathArgs": sourcepathArgs,
1107 "docZip": d.Javadoc.docZip.String(),
1108 "postDoclavaCmds": postDoclavaCmds,
1109 },
1110 })
1111}
1112
1113func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1114 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1115 ctx.Build(pctx, android.BuildParams{
1116 Rule: apiCheck,
1117 Description: "Doclava Check API",
1118 Output: output,
1119 Inputs: nil,
1120 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1121 checkApiClasspath...),
1122 Args: map[string]string{
1123 "msg": msg,
1124 "classpath": checkApiClasspath.FormJavaClassPath(""),
1125 "opts": opts,
1126 "apiFile": apiFile.String(),
1127 "apiFileToCheck": d.apiFile.String(),
1128 "removedApiFile": removedApiFile.String(),
1129 "removedApiFileToCheck": d.removedApiFile.String(),
1130 },
1131 })
1132}
1133
1134func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1135 classpathArgs, opts string) {
1136 ctx.Build(pctx, android.BuildParams{
1137 Rule: dokka,
1138 Description: "Dokka",
1139 Output: d.Javadoc.stubsSrcJar,
1140 Inputs: d.Javadoc.srcFiles,
1141 Implicits: implicits,
1142 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001143 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1144 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1145 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001146 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1147 "classpathArgs": classpathArgs,
1148 "opts": opts,
1149 "docZip": d.Javadoc.docZip.String(),
1150 },
1151 })
1152}
1153
1154func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1155 deps := d.Javadoc.collectDeps(ctx)
1156
1157 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1158 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1159 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1160 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1161
1162 var implicits android.Paths
1163 implicits = append(implicits, d.Javadoc.srcJars...)
1164 implicits = append(implicits, d.Javadoc.argFiles...)
1165
1166 var implicitOutputs android.WritablePaths
1167 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1168 for _, o := range d.Javadoc.properties.Out {
1169 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1170 }
1171
1172 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1173 if err != nil {
1174 return
1175 }
1176
1177 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1178 if Bool(d.properties.Dokka_enabled) {
1179 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1180 } else {
1181 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1182 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1183 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1184 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1185 flags.postDoclavaCmds)
1186 }
1187
Luca Stefanicf7b2932019-09-01 21:49:45 +02001188 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001189 !ctx.Config().IsPdkBuild() {
1190 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1191 "check_api.current.api_file")
1192 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1193 "check_api.current_removed_api_file")
1194
1195 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1196 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1197 fmt.Sprintf(`\n******************************\n`+
1198 `You have tried to change the API from what has been previously approved.\n\n`+
1199 `To make these errors go away, you have two choices:\n`+
1200 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1201 ` errors above.\n\n`+
1202 ` 2. You can update current.txt by executing the following command:\n`+
1203 ` make %s-update-current-api\n\n`+
1204 ` To submit the revised current.txt to the main Android repository,\n`+
1205 ` you will need approval.\n`+
1206 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1207 d.checkCurrentApiTimestamp)
1208
1209 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1210 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1211 d.updateCurrentApiTimestamp)
1212 }
1213
Luca Stefanicf7b2932019-09-01 21:49:45 +02001214 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001215 !ctx.Config().IsPdkBuild() {
1216 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1217 "check_api.last_released.api_file")
1218 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1219 "check_api.last_released.removed_api_file")
1220
1221 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1222 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1223 `\n******************************\n`+
1224 `You have tried to change the API from what has been previously released in\n`+
1225 `an SDK. Please fix the errors listed above.\n`+
1226 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1227 d.checkLastReleasedApiTimestamp)
1228 }
1229}
1230
1231//
1232// Droidstubs
1233//
1234type Droidstubs struct {
1235 Javadoc
1236
Pete Gillin581d6082018-10-22 15:55:04 +01001237 properties DroidstubsProperties
1238 apiFile android.WritablePath
1239 apiXmlFile android.WritablePath
1240 lastReleasedApiXmlFile android.WritablePath
1241 dexApiFile android.WritablePath
1242 privateApiFile android.WritablePath
1243 privateDexApiFile android.WritablePath
1244 removedApiFile android.WritablePath
1245 removedDexApiFile android.WritablePath
1246 apiMappingFile android.WritablePath
1247 exactApiFile android.WritablePath
1248 proguardFile android.WritablePath
1249 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001250
1251 checkCurrentApiTimestamp android.WritablePath
1252 updateCurrentApiTimestamp android.WritablePath
1253 checkLastReleasedApiTimestamp android.WritablePath
1254
Pete Gillin581d6082018-10-22 15:55:04 +01001255 checkNullabilityWarningsTimestamp android.WritablePath
1256
Nan Zhang1598a9e2018-09-04 17:14:32 -07001257 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001258 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259
1260 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001261
1262 jdiffDocZip android.WritablePath
1263 jdiffStubsSrcJar android.WritablePath
Jerome Gaillard0b09ad72019-10-10 19:29:11 +01001264
1265 metadataZip android.WritablePath
1266 metadataDir android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001267}
1268
1269func DroidstubsFactory() android.Module {
1270 module := &Droidstubs{}
1271
1272 module.AddProperties(&module.properties,
1273 &module.Javadoc.properties)
1274
1275 InitDroiddocModule(module, android.HostAndDeviceSupported)
1276 return module
1277}
1278
1279func DroidstubsHostFactory() android.Module {
1280 module := &Droidstubs{}
1281
1282 module.AddProperties(&module.properties,
1283 &module.Javadoc.properties)
1284
1285 InitDroiddocModule(module, android.HostSupported)
1286 return module
1287}
1288
1289func (d *Droidstubs) ApiFilePath() android.Path {
1290 return d.apiFilePath
1291}
1292
1293func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1294 d.Javadoc.addDeps(ctx)
1295
Inseob Kim38449af2019-02-28 14:24:05 +09001296 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1297 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1298 }
1299
Nan Zhang1598a9e2018-09-04 17:14:32 -07001300 if len(d.properties.Merge_annotations_dirs) != 0 {
1301 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1302 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1303 }
1304 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001305
Pete Gillin77167902018-09-19 18:16:26 +01001306 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1307 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1308 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1309 }
1310 }
1311
Nan Zhang9c69a122018-08-22 10:22:08 -07001312 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1313 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1314 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1315 }
1316 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001317}
1318
1319func (d *Droidstubs) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
1320 deps deps) (droiddocBuilderFlags, error) {
1321 var flags droiddocBuilderFlags
1322
1323 *implicits = append(*implicits, deps.bootClasspath...)
1324 *implicits = append(*implicits, deps.classpath...)
1325
1326 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
1327 // since it doesn't support system modules yet.
1328 if len(deps.bootClasspath.Strings()) > 0 {
1329 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
1330 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
1331 }
1332 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
1333
Sundong Ahn56dce442018-10-05 18:41:09 +09001334 flags.sourcepathArgs = "-sourcepath \"" + strings.Join(d.Javadoc.sourcepaths.Strings(), ":") + "\""
Nan Zhang1598a9e2018-09-04 17:14:32 -07001335 return flags, nil
1336}
1337
1338func (d *Droidstubs) collectStubsFlags(ctx android.ModuleContext,
1339 implicitOutputs *android.WritablePaths) string {
1340 var metalavaFlags string
Luca Stefanicf7b2932019-09-01 21:49:45 +02001341 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1342 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001343 String(d.properties.Api_filename) != "" {
1344 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1345 metalavaFlags = metalavaFlags + " --api " + d.apiFile.String()
1346 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1347 d.apiFilePath = d.apiFile
1348 }
1349
Luca Stefanicf7b2932019-09-01 21:49:45 +02001350 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") ||
1351 apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") ||
Nan Zhang1598a9e2018-09-04 17:14:32 -07001352 String(d.properties.Removed_api_filename) != "" {
1353 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1354 metalavaFlags = metalavaFlags + " --removed-api " + d.removedApiFile.String()
1355 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1356 }
1357
1358 if String(d.properties.Private_api_filename) != "" {
1359 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1360 metalavaFlags = metalavaFlags + " --private-api " + d.privateApiFile.String()
1361 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1362 }
1363
1364 if String(d.properties.Dex_api_filename) != "" {
1365 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1366 metalavaFlags += " --dex-api " + d.dexApiFile.String()
1367 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1368 }
1369
1370 if String(d.properties.Private_dex_api_filename) != "" {
1371 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1372 metalavaFlags = metalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
1373 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1374 }
1375
1376 if String(d.properties.Removed_dex_api_filename) != "" {
1377 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1378 metalavaFlags = metalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
1379 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1380 }
1381
1382 if String(d.properties.Exact_api_filename) != "" {
1383 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1384 metalavaFlags = metalavaFlags + " --exact-api " + d.exactApiFile.String()
1385 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1386 }
1387
Nan Zhang9c69a122018-08-22 10:22:08 -07001388 if String(d.properties.Dex_mapping_filename) != "" {
1389 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1390 metalavaFlags = metalavaFlags + " --dex-api-mapping " + d.apiMappingFile.String()
1391 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1392 }
1393
Nan Zhang199645c2018-09-19 12:40:06 -07001394 if String(d.properties.Proguard_filename) != "" {
1395 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1396 metalavaFlags += " --proguard " + d.proguardFile.String()
1397 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1398 }
1399
Nan Zhang9c69a122018-08-22 10:22:08 -07001400 if Bool(d.properties.Write_sdk_values) {
Jerome Gaillard0b09ad72019-10-10 19:29:11 +01001401 d.metadataDir = android.PathForModuleOut(ctx, "metadata")
1402 metalavaFlags = metalavaFlags + " --sdk-values " + d.metadataDir.String()
Nan Zhang9c69a122018-08-22 10:22:08 -07001403 }
1404
Nan Zhang1598a9e2018-09-04 17:14:32 -07001405 if Bool(d.properties.Create_doc_stubs) {
1406 metalavaFlags += " --doc-stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1407 } else {
1408 metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1409 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001410 return metalavaFlags
1411}
1412
1413func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
Nan Zhangdee152b2018-12-26 16:06:37 -08001414 implicits *android.Paths, implicitOutputs *android.WritablePaths) (string, string) {
1415 var flags, mergeAnnoDirFlags string
Nan Zhang1598a9e2018-09-04 17:14:32 -07001416 if Bool(d.properties.Annotations_enabled) {
Pete Gillina262c052018-09-14 14:25:48 +01001417 flags += " --include-annotations"
Pete Gillinc382a562018-11-14 18:45:46 +00001418 validatingNullability :=
1419 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1420 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001421 migratingNullability := String(d.properties.Previous_api) != ""
1422 if !(migratingNullability || validatingNullability) {
1423 ctx.PropertyErrorf("previous_api",
1424 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001425 }
Pete Gillina262c052018-09-14 14:25:48 +01001426 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001427 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Pete Gillina262c052018-09-14 14:25:48 +01001428 *implicits = append(*implicits, previousApi)
1429 flags += " --migrate-nullness " + previousApi.String()
1430 }
Pete Gillinc382a562018-11-14 18:45:46 +00001431 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross8a497952019-03-05 22:25:09 -08001432 flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
Pete Gillinc382a562018-11-14 18:45:46 +00001433 }
Pete Gillina262c052018-09-14 14:25:48 +01001434 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001435 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
1436 *implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
1437 flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
Pete Gillina262c052018-09-14 14:25:48 +01001438 }
Nan Zhanga40da042018-08-01 12:48:00 -07001439
1440 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
1441 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
1442
Nan Zhangf4936b02018-08-01 15:00:28 -07001443 flags += " --extract-annotations " + d.annotationsZip.String()
1444
Nan Zhang1598a9e2018-09-04 17:14:32 -07001445 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001446 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001447 "has to be non-empty if annotations was enabled!")
1448 }
Nan Zhangf4936b02018-08-01 15:00:28 -07001449 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1450 if t, ok := m.(*ExportedDroiddocDir); ok {
1451 *implicits = append(*implicits, t.deps...)
Nan Zhangdee152b2018-12-26 16:06:37 -08001452 mergeAnnoDirFlags += " --merge-qualifier-annotations " + t.dir.String()
Nan Zhangf4936b02018-08-01 15:00:28 -07001453 } else {
Nan Zhang9c69a122018-08-22 10:22:08 -07001454 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhangf4936b02018-08-01 15:00:28 -07001455 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1456 }
1457 })
Nan Zhangdee152b2018-12-26 16:06:37 -08001458 flags += mergeAnnoDirFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001459 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001460 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
Nan Zhanga40da042018-08-01 12:48:00 -07001461 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001462
Nan Zhangdee152b2018-12-26 16:06:37 -08001463 return flags, mergeAnnoDirFlags
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001464}
1465
1466func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
1467 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1468 var flags string
Pete Gillin77167902018-09-19 18:16:26 +01001469 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1470 if t, ok := m.(*ExportedDroiddocDir); ok {
1471 *implicits = append(*implicits, t.deps...)
1472 flags += " --merge-inclusion-annotations " + t.dir.String()
1473 } else {
1474 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1475 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1476 }
1477 })
Nan Zhanga40da042018-08-01 12:48:00 -07001478
1479 return flags
1480}
1481
Nan Zhang9c69a122018-08-22 10:22:08 -07001482func (d *Droidstubs) collectAPILevelsAnnotationsFlags(ctx android.ModuleContext,
1483 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1484 var flags string
1485 if Bool(d.properties.Api_levels_annotations_enabled) {
1486 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1487 *implicitOutputs = append(*implicitOutputs, d.apiVersionsXml)
1488
1489 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1490 ctx.PropertyErrorf("api_levels_annotations_dirs",
1491 "has to be non-empty if api levels annotations was enabled!")
1492 }
1493
1494 flags = " --generate-api-levels " + d.apiVersionsXml.String() + " --apply-api-levels " +
1495 d.apiVersionsXml.String() + " --current-version " + ctx.Config().PlatformSdkVersion() +
1496 " --current-codename " + ctx.Config().PlatformSdkCodename() + " "
1497
1498 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1499 if t, ok := m.(*ExportedDroiddocDir); ok {
1500 var androidJars android.Paths
1501 for _, dep := range t.deps {
1502 if strings.HasSuffix(dep.String(), "android.jar") {
1503 androidJars = append(androidJars, dep)
1504 }
1505 }
1506 *implicits = append(*implicits, androidJars...)
Tor Norbyeebcdfed2019-01-24 11:05:46 -08001507 flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
Nan Zhang9c69a122018-08-22 10:22:08 -07001508 } else {
1509 ctx.PropertyErrorf("api_levels_annotations_dirs",
1510 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1511 }
1512 })
1513
1514 }
1515
1516 return flags
1517}
1518
Nan Zhang71bbe632018-09-17 14:32:21 -07001519func (d *Droidstubs) collectApiToXmlFlags(ctx android.ModuleContext, implicits *android.Paths,
1520 implicitOutputs *android.WritablePaths) string {
1521 var flags string
1522 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1523 if d.apiFile.String() == "" {
1524 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1525 }
1526
1527 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
1528 *implicitOutputs = append(*implicitOutputs, d.apiXmlFile)
1529
1530 flags = " --api-xml " + d.apiXmlFile.String()
1531
1532 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1533 ctx.PropertyErrorf("check_api.last_released.api_file",
1534 "has to be non-empty if jdiff was enabled!")
1535 }
1536 lastReleasedApi := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1537 "check_api.last_released.api_file")
1538 *implicits = append(*implicits, lastReleasedApi)
1539
1540 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
1541 *implicitOutputs = append(*implicitOutputs, d.lastReleasedApiXmlFile)
1542
1543 flags += " --convert-to-jdiff " + lastReleasedApi.String() + " " +
1544 d.lastReleasedApiXmlFile.String()
1545 }
1546
1547 return flags
1548}
1549
Nan Zhang1598a9e2018-09-04 17:14:32 -07001550func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
1551 implicitOutputs android.WritablePaths, javaVersion,
1552 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001553
Jerome Gaillard0b09ad72019-10-10 19:29:11 +01001554 var writeSdkValues, metadataZip, metadataDir string
1555 if Bool(d.properties.Write_sdk_values) {
1556 writeSdkValues = "true"
1557 d.metadataZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-metadata.zip")
1558 metadataZip = d.metadataZip.String()
1559 metadataDir = d.metadataDir.String()
1560 implicitOutputs = append(implicitOutputs, d.metadataZip)
1561 } else {
1562 writeSdkValues = "false"
1563 metadataZip = ""
1564 metadataDir = ""
1565 }
1566
Nan Zhang86d2d552018-08-09 15:33:27 -07001567 ctx.Build(pctx, android.BuildParams{
1568 Rule: metalava,
1569 Description: "Metalava",
1570 Output: d.Javadoc.stubsSrcJar,
1571 Inputs: d.Javadoc.srcFiles,
1572 Implicits: implicits,
1573 ImplicitOutputs: implicitOutputs,
1574 Args: map[string]string{
Nan Zhang86d2d552018-08-09 15:33:27 -07001575 "outDir": android.PathForModuleOut(ctx, "out").String(),
1576 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1577 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1578 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001579 "javaVersion": javaVersion,
Nan Zhang86d2d552018-08-09 15:33:27 -07001580 "bootclasspathArgs": bootclasspathArgs,
1581 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001582 "sourcepathArgs": sourcepathArgs,
1583 "opts": opts,
Jerome Gaillard0b09ad72019-10-10 19:29:11 +01001584 "writeSdkValues": writeSdkValues,
1585 "metadataZip": metadataZip,
1586 "metadataDir": metadataDir,
Nan Zhang86d2d552018-08-09 15:33:27 -07001587 },
1588 })
1589}
1590
Nan Zhang1598a9e2018-09-04 17:14:32 -07001591func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
Adrian Roos4937c4a2019-08-12 17:54:09 +02001592 apiFile, removedApiFile android.Path, baselineFile android.OptionalPath, updatedBaselineOut android.WritablePath, implicits android.Paths,
Colin Cross39c16792019-01-24 16:32:44 -08001593 javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001594 output android.WritablePath) {
Adrian Roos4937c4a2019-08-12 17:54:09 +02001595
1596 implicits = append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile}, implicits...)
1597 var implicitOutputs android.WritablePaths
1598
1599 if baselineFile.Valid() {
1600 implicits = append(implicits, baselineFile.Path())
1601 implicitOutputs = append(implicitOutputs, updatedBaselineOut)
1602 }
1603
Nan Zhang2760dfc2018-08-24 17:32:54 +00001604 ctx.Build(pctx, android.BuildParams{
Adrian Roos4937c4a2019-08-12 17:54:09 +02001605 Rule: metalavaApiCheck,
1606 Description: "Metalava Check API",
1607 Output: output,
1608 Inputs: d.Javadoc.srcFiles,
1609 Implicits: implicits,
1610 ImplicitOutputs: implicitOutputs,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001611 Args: map[string]string{
Colin Cross39c16792019-01-24 16:32:44 -08001612 "srcJarDir": android.PathForModuleOut(ctx, subdir, "srcjars").String(),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001613 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1614 "javaVersion": javaVersion,
1615 "bootclasspathArgs": bootclasspathArgs,
1616 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001617 "sourcepathArgs": sourcepathArgs,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001618 "opts": opts,
1619 "msg": msg,
1620 },
1621 })
1622}
1623
Nan Zhang71bbe632018-09-17 14:32:21 -07001624func (d *Droidstubs) transformJdiff(ctx android.ModuleContext, implicits android.Paths,
1625 implicitOutputs android.WritablePaths,
1626 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
1627 ctx.Build(pctx, android.BuildParams{
1628 Rule: javadoc,
1629 Description: "Jdiff",
1630 Output: d.jdiffStubsSrcJar,
1631 Inputs: d.Javadoc.srcFiles,
1632 Implicits: implicits,
1633 ImplicitOutputs: implicitOutputs,
1634 Args: map[string]string{
Nan Zhang23a1ba62018-09-19 11:19:39 -07001635 "outDir": android.PathForModuleOut(ctx, "jdiff-out").String(),
1636 "srcJarDir": android.PathForModuleOut(ctx, "jdiff-srcjars").String(),
1637 "stubsDir": android.PathForModuleOut(ctx, "jdiff-stubsDir").String(),
Nan Zhang71bbe632018-09-17 14:32:21 -07001638 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1639 "opts": opts,
1640 "bootclasspathArgs": bootclasspathArgs,
1641 "classpathArgs": classpathArgs,
1642 "sourcepathArgs": sourcepathArgs,
1643 "docZip": d.jdiffDocZip.String(),
1644 },
1645 })
1646}
1647
Nan Zhang1598a9e2018-09-04 17:14:32 -07001648func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001649 deps := d.Javadoc.collectDeps(ctx)
1650
1651 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001652
Nan Zhanga40da042018-08-01 12:48:00 -07001653 var implicits android.Paths
1654 implicits = append(implicits, d.Javadoc.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001655 implicits = append(implicits, d.Javadoc.argFiles...)
Nan Zhanga40da042018-08-01 12:48:00 -07001656
1657 var implicitOutputs android.WritablePaths
Nan Zhang1598a9e2018-09-04 17:14:32 -07001658 for _, o := range d.Javadoc.properties.Out {
Nan Zhanga40da042018-08-01 12:48:00 -07001659 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1660 }
1661
1662 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
Nan Zhang2760dfc2018-08-24 17:32:54 +00001663 metalavaCheckApiImplicits := implicits
Nan Zhang71bbe632018-09-17 14:32:21 -07001664 jdiffImplicits := implicits
1665
Nan Zhanga40da042018-08-01 12:48:00 -07001666 if err != nil {
1667 return
1668 }
1669
Nan Zhang1598a9e2018-09-04 17:14:32 -07001670 flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
Nan Zhangdee152b2018-12-26 16:06:37 -08001671 flags.metalavaAnnotationsFlags, flags.metalavaMergeAnnoDirFlags =
1672 d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001673 flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang9c69a122018-08-22 10:22:08 -07001674 flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang71bbe632018-09-17 14:32:21 -07001675 flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
1676
Nan Zhang1598a9e2018-09-04 17:14:32 -07001677 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1678 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1679 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1680 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1681 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001682 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001683 d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
1684 flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001685 flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
Nan Zhang71bbe632018-09-17 14:32:21 -07001686 flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
Nan Zhang61819ce2018-05-04 18:49:16 -07001687
Luca Stefanicf7b2932019-09-01 21:49:45 +02001688 if apiCheckEnabled(ctx, d.properties.Check_api.Current, "current") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001689 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001690 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1691 "check_api.current.api_file")
1692 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1693 "check_api.current_removed_api_file")
Adrian Roos4937c4a2019-08-12 17:54:09 +02001694 baselineFile := ctx.ExpandOptionalSource(d.properties.Check_api.Current.Baseline_file,
1695 "check_api.current.baseline_file")
Nan Zhang61819ce2018-05-04 18:49:16 -07001696
Nan Zhang2760dfc2018-08-24 17:32:54 +00001697 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001698 opts := " " + d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
1699 " --check-compatibility:removed:current " + removedApiFile.String() +
Nan Zhangdee152b2018-12-26 16:06:37 -08001700 flags.metalavaInclusionAnnotationsFlags + flags.metalavaMergeAnnoDirFlags + " "
Adrian Roos4937c4a2019-08-12 17:54:09 +02001701 baselineOut := android.PathForModuleOut(ctx, "current_baseline.txt")
1702 if baselineFile.Valid() {
1703 opts = opts + "--baseline " + baselineFile.String() + " --update-baseline " + baselineOut.String() + " "
1704 }
Nan Zhang2760dfc2018-08-24 17:32:54 +00001705
Adrian Roos4937c4a2019-08-12 17:54:09 +02001706 d.transformCheckApi(ctx, apiFile, removedApiFile, baselineFile, baselineOut, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001707 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001708 fmt.Sprintf(`\n******************************\n`+
1709 `You have tried to change the API from what has been previously approved.\n\n`+
1710 `To make these errors go away, you have two choices:\n`+
1711 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1712 ` errors above.\n\n`+
1713 ` 2. You can update current.txt by executing the following command:\n`+
1714 ` make %s-update-current-api\n\n`+
1715 ` To submit the revised current.txt to the main Android repository,\n`+
1716 ` you will need approval.\n`+
1717 `******************************\n`, ctx.ModuleName()),
1718 d.checkCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001719
1720 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001721 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1722 d.updateCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001723 }
Nan Zhanga40da042018-08-01 12:48:00 -07001724
Luca Stefanicf7b2932019-09-01 21:49:45 +02001725 if apiCheckEnabled(ctx, d.properties.Check_api.Last_released, "last_released") &&
Nan Zhang1598a9e2018-09-04 17:14:32 -07001726 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001727 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1728 "check_api.last_released.api_file")
1729 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1730 "check_api.last_released.removed_api_file")
Adrian Roos4937c4a2019-08-12 17:54:09 +02001731 baselineFile := ctx.ExpandOptionalSource(d.properties.Check_api.Last_released.Baseline_file,
1732 "check_api.last_released.baseline_file")
Nan Zhang61819ce2018-05-04 18:49:16 -07001733
Nan Zhang2760dfc2018-08-24 17:32:54 +00001734 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001735 opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
1736 flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
Nan Zhangdee152b2018-12-26 16:06:37 -08001737 removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
Adrian Roos4937c4a2019-08-12 17:54:09 +02001738 baselineOut := android.PathForModuleOut(ctx, "last_released_baseline.txt")
1739 if baselineFile.Valid() {
1740 opts = opts + "--baseline " + baselineFile.String() + " --update-baseline " + baselineOut.String() + " "
1741 }
Nan Zhang2760dfc2018-08-24 17:32:54 +00001742
Adrian Roos4937c4a2019-08-12 17:54:09 +02001743 d.transformCheckApi(ctx, apiFile, removedApiFile, baselineFile, baselineOut, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001744 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001745 `\n******************************\n`+
1746 `You have tried to change the API from what has been previously released in\n`+
1747 `an SDK. Please fix the errors listed above.\n`+
1748 `******************************\n`,
1749 d.checkLastReleasedApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001750 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001751
Pete Gillin581d6082018-10-22 15:55:04 +01001752 if String(d.properties.Check_nullability_warnings) != "" {
1753 if d.nullabilityWarningsFile == nil {
1754 ctx.PropertyErrorf("check_nullability_warnings",
1755 "Cannot specify check_nullability_warnings unless validating nullability")
1756 }
1757 checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
1758 "check_nullability_warnings")
1759 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
1760 msg := fmt.Sprintf(`\n******************************\n`+
1761 `The warnings encountered during nullability annotation validation did\n`+
1762 `not match the checked in file of expected warnings. The diffs are shown\n`+
1763 `above. You have two options:\n`+
1764 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1765 ` 2. Update the file of expected warnings by running:\n`+
1766 ` cp %s %s\n`+
1767 ` and submitting the updated file as part of your change.`,
1768 d.nullabilityWarningsFile, checkNullabilityWarnings)
1769 ctx.Build(pctx, android.BuildParams{
1770 Rule: nullabilityWarningsCheck,
1771 Description: "Nullability Warnings Check",
1772 Output: d.checkNullabilityWarningsTimestamp,
1773 Implicits: android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
1774 Args: map[string]string{
1775 "expected": checkNullabilityWarnings.String(),
1776 "actual": d.nullabilityWarningsFile.String(),
1777 "msg": msg,
1778 },
1779 })
1780 }
1781
Nan Zhang71bbe632018-09-17 14:32:21 -07001782 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1783
Nan Zhang86b06202018-09-21 17:09:21 -07001784 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1785 // since there's cron job downstream that fetch this .zip file periodically.
1786 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001787 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1788 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1789
1790 var jdiffImplicitOutputs android.WritablePaths
1791 jdiffImplicitOutputs = append(jdiffImplicitOutputs, d.jdiffDocZip)
1792
1793 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
1794 jdiffImplicits = append(jdiffImplicits, android.Paths{jdiff, d.apiXmlFile, d.lastReleasedApiXmlFile}...)
1795
1796 opts := " -encoding UTF-8 -source 1.8 -J-Xmx1600m -XDignore.symbol.file " +
1797 "-doclet jdiff.JDiff -docletpath " + jdiff.String() + " -quiet " +
1798 "-newapi " + strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext()) +
1799 " -newapidir " + filepath.Dir(d.apiXmlFile.String()) +
1800 " -oldapi " + strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext()) +
1801 " -oldapidir " + filepath.Dir(d.lastReleasedApiXmlFile.String())
1802
1803 d.transformJdiff(ctx, jdiffImplicits, jdiffImplicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1804 flags.sourcepathArgs, opts)
1805 }
Nan Zhang581fd212018-01-10 16:06:12 -08001806}
Dan Willemsencc090972018-02-26 14:33:31 -08001807
Nan Zhanga40da042018-08-01 12:48:00 -07001808//
Nan Zhangf4936b02018-08-01 15:00:28 -07001809// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001810//
Dan Willemsencc090972018-02-26 14:33:31 -08001811var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001812var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001813var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001814var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001815
Nan Zhangf4936b02018-08-01 15:00:28 -07001816type ExportedDroiddocDirProperties struct {
1817 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001818 Path *string
1819}
1820
Nan Zhangf4936b02018-08-01 15:00:28 -07001821type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001822 android.ModuleBase
1823
Nan Zhangf4936b02018-08-01 15:00:28 -07001824 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001825
1826 deps android.Paths
1827 dir android.Path
1828}
1829
Nan Zhangf4936b02018-08-01 15:00:28 -07001830func ExportedDroiddocDirFactory() android.Module {
1831 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001832 module.AddProperties(&module.properties)
1833 android.InitAndroidModule(module)
1834 return module
1835}
1836
Nan Zhangf4936b02018-08-01 15:00:28 -07001837func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001838
Nan Zhangf4936b02018-08-01 15:00:28 -07001839func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001840 path := String(d.properties.Path)
1841 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001842 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001843}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001844
1845//
1846// Defaults
1847//
1848type DocDefaults struct {
1849 android.ModuleBase
1850 android.DefaultsModuleBase
1851}
1852
1853func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1854}
1855
Nan Zhangb2b33de2018-02-23 11:18:47 -08001856func DocDefaultsFactory() android.Module {
1857 module := &DocDefaults{}
1858
1859 module.AddProperties(
1860 &JavadocProperties{},
1861 &DroiddocProperties{},
1862 )
1863
1864 android.InitDefaultsModule(module)
1865
1866 return module
1867}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001868
1869func StubsDefaultsFactory() android.Module {
1870 module := &DocDefaults{}
1871
1872 module.AddProperties(
1873 &JavadocProperties{},
1874 &DroidstubsProperties{},
1875 )
1876
1877 android.InitDefaultsModule(module)
1878
1879 return module
1880}