blob: ae810e11c734f6688fe65251f06b840c90972750 [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"
Jeongik Cha6bd33c12019-06-25 16:26:18 +090026 "github.com/google/blueprint/proptools"
Nan Zhang581fd212018-01-10 16:06:12 -080027)
28
29var (
30 javadoc = pctx.AndroidStaticRule("javadoc",
31 blueprint.RuleParams{
32 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070033 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang40b41b42018-10-02 16:11:17 -070034 `${config.SoongJavacWrapper} ${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070035 `$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
Nan Zhang581fd212018-01-10 16:06:12 -080036 `-d $outDir -quiet && ` +
37 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080038 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds && ` +
39 `rm -rf "$srcJarDir"`,
40
Nan Zhang581fd212018-01-10 16:06:12 -080041 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070042 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080043 "${config.JavadocCmd}",
44 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080045 },
Nan Zhang40b41b42018-10-02 16:11:17 -070046 CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
47 Rspfile: "$out.rsp",
48 RspfileContent: "$in",
49 Restat: true,
Nan Zhang581fd212018-01-10 16:06:12 -080050 },
Nan Zhangaf322cc2018-06-19 15:15:38 -070051 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhang1598a9e2018-09-04 17:14:32 -070052 "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "docZip", "postDoclavaCmds")
Nan Zhang61819ce2018-05-04 18:49:16 -070053
54 apiCheck = pctx.AndroidStaticRule("apiCheck",
55 blueprint.RuleParams{
56 Command: `( ${config.ApiCheckCmd} -JXmx1024m -J"classpath $classpath" $opts ` +
57 `$apiFile $apiFileToCheck $removedApiFile $removedApiFileToCheck ` +
Jiyong Parkeeb8a642018-05-12 22:21:20 +090058 `&& touch $out ) || (echo -e "$msg" ; exit 38)`,
Nan Zhang61819ce2018-05-04 18:49:16 -070059 CommandDeps: []string{
60 "${config.ApiCheckCmd}",
61 },
62 },
63 "classpath", "opts", "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck", "msg")
64
65 updateApi = pctx.AndroidStaticRule("updateApi",
66 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070067 Command: `( ( cp -f $srcApiFile $destApiFile && cp -f $srcRemovedApiFile $destRemovedApiFile ) ` +
Nan Zhang61819ce2018-05-04 18:49:16 -070068 `&& touch $out ) || (echo failed to update public API ; exit 38)`,
69 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070070 "srcApiFile", "destApiFile", "srcRemovedApiFile", "destRemovedApiFile")
Nan Zhang79614d12018-04-19 18:03:39 -070071
72 metalava = pctx.AndroidStaticRule("metalava",
73 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070074 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
75 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070076 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -070077 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -080078 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070079 `$opts && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080080 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
81 `rm -rf "$srcJarDir"`,
Nan Zhang79614d12018-04-19 18:03:39 -070082 CommandDeps: []string{
83 "${config.ZipSyncCmd}",
84 "${config.JavaCmd}",
85 "${config.MetalavaJar}",
Nan Zhang79614d12018-04-19 18:03:39 -070086 "${config.SoongZipCmd}",
87 },
88 Rspfile: "$out.rsp",
89 RspfileContent: "$in",
90 Restat: true,
91 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070092 "outDir", "srcJarDir", "stubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
93 "classpathArgs", "sourcepathArgs", "opts")
Nan Zhang2760dfc2018-08-24 17:32:54 +000094
95 metalavaApiCheck = pctx.AndroidStaticRule("metalavaApiCheck",
96 blueprint.RuleParams{
97 Command: `( rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` +
98 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -070099 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -0800100 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800101 `$opts && touch $out && rm -rf "$srcJarDir") || ` +
Nan Zhang2760dfc2018-08-24 17:32:54 +0000102 `( echo -e "$msg" ; exit 38 )`,
103 CommandDeps: []string{
104 "${config.ZipSyncCmd}",
105 "${config.JavaCmd}",
106 "${config.MetalavaJar}",
107 },
108 Rspfile: "$out.rsp",
109 RspfileContent: "$in",
110 },
Nan Zhang1598a9e2018-09-04 17:14:32 -0700111 "srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg")
112
Pete Gillin581d6082018-10-22 15:55:04 +0100113 nullabilityWarningsCheck = pctx.AndroidStaticRule("nullabilityWarningsCheck",
114 blueprint.RuleParams{
115 Command: `( diff $expected $actual && touch $out ) || ( echo -e "$msg" ; exit 38 )`,
116 },
117 "expected", "actual", "msg")
118
Nan Zhang1598a9e2018-09-04 17:14:32 -0700119 dokka = pctx.AndroidStaticRule("dokka",
120 blueprint.RuleParams{
121 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
122 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
123 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -0700124 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.DokkaJar} $srcJarDir ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -0700125 `$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
126 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800127 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
128 `rm -rf "$srcJarDir"`,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700129 CommandDeps: []string{
130 "${config.ZipSyncCmd}",
131 "${config.DokkaJar}",
132 "${config.MetalavaJar}",
133 "${config.SoongZipCmd}",
134 },
135 Restat: true,
136 },
137 "outDir", "srcJarDir", "stubsDir", "srcJars", "classpathArgs", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -0800138)
139
140func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -0800141 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700142 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800143
Nan Zhang581fd212018-01-10 16:06:12 -0800144 android.RegisterModuleType("droiddoc", DroiddocFactory)
145 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -0700146 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800147 android.RegisterModuleType("javadoc", JavadocFactory)
148 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700149
150 android.RegisterModuleType("droidstubs", DroidstubsFactory)
151 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800152}
153
Colin Crossa1ce2a02018-06-20 15:19:39 -0700154var (
155 srcsLibTag = dependencyTag{name: "sources from javalib"}
156)
157
Nan Zhang581fd212018-01-10 16:06:12 -0800158type JavadocProperties struct {
159 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
160 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -0800161 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800162
163 // list of directories rooted at the Android.bp file that will
164 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800165 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800166
167 // list of source files that should not be used to build the Java module.
168 // This is most useful in the arch/multilib variants to remove non-common files
169 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800170 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800171
Nan Zhangb2b33de2018-02-23 11:18:47 -0800172 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800173 Libs []string `android:"arch_variant"`
174
Nan Zhangb2b33de2018-02-23 11:18:47 -0800175 // the java library (in classpath) for documentation that provides java srcs and srcjars.
176 Srcs_lib *string
177
178 // the base dirs under srcs_lib will be scanned for java srcs.
179 Srcs_lib_whitelist_dirs []string
180
181 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
182 Srcs_lib_whitelist_pkgs []string
183
Nan Zhang581fd212018-01-10 16:06:12 -0800184 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800185 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800186
187 // if not blank, set to the version of the sdk to compile against
188 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900189
190 Aidl struct {
191 // Top level directories to pass to aidl tool
192 Include_dirs []string
193
194 // Directories rooted at the Android.bp file to pass to aidl tool
195 Local_include_dirs []string
196 }
Nan Zhang357466b2018-04-17 17:38:36 -0700197
198 // If not blank, set the java version passed to javadoc as -source
199 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700200
201 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800202 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700203
204 // user customized droiddoc args.
205 // Available variables for substitution:
206 //
207 // $(location <label>): the path to the arg_files with name <label>
Colin Crosse4a05842019-05-28 10:17:14 -0700208 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209 Args *string
210
211 // names of the output files used in args that will be generated
212 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800213}
214
Nan Zhang61819ce2018-05-04 18:49:16 -0700215type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900216 // path to the API txt file that the new API extracted from source code is checked
217 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800218 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700219
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900220 // path to the API txt file that the new @removed API extractd from source code is
221 // checked against. The path can be local to the module or from other module (via
222 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800223 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700224
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900225 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700226 Args *string
227}
228
Nan Zhang581fd212018-01-10 16:06:12 -0800229type DroiddocProperties struct {
230 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800231 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800232
Nan Zhanga40da042018-08-01 12:48:00 -0700233 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800234 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800235
236 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800237 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800238
239 // proofread file contains all of the text content of the javadocs concatenated into one file,
240 // suitable for spell-checking and other goodness.
Colin Cross27b922f2019-03-04 22:35:41 -0800241 Proofread_file *string `android:"path"`
Nan Zhang581fd212018-01-10 16:06:12 -0800242
243 // a todo file lists the program elements that are missing documentation.
244 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800245 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800246
247 // directory under current module source that provide additional resources (images).
248 Resourcesdir *string
249
250 // resources output directory under out/soong/.intermediates.
251 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800252
Nan Zhange2ba5d42018-07-11 15:16:55 -0700253 // if set to true, collect the values used by the Dev tools and
254 // write them in files packaged with the SDK. Defaults to false.
255 Write_sdk_values *bool
256
257 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800258 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700259
260 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800261 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700262
Nan Zhang581fd212018-01-10 16:06:12 -0800263 // a list of files under current module source dir which contains known tags in Java sources.
264 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800265 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700266
267 // the tag name used to distinguish if the API files belong to public/system/test.
268 Api_tag_name *string
269
270 // the generated public API filename by Doclava.
271 Api_filename *string
272
David Brazdilfbe4cc32018-05-31 13:56:46 +0100273 // the generated public Dex API filename by Doclava.
274 Dex_api_filename *string
275
Nan Zhang28c68b92018-03-13 16:17:01 -0700276 // the generated private API filename by Doclava.
277 Private_api_filename *string
278
279 // the generated private Dex API filename by Doclava.
280 Private_dex_api_filename *string
281
282 // the generated removed API filename by Doclava.
283 Removed_api_filename *string
284
David Brazdilaac0c3c2018-04-24 16:23:29 +0100285 // the generated removed Dex API filename by Doclava.
286 Removed_dex_api_filename *string
287
Mathew Inwood76c3de12018-06-22 15:28:11 +0100288 // mapping of dex signatures to source file and line number. This is a temporary property and
289 // will be deleted; you probably shouldn't be using it.
290 Dex_mapping_filename *string
291
Nan Zhang28c68b92018-03-13 16:17:01 -0700292 // the generated exact API filename by Doclava.
293 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700294
Nan Zhang66dc2362018-08-14 20:41:04 -0700295 // the generated proguard filename by Doclava.
296 Proguard_filename *string
297
Nan Zhang853f4202018-04-12 16:55:56 -0700298 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
299 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700300
301 Check_api struct {
302 Last_released ApiToCheck
303
304 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900305
306 // do not perform API check against Last_released, in the case that both two specified API
307 // files by Last_released are modules which don't exist.
308 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700309 }
Nan Zhang79614d12018-04-19 18:03:39 -0700310
Nan Zhang1598a9e2018-09-04 17:14:32 -0700311 // if set to true, generate docs through Dokka instead of Doclava.
312 Dokka_enabled *bool
313}
314
315type DroidstubsProperties struct {
316 // the tag name used to distinguish if the API files belong to public/system/test.
317 Api_tag_name *string
318
Nan Zhang199645c2018-09-19 12:40:06 -0700319 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700320 Api_filename *string
321
Nan Zhang199645c2018-09-19 12:40:06 -0700322 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700323 Dex_api_filename *string
324
Nan Zhang199645c2018-09-19 12:40:06 -0700325 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700326 Private_api_filename *string
327
Nan Zhang199645c2018-09-19 12:40:06 -0700328 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700329 Private_dex_api_filename *string
330
Nan Zhang199645c2018-09-19 12:40:06 -0700331 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700332 Removed_api_filename *string
333
Nan Zhang199645c2018-09-19 12:40:06 -0700334 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700335 Removed_dex_api_filename *string
336
Nan Zhang9c69a122018-08-22 10:22:08 -0700337 // mapping of dex signatures to source file and line number. This is a temporary property and
338 // will be deleted; you probably shouldn't be using it.
339 Dex_mapping_filename *string
340
Nan Zhang199645c2018-09-19 12:40:06 -0700341 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700342 Exact_api_filename *string
343
Nan Zhang199645c2018-09-19 12:40:06 -0700344 // the generated proguard filename by Metalava.
345 Proguard_filename *string
346
Nan Zhang1598a9e2018-09-04 17:14:32 -0700347 Check_api struct {
348 Last_released ApiToCheck
349
350 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900351
352 // do not perform API check against Last_released, in the case that both two specified API
353 // files by Last_released are modules which don't exist.
354 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700355 }
Nan Zhang79614d12018-04-19 18:03:39 -0700356
357 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800358 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700359
360 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700361 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700362
Pete Gillin77167902018-09-19 18:16:26 +0100363 // 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 -0700364 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700365
Pete Gillin77167902018-09-19 18:16:26 +0100366 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
367 Merge_inclusion_annotations_dirs []string
368
Pete Gillinc382a562018-11-14 18:45:46 +0000369 // a file containing a list of classes to do nullability validation for.
370 Validate_nullability_from_list *string
371
Pete Gillin581d6082018-10-22 15:55:04 +0100372 // a file containing expected warnings produced by validation of nullability annotations.
373 Check_nullability_warnings *string
374
Nan Zhang1598a9e2018-09-04 17:14:32 -0700375 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
376 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700377
378 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
379 Api_levels_annotations_enabled *bool
380
381 // the dirs which Metalava extracts API levels annotations from.
382 Api_levels_annotations_dirs []string
383
384 // if set to true, collect the values used by the Dev tools and
385 // write them in files packaged with the SDK. Defaults to false.
386 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700387
388 // If set to true, .xml based public API file will be also generated, and
389 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
390 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800391}
392
Nan Zhanga40da042018-08-01 12:48:00 -0700393//
394// Common flags passed down to build rule
395//
396type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700397 bootClasspathArgs string
398 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700399 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700400 dokkaClasspathArgs string
401 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700402 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700403
Nan Zhanga40da042018-08-01 12:48:00 -0700404 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700405 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700406 postDoclavaCmds string
407
Nan Zhang9c69a122018-08-22 10:22:08 -0700408 metalavaStubsFlags string
409 metalavaAnnotationsFlags string
Nan Zhangdee152b2018-12-26 16:06:37 -0800410 metalavaMergeAnnoDirFlags string
Neil Fullerb2f14ec2018-10-21 22:13:19 +0100411 metalavaInclusionAnnotationsFlags string
Nan Zhang9c69a122018-08-22 10:22:08 -0700412 metalavaApiLevelsAnnotationsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700413
Nan Zhang71bbe632018-09-17 14:32:21 -0700414 metalavaApiToXmlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700415}
416
417func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
418 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
419 android.InitDefaultableModule(module)
420}
421
Nan Zhang1598a9e2018-09-04 17:14:32 -0700422func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
423 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
424 return true
425 } else if String(apiToCheck.Api_file) != "" {
426 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
427 } else if String(apiToCheck.Removed_api_file) != "" {
428 panic("for " + apiVersionTag + " api_file has to be non-empty!")
429 }
430
431 return false
432}
433
Inseob Kim38449af2019-02-28 14:24:05 +0900434func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
435 api_file := String(apiToCheck.Api_file)
436 removed_api_file := String(apiToCheck.Removed_api_file)
437
438 api_module := android.SrcIsModule(api_file)
439 removed_api_module := android.SrcIsModule(removed_api_file)
440
441 if api_module == "" || removed_api_module == "" {
442 return
443 }
444
445 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
446 return
447 }
448
449 apiToCheck.Api_file = nil
450 apiToCheck.Removed_api_file = nil
451}
452
Nan Zhang1598a9e2018-09-04 17:14:32 -0700453type ApiFilePath interface {
454 ApiFilePath() android.Path
455}
456
457func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
458 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
459 ctx.Build(pctx, android.BuildParams{
460 Rule: updateApi,
461 Description: "Update API",
462 Output: output,
463 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
464 destApiFile, destRemovedApiFile),
465 Args: map[string]string{
466 "destApiFile": destApiFile.String(),
467 "srcApiFile": srcApiFile.String(),
468 "destRemovedApiFile": destRemovedApiFile.String(),
469 "srcRemovedApiFile": srcRemovedApiFile.String(),
470 },
471 })
472}
473
Nan Zhanga40da042018-08-01 12:48:00 -0700474//
475// Javadoc
476//
Nan Zhang581fd212018-01-10 16:06:12 -0800477type Javadoc struct {
478 android.ModuleBase
479 android.DefaultableModuleBase
480
481 properties JavadocProperties
482
483 srcJars android.Paths
484 srcFiles android.Paths
485 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700486 argFiles android.Paths
487
488 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800489
Nan Zhangccff0f72018-03-08 17:26:16 -0800490 docZip android.WritablePath
491 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800492}
493
Colin Cross41955e82019-05-29 14:40:35 -0700494func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
495 switch tag {
496 case "":
497 return android.Paths{j.stubsSrcJar}, nil
498 default:
499 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
500 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800501}
502
Colin Crossa3002fc2019-07-08 16:48:04 -0700503// javadoc converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800504func JavadocFactory() android.Module {
505 module := &Javadoc{}
506
507 module.AddProperties(&module.properties)
508
509 InitDroiddocModule(module, android.HostAndDeviceSupported)
510 return module
511}
512
Colin Crossa3002fc2019-07-08 16:48:04 -0700513// javadoc_host converts .java source files to documentation using javadoc.
Nan Zhang581fd212018-01-10 16:06:12 -0800514func JavadocHostFactory() android.Module {
515 module := &Javadoc{}
516
517 module.AddProperties(&module.properties)
518
519 InitDroiddocModule(module, android.HostSupported)
520 return module
521}
522
Colin Cross41955e82019-05-29 14:40:35 -0700523var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800524
Colin Cross83bb3162018-06-25 15:48:06 -0700525func (j *Javadoc) sdkVersion() string {
Jeongik Cha6bd33c12019-06-25 16:26:18 +0900526 return proptools.StringDefault(j.properties.Sdk_version, defaultSdkVersion(j))
Colin Cross83bb3162018-06-25 15:48:06 -0700527}
528
529func (j *Javadoc) minSdkVersion() string {
530 return j.sdkVersion()
531}
532
Dan Willemsen419290a2018-10-31 15:28:47 -0700533func (j *Javadoc) targetSdkVersion() string {
534 return j.sdkVersion()
535}
536
Nan Zhang581fd212018-01-10 16:06:12 -0800537func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
538 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100539 sdkDep := decodeSdkDep(ctx, sdkContext(j))
540 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700541 if sdkDep.useDefaultLibs {
542 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
543 if ctx.Config().TargetOpenJDK9() {
544 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
545 }
Paul Duffin250e6192019-06-07 10:44:37 +0100546 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700547 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
548 }
549 } else if sdkDep.useModule {
550 if ctx.Config().TargetOpenJDK9() {
551 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
552 }
553 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700554 }
Nan Zhang581fd212018-01-10 16:06:12 -0800555 }
556 }
557
Colin Cross42d48b72018-08-29 14:10:52 -0700558 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700559 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700560 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700561 }
Nan Zhang581fd212018-01-10 16:06:12 -0800562}
563
Nan Zhangb2b33de2018-02-23 11:18:47 -0800564func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
565 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
566 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900567 // convert foo.bar.baz to foo/bar/baz
568 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
569 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800570 if _, found := whitelistPathPrefixes[prefix]; !found {
571 whitelistPathPrefixes[prefix] = true
572 }
573 }
574 }
575}
576
Nan Zhanga40da042018-08-01 12:48:00 -0700577func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
578 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900579
Colin Cross3047fa22019-04-18 10:56:44 -0700580 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900581
582 return flags
583}
584
585func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700586 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900587
588 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
589 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
590
591 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700592 var deps android.Paths
593
Jiyong Park1e440682018-05-23 18:42:04 +0900594 if aidlPreprocess.Valid() {
595 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700596 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900597 } else {
598 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
599 }
600
601 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
602 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
603 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
604 flags = append(flags, "-I"+src.String())
605 }
606
Colin Cross3047fa22019-04-18 10:56:44 -0700607 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900608}
609
610func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700611 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900612
613 outSrcFiles := make(android.Paths, 0, len(srcFiles))
614
615 for _, srcFile := range srcFiles {
616 switch srcFile.Ext() {
617 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700618 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900619 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900620 case ".sysprop":
621 javaFile := genSysprop(ctx, srcFile)
622 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900623 default:
624 outSrcFiles = append(outSrcFiles, srcFile)
625 }
626 }
627
628 return outSrcFiles
629}
630
Nan Zhang581fd212018-01-10 16:06:12 -0800631func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
632 var deps deps
633
Colin Cross83bb3162018-06-25 15:48:06 -0700634 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800635 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700636 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800637 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700638 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800639 }
640
641 ctx.VisitDirectDeps(func(module android.Module) {
642 otherName := ctx.OtherModuleName(module)
643 tag := ctx.OtherModuleDependencyTag(module)
644
Colin Cross2d24c1b2018-05-23 10:59:18 -0700645 switch tag {
646 case bootClasspathTag:
647 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800648 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700649 } else {
650 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
651 }
652 case libTag:
653 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800654 case SdkLibraryDependency:
655 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700656 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900657 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700658 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800659 checkProducesJars(ctx, dep)
660 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800661 default:
662 ctx.ModuleErrorf("depends on non-java module %q", otherName)
663 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700664 case srcsLibTag:
665 switch dep := module.(type) {
666 case Dependency:
667 srcs := dep.(SrcDependency).CompiledSrcs()
668 whitelistPathPrefixes := make(map[string]bool)
669 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
670 for _, src := range srcs {
671 if _, ok := src.(android.WritablePath); ok { // generated sources
672 deps.srcs = append(deps.srcs, src)
673 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700674 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700675 if strings.HasPrefix(src.Rel(), k) {
676 deps.srcs = append(deps.srcs, src)
677 break
678 }
679 }
680 }
681 }
682 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
683 default:
684 ctx.ModuleErrorf("depends on non-java module %q", otherName)
685 }
Nan Zhang357466b2018-04-17 17:38:36 -0700686 case systemModulesTag:
687 if deps.systemModules != nil {
688 panic("Found two system module dependencies")
689 }
690 sm := module.(*SystemModules)
Dan Willemsenff60a732019-06-13 16:52:01 +0000691 if sm.outputDir == nil && len(sm.outputDeps) == 0 {
Nan Zhang357466b2018-04-17 17:38:36 -0700692 panic("Missing directory for system module dependency")
693 }
Dan Willemsenff60a732019-06-13 16:52:01 +0000694 deps.systemModules = sm.outputDir
695 deps.systemModulesDeps = sm.outputDeps
Nan Zhang581fd212018-01-10 16:06:12 -0800696 }
697 })
698 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
699 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800700 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700701 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900702 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800703
704 // srcs may depend on some genrule output.
705 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800706 j.srcJars = append(j.srcJars, deps.srcJars...)
707
Nan Zhang581fd212018-01-10 16:06:12 -0800708 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800709 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800710
711 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800712 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800713
Nan Zhang9c69a122018-08-22 10:22:08 -0700714 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800715 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
716 }
717 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800718
Colin Cross8a497952019-03-05 22:25:09 -0800719 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000720 argFilesMap := map[string]string{}
721 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700722
Paul Duffin99e4a502019-02-11 15:38:42 +0000723 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800724 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000725 if _, exists := argFilesMap[label]; !exists {
726 argFilesMap[label] = strings.Join(paths.Strings(), " ")
727 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700728 } else {
729 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000730 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700731 }
732 }
733
734 var err error
Colin Cross15638152019-07-11 11:11:35 -0700735 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
Nan Zhang1598a9e2018-09-04 17:14:32 -0700736 if strings.HasPrefix(name, "location ") {
737 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000738 if paths, ok := argFilesMap[label]; ok {
Colin Cross15638152019-07-11 11:11:35 -0700739 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700740 } else {
Colin Cross15638152019-07-11 11:11:35 -0700741 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000742 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700743 }
744 } else if name == "genDir" {
Colin Cross15638152019-07-11 11:11:35 -0700745 return android.PathForModuleGen(ctx).String(), nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700746 }
Colin Cross15638152019-07-11 11:11:35 -0700747 return "", fmt.Errorf("unknown variable '$(%s)'", name)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700748 })
749
750 if err != nil {
751 ctx.PropertyErrorf("args", "%s", err.Error())
752 }
753
Nan Zhang581fd212018-01-10 16:06:12 -0800754 return deps
755}
756
757func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
758 j.addDeps(ctx)
759}
760
761func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
762 deps := j.collectDeps(ctx)
763
764 var implicits android.Paths
765 implicits = append(implicits, deps.bootClasspath...)
766 implicits = append(implicits, deps.classpath...)
767
Nan Zhang1598a9e2018-09-04 17:14:32 -0700768 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700769
Colin Cross83bb3162018-06-25 15:48:06 -0700770 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700771 if len(deps.bootClasspath) > 0 {
772 var systemModules classpath
773 if deps.systemModules != nil {
774 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800775 }
Dan Willemsenff60a732019-06-13 16:52:01 +0000776 implicits = append(implicits, deps.systemModulesDeps...)
Colin Cross997262f2018-06-19 22:49:39 -0700777 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
778 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800779 }
780 if len(deps.classpath.Strings()) > 0 {
781 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
782 }
783
784 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700785 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800786
Nan Zhangaf322cc2018-06-19 15:15:38 -0700787 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800788
Nan Zhang1598a9e2018-09-04 17:14:32 -0700789 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
790
Nan Zhang581fd212018-01-10 16:06:12 -0800791 ctx.Build(pctx, android.BuildParams{
792 Rule: javadoc,
793 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800794 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800795 ImplicitOutput: j.docZip,
796 Inputs: j.srcFiles,
797 Implicits: implicits,
798 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700799 "outDir": android.PathForModuleOut(ctx, "out").String(),
800 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
801 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800802 "srcJars": strings.Join(j.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -0700803 "opts": proptools.NinjaEscape(opts),
Nan Zhang853f4202018-04-12 16:55:56 -0700804 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800805 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700806 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800807 "docZip": j.docZip.String(),
808 },
809 })
810}
811
Nan Zhanga40da042018-08-01 12:48:00 -0700812//
813// Droiddoc
814//
815type Droiddoc struct {
816 Javadoc
817
818 properties DroiddocProperties
819 apiFile android.WritablePath
820 dexApiFile android.WritablePath
821 privateApiFile android.WritablePath
822 privateDexApiFile android.WritablePath
823 removedApiFile android.WritablePath
824 removedDexApiFile android.WritablePath
825 exactApiFile android.WritablePath
826 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700827 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700828
829 checkCurrentApiTimestamp android.WritablePath
830 updateCurrentApiTimestamp android.WritablePath
831 checkLastReleasedApiTimestamp android.WritablePath
832
Nan Zhanga40da042018-08-01 12:48:00 -0700833 apiFilePath android.Path
834}
835
Colin Crossa3002fc2019-07-08 16:48:04 -0700836// droiddoc converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700837func DroiddocFactory() android.Module {
838 module := &Droiddoc{}
839
840 module.AddProperties(&module.properties,
841 &module.Javadoc.properties)
842
843 InitDroiddocModule(module, android.HostAndDeviceSupported)
844 return module
845}
846
Colin Crossa3002fc2019-07-08 16:48:04 -0700847// droiddoc_host converts .java source files to documentation using doclava or dokka.
Nan Zhanga40da042018-08-01 12:48:00 -0700848func DroiddocHostFactory() android.Module {
849 module := &Droiddoc{}
850
851 module.AddProperties(&module.properties,
852 &module.Javadoc.properties)
853
854 InitDroiddocModule(module, android.HostSupported)
855 return module
856}
857
858func (d *Droiddoc) ApiFilePath() android.Path {
859 return d.apiFilePath
860}
861
Nan Zhang581fd212018-01-10 16:06:12 -0800862func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
863 d.Javadoc.addDeps(ctx)
864
Inseob Kim38449af2019-02-28 14:24:05 +0900865 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
866 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
867 }
868
Nan Zhang79614d12018-04-19 18:03:39 -0700869 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800870 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
871 }
Nan Zhang581fd212018-01-10 16:06:12 -0800872}
873
Nan Zhang66dc2362018-08-14 20:41:04 -0700874func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
875 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700876 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800877
Nan Zhanga40da042018-08-01 12:48:00 -0700878 *implicits = append(*implicits, deps.bootClasspath...)
879 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800880
Nan Zhangc94f9d82018-06-26 10:02:26 -0700881 if len(deps.bootClasspath.Strings()) > 0 {
882 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700883 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700884 }
Nan Zhanga40da042018-08-01 12:48:00 -0700885 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700886 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700887 dokkaClasspath := classpath{}
888 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
889 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
890 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700891
Nan Zhang9c69a122018-08-22 10:22:08 -0700892 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
893 // based stubs generation.
894 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
895 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
896 // the correct package name base path.
897 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
898 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
899 } else {
900 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
901 }
Nan Zhang581fd212018-01-10 16:06:12 -0800902
Nan Zhanga40da042018-08-01 12:48:00 -0700903 return flags, nil
904}
Nan Zhang581fd212018-01-10 16:06:12 -0800905
Nan Zhanga40da042018-08-01 12:48:00 -0700906func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700907 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800908
Nan Zhanga40da042018-08-01 12:48:00 -0700909 *implicits = append(*implicits, jsilver)
910 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700911
Nan Zhang46130972018-06-04 11:28:01 -0700912 var date string
913 if runtime.GOOS == "darwin" {
914 date = `date -r`
915 } else {
916 date = `date -d`
917 }
918
Nan Zhang443fa522018-08-20 20:58:28 -0700919 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
920 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
921 // 1.9 language features.
922 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700923 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Colin Cross15638152019-07-11 11:11:35 -0700924 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
925 `-hdf page.now "$(` + date + ` @$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700926
Nan Zhanga40da042018-08-01 12:48:00 -0700927 if String(d.properties.Custom_template) == "" {
928 // TODO: This is almost always droiddoc-templates-sdk
929 ctx.PropertyErrorf("custom_template", "must specify a template")
930 }
931
932 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700933 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700934 *implicits = append(*implicits, t.deps...)
935 args = args + " -templatedir " + t.dir.String()
936 } else {
937 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
938 }
939 })
940
941 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800942 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800943 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800944 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700945 }
946
947 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800948 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800949 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800950 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700951 }
952
953 if len(d.properties.Html_dirs) > 2 {
954 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
955 }
956
Colin Cross8a497952019-03-05 22:25:09 -0800957 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700958 *implicits = append(*implicits, knownTags...)
959
960 for _, kt := range knownTags {
961 args = args + " -knowntags " + kt.String()
962 }
963
964 for _, hdf := range d.properties.Hdf {
965 args = args + " -hdf " + hdf
966 }
967
968 if String(d.properties.Proofread_file) != "" {
969 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
970 args = args + " -proofread " + proofreadFile.String()
971 }
972
973 if String(d.properties.Todo_file) != "" {
974 // tricky part:
975 // we should not compute full path for todo_file through PathForModuleOut().
976 // the non-standard doclet will get the full path relative to "-o".
977 args = args + " -todo " + String(d.properties.Todo_file)
978 }
979
980 if String(d.properties.Resourcesdir) != "" {
981 // TODO: should we add files under resourcesDir to the implicits? It seems that
982 // resourcesDir is one sub dir of htmlDir
983 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
984 args = args + " -resourcesdir " + resourcesDir.String()
985 }
986
987 if String(d.properties.Resourcesoutdir) != "" {
988 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
989 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
990 }
991 return args
992}
993
Nan Zhang1598a9e2018-09-04 17:14:32 -0700994func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
995 implicitOutputs *android.WritablePaths) string {
996 var doclavaFlags string
997 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
998 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
999 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001000 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1001 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001002 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1003 d.apiFilePath = d.apiFile
1004 }
1005
Nan Zhang1598a9e2018-09-04 17:14:32 -07001006 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1007 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1008 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001009 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1010 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001011 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1012 }
1013
1014 if String(d.properties.Private_api_filename) != "" {
1015 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1016 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001017 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1018 }
1019
1020 if String(d.properties.Dex_api_filename) != "" {
1021 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1022 doclavaFlags += " -dexApi " + d.dexApiFile.String()
1023 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1024 }
1025
1026 if String(d.properties.Private_dex_api_filename) != "" {
1027 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1028 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001029 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1030 }
1031
1032 if String(d.properties.Removed_dex_api_filename) != "" {
1033 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1034 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001035 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1036 }
1037
1038 if String(d.properties.Exact_api_filename) != "" {
1039 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1040 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001041 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1042 }
1043
1044 if String(d.properties.Dex_mapping_filename) != "" {
1045 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1046 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001047 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1048 }
1049
Nan Zhang66dc2362018-08-14 20:41:04 -07001050 if String(d.properties.Proguard_filename) != "" {
1051 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1052 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -07001053 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1054 }
1055
Nan Zhanga40da042018-08-01 12:48:00 -07001056 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001057 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001058 }
1059
1060 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001061 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001062 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001063
1064 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001065}
1066
1067func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1068 var cmds string
1069 if String(d.properties.Static_doc_index_redirect) != "" {
1070 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1071 "static_doc_index_redirect")
1072 *implicits = append(*implicits, static_doc_index_redirect)
1073 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001074 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001075 }
1076
1077 if String(d.properties.Static_doc_properties) != "" {
1078 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1079 "static_doc_properties")
1080 *implicits = append(*implicits, static_doc_properties)
1081 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001082 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001083 }
1084 return cmds
1085}
1086
Nan Zhang1598a9e2018-09-04 17:14:32 -07001087func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1088 implicitOutputs android.WritablePaths,
1089 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1090 ctx.Build(pctx, android.BuildParams{
1091 Rule: javadoc,
1092 Description: "Doclava",
1093 Output: d.Javadoc.stubsSrcJar,
1094 Inputs: d.Javadoc.srcFiles,
1095 Implicits: implicits,
1096 ImplicitOutputs: implicitOutputs,
1097 Args: map[string]string{
1098 "outDir": android.PathForModuleOut(ctx, "out").String(),
1099 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1100 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1101 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -07001102 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001103 "bootclasspathArgs": bootclasspathArgs,
1104 "classpathArgs": classpathArgs,
1105 "sourcepathArgs": sourcepathArgs,
1106 "docZip": d.Javadoc.docZip.String(),
1107 "postDoclavaCmds": postDoclavaCmds,
1108 },
1109 })
1110}
1111
1112func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1113 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1114 ctx.Build(pctx, android.BuildParams{
1115 Rule: apiCheck,
1116 Description: "Doclava Check API",
1117 Output: output,
1118 Inputs: nil,
1119 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1120 checkApiClasspath...),
1121 Args: map[string]string{
1122 "msg": msg,
1123 "classpath": checkApiClasspath.FormJavaClassPath(""),
Colin Cross15638152019-07-11 11:11:35 -07001124 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001125 "apiFile": apiFile.String(),
1126 "apiFileToCheck": d.apiFile.String(),
1127 "removedApiFile": removedApiFile.String(),
1128 "removedApiFileToCheck": d.removedApiFile.String(),
1129 },
1130 })
1131}
1132
1133func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1134 classpathArgs, opts string) {
1135 ctx.Build(pctx, android.BuildParams{
1136 Rule: dokka,
1137 Description: "Dokka",
1138 Output: d.Javadoc.stubsSrcJar,
1139 Inputs: d.Javadoc.srcFiles,
1140 Implicits: implicits,
1141 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001142 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1143 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1144 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001145 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1146 "classpathArgs": classpathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001147 "opts": proptools.NinjaEscape(opts),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001148 "docZip": d.Javadoc.docZip.String(),
1149 },
1150 })
1151}
1152
1153func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1154 deps := d.Javadoc.collectDeps(ctx)
1155
1156 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1157 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1158 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1159 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1160
1161 var implicits android.Paths
1162 implicits = append(implicits, d.Javadoc.srcJars...)
1163 implicits = append(implicits, d.Javadoc.argFiles...)
1164
1165 var implicitOutputs android.WritablePaths
1166 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1167 for _, o := range d.Javadoc.properties.Out {
1168 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1169 }
1170
1171 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1172 if err != nil {
1173 return
1174 }
1175
1176 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1177 if Bool(d.properties.Dokka_enabled) {
1178 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1179 } else {
1180 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1181 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1182 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1183 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1184 flags.postDoclavaCmds)
1185 }
1186
1187 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1188 !ctx.Config().IsPdkBuild() {
1189 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1190 "check_api.current.api_file")
1191 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1192 "check_api.current_removed_api_file")
1193
1194 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1195 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1196 fmt.Sprintf(`\n******************************\n`+
1197 `You have tried to change the API from what has been previously approved.\n\n`+
1198 `To make these errors go away, you have two choices:\n`+
1199 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1200 ` errors above.\n\n`+
1201 ` 2. You can update current.txt by executing the following command:\n`+
1202 ` make %s-update-current-api\n\n`+
1203 ` To submit the revised current.txt to the main Android repository,\n`+
1204 ` you will need approval.\n`+
1205 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1206 d.checkCurrentApiTimestamp)
1207
1208 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1209 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1210 d.updateCurrentApiTimestamp)
1211 }
1212
1213 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1214 !ctx.Config().IsPdkBuild() {
1215 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1216 "check_api.last_released.api_file")
1217 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1218 "check_api.last_released.removed_api_file")
1219
1220 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1221 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1222 `\n******************************\n`+
1223 `You have tried to change the API from what has been previously released in\n`+
1224 `an SDK. Please fix the errors listed above.\n`+
1225 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1226 d.checkLastReleasedApiTimestamp)
1227 }
1228}
1229
1230//
1231// Droidstubs
1232//
1233type Droidstubs struct {
1234 Javadoc
1235
Pete Gillin581d6082018-10-22 15:55:04 +01001236 properties DroidstubsProperties
1237 apiFile android.WritablePath
1238 apiXmlFile android.WritablePath
1239 lastReleasedApiXmlFile android.WritablePath
1240 dexApiFile android.WritablePath
1241 privateApiFile android.WritablePath
1242 privateDexApiFile android.WritablePath
1243 removedApiFile android.WritablePath
1244 removedDexApiFile android.WritablePath
1245 apiMappingFile android.WritablePath
1246 exactApiFile android.WritablePath
1247 proguardFile android.WritablePath
1248 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001249
1250 checkCurrentApiTimestamp android.WritablePath
1251 updateCurrentApiTimestamp android.WritablePath
1252 checkLastReleasedApiTimestamp android.WritablePath
1253
Pete Gillin581d6082018-10-22 15:55:04 +01001254 checkNullabilityWarningsTimestamp android.WritablePath
1255
Nan Zhang1598a9e2018-09-04 17:14:32 -07001256 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001257 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001258
1259 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001260
1261 jdiffDocZip android.WritablePath
1262 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001263}
1264
Colin Crossa3002fc2019-07-08 16:48:04 -07001265// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
1266// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
1267// a droiddoc module to generate documentation.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001268func DroidstubsFactory() android.Module {
1269 module := &Droidstubs{}
1270
1271 module.AddProperties(&module.properties,
1272 &module.Javadoc.properties)
1273
1274 InitDroiddocModule(module, android.HostAndDeviceSupported)
1275 return module
1276}
1277
Colin Crossa3002fc2019-07-08 16:48:04 -07001278// droidstubs_host passes sources files through Metalava to generate stub .java files that only contain the API
1279// to be documented, filtering out hidden classes and methods. The resulting .java files are intended to be
1280// passed to a droiddoc_host module to generate documentation. Use a droidstubs_host instead of a droidstubs
1281// module when symbols needed by the source files are provided by java_library_host modules.
Nan Zhang1598a9e2018-09-04 17:14:32 -07001282func DroidstubsHostFactory() android.Module {
1283 module := &Droidstubs{}
1284
1285 module.AddProperties(&module.properties,
1286 &module.Javadoc.properties)
1287
1288 InitDroiddocModule(module, android.HostSupported)
1289 return module
1290}
1291
1292func (d *Droidstubs) ApiFilePath() android.Path {
1293 return d.apiFilePath
1294}
1295
1296func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1297 d.Javadoc.addDeps(ctx)
1298
Inseob Kim38449af2019-02-28 14:24:05 +09001299 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1300 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1301 }
1302
Nan Zhang1598a9e2018-09-04 17:14:32 -07001303 if len(d.properties.Merge_annotations_dirs) != 0 {
1304 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1305 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1306 }
1307 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001308
Pete Gillin77167902018-09-19 18:16:26 +01001309 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1310 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1311 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1312 }
1313 }
1314
Nan Zhang9c69a122018-08-22 10:22:08 -07001315 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1316 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1317 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1318 }
1319 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001320}
1321
1322func (d *Droidstubs) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
1323 deps deps) (droiddocBuilderFlags, error) {
1324 var flags droiddocBuilderFlags
1325
1326 *implicits = append(*implicits, deps.bootClasspath...)
1327 *implicits = append(*implicits, deps.classpath...)
1328
1329 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
1330 // since it doesn't support system modules yet.
1331 if len(deps.bootClasspath.Strings()) > 0 {
1332 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
1333 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
1334 }
1335 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
1336
Sundong Ahn56dce442018-10-05 18:41:09 +09001337 flags.sourcepathArgs = "-sourcepath \"" + strings.Join(d.Javadoc.sourcepaths.Strings(), ":") + "\""
Nan Zhang1598a9e2018-09-04 17:14:32 -07001338 return flags, nil
1339}
1340
1341func (d *Droidstubs) collectStubsFlags(ctx android.ModuleContext,
1342 implicitOutputs *android.WritablePaths) string {
1343 var metalavaFlags string
1344 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1345 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1346 String(d.properties.Api_filename) != "" {
1347 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1348 metalavaFlags = metalavaFlags + " --api " + d.apiFile.String()
1349 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1350 d.apiFilePath = d.apiFile
1351 }
1352
1353 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1354 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1355 String(d.properties.Removed_api_filename) != "" {
1356 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1357 metalavaFlags = metalavaFlags + " --removed-api " + d.removedApiFile.String()
1358 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1359 }
1360
1361 if String(d.properties.Private_api_filename) != "" {
1362 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1363 metalavaFlags = metalavaFlags + " --private-api " + d.privateApiFile.String()
1364 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1365 }
1366
1367 if String(d.properties.Dex_api_filename) != "" {
1368 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1369 metalavaFlags += " --dex-api " + d.dexApiFile.String()
1370 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1371 }
1372
1373 if String(d.properties.Private_dex_api_filename) != "" {
1374 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1375 metalavaFlags = metalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
1376 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1377 }
1378
1379 if String(d.properties.Removed_dex_api_filename) != "" {
1380 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1381 metalavaFlags = metalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
1382 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1383 }
1384
1385 if String(d.properties.Exact_api_filename) != "" {
1386 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1387 metalavaFlags = metalavaFlags + " --exact-api " + d.exactApiFile.String()
1388 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1389 }
1390
Nan Zhang9c69a122018-08-22 10:22:08 -07001391 if String(d.properties.Dex_mapping_filename) != "" {
1392 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1393 metalavaFlags = metalavaFlags + " --dex-api-mapping " + d.apiMappingFile.String()
1394 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1395 }
1396
Nan Zhang199645c2018-09-19 12:40:06 -07001397 if String(d.properties.Proguard_filename) != "" {
1398 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1399 metalavaFlags += " --proguard " + d.proguardFile.String()
1400 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1401 }
1402
Nan Zhang9c69a122018-08-22 10:22:08 -07001403 if Bool(d.properties.Write_sdk_values) {
1404 metalavaFlags = metalavaFlags + " --sdk-values " + android.PathForModuleOut(ctx, "out").String()
1405 }
1406
Nan Zhang1598a9e2018-09-04 17:14:32 -07001407 if Bool(d.properties.Create_doc_stubs) {
1408 metalavaFlags += " --doc-stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1409 } else {
1410 metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1411 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001412 return metalavaFlags
1413}
1414
1415func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
Nan Zhangdee152b2018-12-26 16:06:37 -08001416 implicits *android.Paths, implicitOutputs *android.WritablePaths) (string, string) {
1417 var flags, mergeAnnoDirFlags string
Nan Zhang1598a9e2018-09-04 17:14:32 -07001418 if Bool(d.properties.Annotations_enabled) {
Pete Gillina262c052018-09-14 14:25:48 +01001419 flags += " --include-annotations"
Pete Gillinc382a562018-11-14 18:45:46 +00001420 validatingNullability :=
1421 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1422 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001423 migratingNullability := String(d.properties.Previous_api) != ""
1424 if !(migratingNullability || validatingNullability) {
1425 ctx.PropertyErrorf("previous_api",
1426 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001427 }
Pete Gillina262c052018-09-14 14:25:48 +01001428 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001429 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Pete Gillina262c052018-09-14 14:25:48 +01001430 *implicits = append(*implicits, previousApi)
1431 flags += " --migrate-nullness " + previousApi.String()
1432 }
Pete Gillinc382a562018-11-14 18:45:46 +00001433 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross8a497952019-03-05 22:25:09 -08001434 flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
Pete Gillinc382a562018-11-14 18:45:46 +00001435 }
Pete Gillina262c052018-09-14 14:25:48 +01001436 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001437 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
1438 *implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
1439 flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
Pete Gillina262c052018-09-14 14:25:48 +01001440 }
Nan Zhanga40da042018-08-01 12:48:00 -07001441
1442 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
1443 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
1444
Nan Zhangf4936b02018-08-01 15:00:28 -07001445 flags += " --extract-annotations " + d.annotationsZip.String()
1446
Nan Zhang1598a9e2018-09-04 17:14:32 -07001447 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001448 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001449 "has to be non-empty if annotations was enabled!")
1450 }
Nan Zhangf4936b02018-08-01 15:00:28 -07001451 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1452 if t, ok := m.(*ExportedDroiddocDir); ok {
1453 *implicits = append(*implicits, t.deps...)
Nan Zhangdee152b2018-12-26 16:06:37 -08001454 mergeAnnoDirFlags += " --merge-qualifier-annotations " + t.dir.String()
Nan Zhangf4936b02018-08-01 15:00:28 -07001455 } else {
Nan Zhang9c69a122018-08-22 10:22:08 -07001456 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhangf4936b02018-08-01 15:00:28 -07001457 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1458 }
1459 })
Nan Zhangdee152b2018-12-26 16:06:37 -08001460 flags += mergeAnnoDirFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001461 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001462 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
Nan Zhanga40da042018-08-01 12:48:00 -07001463 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001464
Nan Zhangdee152b2018-12-26 16:06:37 -08001465 return flags, mergeAnnoDirFlags
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001466}
1467
1468func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
1469 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1470 var flags string
Pete Gillin77167902018-09-19 18:16:26 +01001471 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1472 if t, ok := m.(*ExportedDroiddocDir); ok {
1473 *implicits = append(*implicits, t.deps...)
1474 flags += " --merge-inclusion-annotations " + t.dir.String()
1475 } else {
1476 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1477 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1478 }
1479 })
Nan Zhanga40da042018-08-01 12:48:00 -07001480
1481 return flags
1482}
1483
Nan Zhang9c69a122018-08-22 10:22:08 -07001484func (d *Droidstubs) collectAPILevelsAnnotationsFlags(ctx android.ModuleContext,
1485 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1486 var flags string
1487 if Bool(d.properties.Api_levels_annotations_enabled) {
1488 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1489 *implicitOutputs = append(*implicitOutputs, d.apiVersionsXml)
1490
1491 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1492 ctx.PropertyErrorf("api_levels_annotations_dirs",
1493 "has to be non-empty if api levels annotations was enabled!")
1494 }
1495
1496 flags = " --generate-api-levels " + d.apiVersionsXml.String() + " --apply-api-levels " +
1497 d.apiVersionsXml.String() + " --current-version " + ctx.Config().PlatformSdkVersion() +
1498 " --current-codename " + ctx.Config().PlatformSdkCodename() + " "
1499
1500 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1501 if t, ok := m.(*ExportedDroiddocDir); ok {
1502 var androidJars android.Paths
1503 for _, dep := range t.deps {
1504 if strings.HasSuffix(dep.String(), "android.jar") {
1505 androidJars = append(androidJars, dep)
1506 }
1507 }
1508 *implicits = append(*implicits, androidJars...)
Tor Norbyeebcdfed2019-01-24 11:05:46 -08001509 flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
Nan Zhang9c69a122018-08-22 10:22:08 -07001510 } else {
1511 ctx.PropertyErrorf("api_levels_annotations_dirs",
1512 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1513 }
1514 })
1515
1516 }
1517
1518 return flags
1519}
1520
Nan Zhang71bbe632018-09-17 14:32:21 -07001521func (d *Droidstubs) collectApiToXmlFlags(ctx android.ModuleContext, implicits *android.Paths,
1522 implicitOutputs *android.WritablePaths) string {
1523 var flags string
1524 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1525 if d.apiFile.String() == "" {
1526 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1527 }
1528
1529 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
1530 *implicitOutputs = append(*implicitOutputs, d.apiXmlFile)
1531
1532 flags = " --api-xml " + d.apiXmlFile.String()
1533
1534 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1535 ctx.PropertyErrorf("check_api.last_released.api_file",
1536 "has to be non-empty if jdiff was enabled!")
1537 }
1538 lastReleasedApi := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1539 "check_api.last_released.api_file")
1540 *implicits = append(*implicits, lastReleasedApi)
1541
1542 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
1543 *implicitOutputs = append(*implicitOutputs, d.lastReleasedApiXmlFile)
1544
1545 flags += " --convert-to-jdiff " + lastReleasedApi.String() + " " +
1546 d.lastReleasedApiXmlFile.String()
1547 }
1548
1549 return flags
1550}
1551
Nan Zhang1598a9e2018-09-04 17:14:32 -07001552func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
1553 implicitOutputs android.WritablePaths, javaVersion,
1554 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001555
Nan Zhang86d2d552018-08-09 15:33:27 -07001556 ctx.Build(pctx, android.BuildParams{
1557 Rule: metalava,
1558 Description: "Metalava",
1559 Output: d.Javadoc.stubsSrcJar,
1560 Inputs: d.Javadoc.srcFiles,
1561 Implicits: implicits,
1562 ImplicitOutputs: implicitOutputs,
1563 Args: map[string]string{
Nan Zhang86d2d552018-08-09 15:33:27 -07001564 "outDir": android.PathForModuleOut(ctx, "out").String(),
1565 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1566 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1567 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001568 "javaVersion": javaVersion,
Nan Zhang86d2d552018-08-09 15:33:27 -07001569 "bootclasspathArgs": bootclasspathArgs,
1570 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001571 "sourcepathArgs": sourcepathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001572 "opts": proptools.NinjaEscape(opts),
Nan Zhang86d2d552018-08-09 15:33:27 -07001573 },
1574 })
1575}
1576
Nan Zhang1598a9e2018-09-04 17:14:32 -07001577func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
1578 apiFile, removedApiFile android.Path, implicits android.Paths,
Colin Cross39c16792019-01-24 16:32:44 -08001579 javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001580 output android.WritablePath) {
1581 ctx.Build(pctx, android.BuildParams{
1582 Rule: metalavaApiCheck,
1583 Description: "Metalava Check API",
1584 Output: output,
1585 Inputs: d.Javadoc.srcFiles,
1586 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1587 implicits...),
1588 Args: map[string]string{
Colin Cross39c16792019-01-24 16:32:44 -08001589 "srcJarDir": android.PathForModuleOut(ctx, subdir, "srcjars").String(),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001590 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1591 "javaVersion": javaVersion,
1592 "bootclasspathArgs": bootclasspathArgs,
1593 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001594 "sourcepathArgs": sourcepathArgs,
Colin Cross15638152019-07-11 11:11:35 -07001595 "opts": proptools.NinjaEscape(opts),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001596 "msg": msg,
1597 },
1598 })
1599}
1600
Nan Zhang71bbe632018-09-17 14:32:21 -07001601func (d *Droidstubs) transformJdiff(ctx android.ModuleContext, implicits android.Paths,
1602 implicitOutputs android.WritablePaths,
1603 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
1604 ctx.Build(pctx, android.BuildParams{
1605 Rule: javadoc,
1606 Description: "Jdiff",
1607 Output: d.jdiffStubsSrcJar,
1608 Inputs: d.Javadoc.srcFiles,
1609 Implicits: implicits,
1610 ImplicitOutputs: implicitOutputs,
1611 Args: map[string]string{
Nan Zhang23a1ba62018-09-19 11:19:39 -07001612 "outDir": android.PathForModuleOut(ctx, "jdiff-out").String(),
1613 "srcJarDir": android.PathForModuleOut(ctx, "jdiff-srcjars").String(),
1614 "stubsDir": android.PathForModuleOut(ctx, "jdiff-stubsDir").String(),
Nan Zhang71bbe632018-09-17 14:32:21 -07001615 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Colin Cross15638152019-07-11 11:11:35 -07001616 "opts": proptools.NinjaEscape(opts),
Nan Zhang71bbe632018-09-17 14:32:21 -07001617 "bootclasspathArgs": bootclasspathArgs,
1618 "classpathArgs": classpathArgs,
1619 "sourcepathArgs": sourcepathArgs,
1620 "docZip": d.jdiffDocZip.String(),
1621 },
1622 })
1623}
1624
Nan Zhang1598a9e2018-09-04 17:14:32 -07001625func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001626 deps := d.Javadoc.collectDeps(ctx)
1627
1628 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001629
Nan Zhanga40da042018-08-01 12:48:00 -07001630 var implicits android.Paths
1631 implicits = append(implicits, d.Javadoc.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001632 implicits = append(implicits, d.Javadoc.argFiles...)
Nan Zhanga40da042018-08-01 12:48:00 -07001633
1634 var implicitOutputs android.WritablePaths
Nan Zhang1598a9e2018-09-04 17:14:32 -07001635 for _, o := range d.Javadoc.properties.Out {
Nan Zhanga40da042018-08-01 12:48:00 -07001636 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1637 }
1638
1639 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
Nan Zhang2760dfc2018-08-24 17:32:54 +00001640 metalavaCheckApiImplicits := implicits
Nan Zhang71bbe632018-09-17 14:32:21 -07001641 jdiffImplicits := implicits
1642
Nan Zhanga40da042018-08-01 12:48:00 -07001643 if err != nil {
1644 return
1645 }
1646
Nan Zhang1598a9e2018-09-04 17:14:32 -07001647 flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
Nan Zhangdee152b2018-12-26 16:06:37 -08001648 flags.metalavaAnnotationsFlags, flags.metalavaMergeAnnoDirFlags =
1649 d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001650 flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang9c69a122018-08-22 10:22:08 -07001651 flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang71bbe632018-09-17 14:32:21 -07001652 flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
1653
Nan Zhang1598a9e2018-09-04 17:14:32 -07001654 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1655 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1656 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1657 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1658 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001659 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001660 d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
1661 flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001662 flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
Nan Zhang71bbe632018-09-17 14:32:21 -07001663 flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
Nan Zhang61819ce2018-05-04 18:49:16 -07001664
Nan Zhang1598a9e2018-09-04 17:14:32 -07001665 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1666 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001667 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1668 "check_api.current.api_file")
1669 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1670 "check_api.current_removed_api_file")
1671
Nan Zhang2760dfc2018-08-24 17:32:54 +00001672 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001673 opts := " " + d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
1674 " --check-compatibility:removed:current " + removedApiFile.String() +
Nan Zhangdee152b2018-12-26 16:06:37 -08001675 flags.metalavaInclusionAnnotationsFlags + flags.metalavaMergeAnnoDirFlags + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001676
Nan Zhang1598a9e2018-09-04 17:14:32 -07001677 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001678 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001679 fmt.Sprintf(`\n******************************\n`+
1680 `You have tried to change the API from what has been previously approved.\n\n`+
1681 `To make these errors go away, you have two choices:\n`+
1682 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1683 ` errors above.\n\n`+
1684 ` 2. You can update current.txt by executing the following command:\n`+
1685 ` make %s-update-current-api\n\n`+
1686 ` To submit the revised current.txt to the main Android repository,\n`+
1687 ` you will need approval.\n`+
1688 `******************************\n`, ctx.ModuleName()),
1689 d.checkCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001690
1691 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001692 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1693 d.updateCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001694 }
Nan Zhanga40da042018-08-01 12:48:00 -07001695
Nan Zhang1598a9e2018-09-04 17:14:32 -07001696 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1697 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001698 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1699 "check_api.last_released.api_file")
1700 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1701 "check_api.last_released.removed_api_file")
1702
Nan Zhang2760dfc2018-08-24 17:32:54 +00001703 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001704 opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
1705 flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
Nan Zhangdee152b2018-12-26 16:06:37 -08001706 removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001707
Nan Zhang1598a9e2018-09-04 17:14:32 -07001708 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001709 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001710 `\n******************************\n`+
1711 `You have tried to change the API from what has been previously released in\n`+
1712 `an SDK. Please fix the errors listed above.\n`+
1713 `******************************\n`,
1714 d.checkLastReleasedApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001715 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001716
Pete Gillin581d6082018-10-22 15:55:04 +01001717 if String(d.properties.Check_nullability_warnings) != "" {
1718 if d.nullabilityWarningsFile == nil {
1719 ctx.PropertyErrorf("check_nullability_warnings",
1720 "Cannot specify check_nullability_warnings unless validating nullability")
1721 }
1722 checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
1723 "check_nullability_warnings")
1724 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
1725 msg := fmt.Sprintf(`\n******************************\n`+
1726 `The warnings encountered during nullability annotation validation did\n`+
1727 `not match the checked in file of expected warnings. The diffs are shown\n`+
1728 `above. You have two options:\n`+
1729 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1730 ` 2. Update the file of expected warnings by running:\n`+
1731 ` cp %s %s\n`+
1732 ` and submitting the updated file as part of your change.`,
1733 d.nullabilityWarningsFile, checkNullabilityWarnings)
1734 ctx.Build(pctx, android.BuildParams{
1735 Rule: nullabilityWarningsCheck,
1736 Description: "Nullability Warnings Check",
1737 Output: d.checkNullabilityWarningsTimestamp,
1738 Implicits: android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
1739 Args: map[string]string{
1740 "expected": checkNullabilityWarnings.String(),
1741 "actual": d.nullabilityWarningsFile.String(),
1742 "msg": msg,
1743 },
1744 })
1745 }
1746
Nan Zhang71bbe632018-09-17 14:32:21 -07001747 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1748
Nan Zhang86b06202018-09-21 17:09:21 -07001749 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1750 // since there's cron job downstream that fetch this .zip file periodically.
1751 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001752 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1753 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1754
1755 var jdiffImplicitOutputs android.WritablePaths
1756 jdiffImplicitOutputs = append(jdiffImplicitOutputs, d.jdiffDocZip)
1757
1758 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
1759 jdiffImplicits = append(jdiffImplicits, android.Paths{jdiff, d.apiXmlFile, d.lastReleasedApiXmlFile}...)
1760
Pete Gillin2b1ea2e2019-06-10 14:20:11 +01001761 opts := " -source 1.8 -J-Xmx1600m -XDignore.symbol.file " +
Nan Zhang71bbe632018-09-17 14:32:21 -07001762 "-doclet jdiff.JDiff -docletpath " + jdiff.String() + " -quiet " +
1763 "-newapi " + strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext()) +
1764 " -newapidir " + filepath.Dir(d.apiXmlFile.String()) +
1765 " -oldapi " + strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext()) +
1766 " -oldapidir " + filepath.Dir(d.lastReleasedApiXmlFile.String())
1767
1768 d.transformJdiff(ctx, jdiffImplicits, jdiffImplicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1769 flags.sourcepathArgs, opts)
1770 }
Nan Zhang581fd212018-01-10 16:06:12 -08001771}
Dan Willemsencc090972018-02-26 14:33:31 -08001772
Nan Zhanga40da042018-08-01 12:48:00 -07001773//
Nan Zhangf4936b02018-08-01 15:00:28 -07001774// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001775//
Dan Willemsencc090972018-02-26 14:33:31 -08001776var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001777var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001778var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001779var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001780
Nan Zhangf4936b02018-08-01 15:00:28 -07001781type ExportedDroiddocDirProperties struct {
1782 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001783 Path *string
1784}
1785
Nan Zhangf4936b02018-08-01 15:00:28 -07001786type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001787 android.ModuleBase
1788
Nan Zhangf4936b02018-08-01 15:00:28 -07001789 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001790
1791 deps android.Paths
1792 dir android.Path
1793}
1794
Colin Crossa3002fc2019-07-08 16:48:04 -07001795// droiddoc_exported_dir exports a directory of html templates or nullability annotations for use by doclava.
Nan Zhangf4936b02018-08-01 15:00:28 -07001796func ExportedDroiddocDirFactory() android.Module {
1797 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001798 module.AddProperties(&module.properties)
1799 android.InitAndroidModule(module)
1800 return module
1801}
1802
Nan Zhangf4936b02018-08-01 15:00:28 -07001803func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001804
Nan Zhangf4936b02018-08-01 15:00:28 -07001805func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001806 path := String(d.properties.Path)
1807 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001808 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001809}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001810
1811//
1812// Defaults
1813//
1814type DocDefaults struct {
1815 android.ModuleBase
1816 android.DefaultsModuleBase
1817}
1818
Nan Zhangb2b33de2018-02-23 11:18:47 -08001819func DocDefaultsFactory() android.Module {
1820 module := &DocDefaults{}
1821
1822 module.AddProperties(
1823 &JavadocProperties{},
1824 &DroiddocProperties{},
1825 )
1826
1827 android.InitDefaultsModule(module)
1828
1829 return module
1830}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001831
1832func StubsDefaultsFactory() android.Module {
1833 module := &DocDefaults{}
1834
1835 module.AddProperties(
1836 &JavadocProperties{},
1837 &DroidstubsProperties{},
1838 )
1839
1840 android.InitDefaultsModule(module)
1841
1842 return module
1843}