blob: e163617e8f61dfb3ecf98c82911a996b23baae0e [file] [log] [blame]
Nan Zhang581fd212018-01-10 16:06:12 -08001// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package java
16
17import (
18 "android/soong/android"
19 "android/soong/java/config"
20 "fmt"
Nan Zhangb2b33de2018-02-23 11:18:47 -080021 "path/filepath"
Nan Zhang46130972018-06-04 11:28:01 -070022 "runtime"
Nan Zhang581fd212018-01-10 16:06:12 -080023 "strings"
24
25 "github.com/google/blueprint"
26)
27
28var (
29 javadoc = pctx.AndroidStaticRule("javadoc",
30 blueprint.RuleParams{
31 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Colin Cross436b7652018-03-15 16:24:10 -070032 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang40b41b42018-10-02 16:11:17 -070033 `${config.SoongJavacWrapper} ${config.JavadocCmd} -encoding UTF-8 @$out.rsp @$srcJarDir/list ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070034 `$opts $bootclasspathArgs $classpathArgs $sourcepathArgs ` +
Nan Zhang581fd212018-01-10 16:06:12 -080035 `-d $outDir -quiet && ` +
36 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080037 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir $postDoclavaCmds && ` +
38 `rm -rf "$srcJarDir"`,
39
Nan Zhang581fd212018-01-10 16:06:12 -080040 CommandDeps: []string{
Colin Cross436b7652018-03-15 16:24:10 -070041 "${config.ZipSyncCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080042 "${config.JavadocCmd}",
43 "${config.SoongZipCmd}",
Nan Zhang581fd212018-01-10 16:06:12 -080044 },
Nan Zhang40b41b42018-10-02 16:11:17 -070045 CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
46 Rspfile: "$out.rsp",
47 RspfileContent: "$in",
48 Restat: true,
Nan Zhang581fd212018-01-10 16:06:12 -080049 },
Nan Zhangaf322cc2018-06-19 15:15:38 -070050 "outDir", "srcJarDir", "stubsDir", "srcJars", "opts",
Nan Zhang1598a9e2018-09-04 17:14:32 -070051 "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "docZip", "postDoclavaCmds")
Nan Zhang61819ce2018-05-04 18:49:16 -070052
53 apiCheck = pctx.AndroidStaticRule("apiCheck",
54 blueprint.RuleParams{
55 Command: `( ${config.ApiCheckCmd} -JXmx1024m -J"classpath $classpath" $opts ` +
56 `$apiFile $apiFileToCheck $removedApiFile $removedApiFileToCheck ` +
Jiyong Parkeeb8a642018-05-12 22:21:20 +090057 `&& touch $out ) || (echo -e "$msg" ; exit 38)`,
Nan Zhang61819ce2018-05-04 18:49:16 -070058 CommandDeps: []string{
59 "${config.ApiCheckCmd}",
60 },
61 },
62 "classpath", "opts", "apiFile", "apiFileToCheck", "removedApiFile", "removedApiFileToCheck", "msg")
63
64 updateApi = pctx.AndroidStaticRule("updateApi",
65 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070066 Command: `( ( cp -f $srcApiFile $destApiFile && cp -f $srcRemovedApiFile $destRemovedApiFile ) ` +
Nan Zhang61819ce2018-05-04 18:49:16 -070067 `&& touch $out ) || (echo failed to update public API ; exit 38)`,
68 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070069 "srcApiFile", "destApiFile", "srcRemovedApiFile", "destRemovedApiFile")
Nan Zhang79614d12018-04-19 18:03:39 -070070
71 metalava = pctx.AndroidStaticRule("metalava",
72 blueprint.RuleParams{
Nan Zhang1598a9e2018-09-04 17:14:32 -070073 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
74 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
Nan Zhang79614d12018-04-19 18:03:39 -070075 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
Nan Zhang357466b2018-04-17 17:38:36 -070076 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -080077 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -070078 `$opts && ` +
Colin Cross44c29a82019-01-24 16:36:57 -080079 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
80 `rm -rf "$srcJarDir"`,
Nan Zhang79614d12018-04-19 18:03:39 -070081 CommandDeps: []string{
82 "${config.ZipSyncCmd}",
83 "${config.JavaCmd}",
84 "${config.MetalavaJar}",
Nan Zhang79614d12018-04-19 18:03:39 -070085 "${config.SoongZipCmd}",
86 },
87 Rspfile: "$out.rsp",
88 RspfileContent: "$in",
89 Restat: true,
90 },
Nan Zhang1598a9e2018-09-04 17:14:32 -070091 "outDir", "srcJarDir", "stubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
92 "classpathArgs", "sourcepathArgs", "opts")
Nan Zhang2760dfc2018-08-24 17:32:54 +000093
94 metalavaApiCheck = pctx.AndroidStaticRule("metalavaApiCheck",
95 blueprint.RuleParams{
96 Command: `( rm -rf "$srcJarDir" && mkdir -p "$srcJarDir" && ` +
97 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
98 `${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
Tor Norbye76c875a2018-12-26 20:34:29 -080099 `$bootclasspathArgs $classpathArgs $sourcepathArgs --no-banner --color --quiet --format=v2 ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800100 `$opts && touch $out && rm -rf "$srcJarDir") || ` +
Nan Zhang2760dfc2018-08-24 17:32:54 +0000101 `( echo -e "$msg" ; exit 38 )`,
102 CommandDeps: []string{
103 "${config.ZipSyncCmd}",
104 "${config.JavaCmd}",
105 "${config.MetalavaJar}",
106 },
107 Rspfile: "$out.rsp",
108 RspfileContent: "$in",
109 },
Nan Zhang1598a9e2018-09-04 17:14:32 -0700110 "srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg")
111
Pete Gillin581d6082018-10-22 15:55:04 +0100112 nullabilityWarningsCheck = pctx.AndroidStaticRule("nullabilityWarningsCheck",
113 blueprint.RuleParams{
114 Command: `( diff $expected $actual && touch $out ) || ( echo -e "$msg" ; exit 38 )`,
115 },
116 "expected", "actual", "msg")
117
Nan Zhang1598a9e2018-09-04 17:14:32 -0700118 dokka = pctx.AndroidStaticRule("dokka",
119 blueprint.RuleParams{
120 Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
121 `mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
122 `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
123 `${config.JavaCmd} -jar ${config.DokkaJar} $srcJarDir ` +
124 `$classpathArgs -format dac -dacRoot /reference/kotlin -output $outDir $opts && ` +
125 `${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
Colin Cross44c29a82019-01-24 16:36:57 -0800126 `${config.SoongZipCmd} -write_if_changed -jar -o $out -C $stubsDir -D $stubsDir && ` +
127 `rm -rf "$srcJarDir"`,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700128 CommandDeps: []string{
129 "${config.ZipSyncCmd}",
130 "${config.DokkaJar}",
131 "${config.MetalavaJar}",
132 "${config.SoongZipCmd}",
133 },
134 Restat: true,
135 },
136 "outDir", "srcJarDir", "stubsDir", "srcJars", "classpathArgs", "opts", "docZip")
Nan Zhang581fd212018-01-10 16:06:12 -0800137)
138
139func init() {
Nan Zhangb2b33de2018-02-23 11:18:47 -0800140 android.RegisterModuleType("doc_defaults", DocDefaultsFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700141 android.RegisterModuleType("stubs_defaults", StubsDefaultsFactory)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800142
Nan Zhang581fd212018-01-10 16:06:12 -0800143 android.RegisterModuleType("droiddoc", DroiddocFactory)
144 android.RegisterModuleType("droiddoc_host", DroiddocHostFactory)
Nan Zhangf4936b02018-08-01 15:00:28 -0700145 android.RegisterModuleType("droiddoc_exported_dir", ExportedDroiddocDirFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800146 android.RegisterModuleType("javadoc", JavadocFactory)
147 android.RegisterModuleType("javadoc_host", JavadocHostFactory)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700148
149 android.RegisterModuleType("droidstubs", DroidstubsFactory)
150 android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
Nan Zhang581fd212018-01-10 16:06:12 -0800151}
152
Colin Crossa1ce2a02018-06-20 15:19:39 -0700153var (
154 srcsLibTag = dependencyTag{name: "sources from javalib"}
155)
156
Nan Zhang581fd212018-01-10 16:06:12 -0800157type JavadocProperties struct {
158 // list of source files used to compile the Java module. May be .java, .logtags, .proto,
159 // or .aidl files.
Colin Cross27b922f2019-03-04 22:35:41 -0800160 Srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800161
162 // list of directories rooted at the Android.bp file that will
163 // be added to the search paths for finding source files when passing package names.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800164 Local_sourcepaths []string
Nan Zhang581fd212018-01-10 16:06:12 -0800165
166 // list of source files that should not be used to build the Java module.
167 // This is most useful in the arch/multilib variants to remove non-common files
168 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800169 Exclude_srcs []string `android:"path,arch_variant"`
Nan Zhang581fd212018-01-10 16:06:12 -0800170
Nan Zhangb2b33de2018-02-23 11:18:47 -0800171 // list of java libraries that will be in the classpath.
Nan Zhang581fd212018-01-10 16:06:12 -0800172 Libs []string `android:"arch_variant"`
173
Paul Duffin2fbbfb82019-02-13 12:49:33 +0000174 // don't build against the default libraries (bootclasspath, ext, and framework for device
175 // targets)
Nan Zhang5994b622018-09-21 16:39:51 -0700176 No_standard_libs *bool
177
Paul Duffin2fbbfb82019-02-13 12:49:33 +0000178 // don't build against the framework libraries (ext, and framework for device targets)
Nan Zhange66c7272018-03-06 12:59:27 -0800179 No_framework_libs *bool
180
Nan Zhangb2b33de2018-02-23 11:18:47 -0800181 // the java library (in classpath) for documentation that provides java srcs and srcjars.
182 Srcs_lib *string
183
184 // the base dirs under srcs_lib will be scanned for java srcs.
185 Srcs_lib_whitelist_dirs []string
186
187 // the sub dirs under srcs_lib_whitelist_dirs will be scanned for java srcs.
188 Srcs_lib_whitelist_pkgs []string
189
Nan Zhang581fd212018-01-10 16:06:12 -0800190 // If set to false, don't allow this module(-docs.zip) to be exported. Defaults to true.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800191 Installable *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800192
193 // if not blank, set to the version of the sdk to compile against
194 Sdk_version *string `android:"arch_variant"`
Jiyong Park1e440682018-05-23 18:42:04 +0900195
196 Aidl struct {
197 // Top level directories to pass to aidl tool
198 Include_dirs []string
199
200 // Directories rooted at the Android.bp file to pass to aidl tool
201 Local_include_dirs []string
202 }
Nan Zhang357466b2018-04-17 17:38:36 -0700203
204 // If not blank, set the java version passed to javadoc as -source
205 Java_version *string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700206
207 // local files that are used within user customized droiddoc options.
Colin Cross27b922f2019-03-04 22:35:41 -0800208 Arg_files []string `android:"path"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700209
210 // user customized droiddoc args.
211 // Available variables for substitution:
212 //
213 // $(location <label>): the path to the arg_files with name <label>
214 Args *string
215
216 // names of the output files used in args that will be generated
217 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800218}
219
Nan Zhang61819ce2018-05-04 18:49:16 -0700220type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900221 // path to the API txt file that the new API extracted from source code is checked
222 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800223 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700224
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900225 // path to the API txt file that the new @removed API extractd from source code is
226 // checked against. The path can be local to the module or from other module (via
227 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800228 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700229
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900230 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700231 Args *string
232}
233
Nan Zhang581fd212018-01-10 16:06:12 -0800234type DroiddocProperties struct {
235 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800236 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800237
Nan Zhanga40da042018-08-01 12:48:00 -0700238 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800239 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800240
241 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800242 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800243
244 // proofread file contains all of the text content of the javadocs concatenated into one file,
245 // suitable for spell-checking and other goodness.
Colin Cross27b922f2019-03-04 22:35:41 -0800246 Proofread_file *string `android:"path"`
Nan Zhang581fd212018-01-10 16:06:12 -0800247
248 // a todo file lists the program elements that are missing documentation.
249 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800250 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800251
252 // directory under current module source that provide additional resources (images).
253 Resourcesdir *string
254
255 // resources output directory under out/soong/.intermediates.
256 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800257
Nan Zhange2ba5d42018-07-11 15:16:55 -0700258 // if set to true, collect the values used by the Dev tools and
259 // write them in files packaged with the SDK. Defaults to false.
260 Write_sdk_values *bool
261
262 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800263 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700264
265 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800266 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700267
Nan Zhang581fd212018-01-10 16:06:12 -0800268 // a list of files under current module source dir which contains known tags in Java sources.
269 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800270 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700271
272 // the tag name used to distinguish if the API files belong to public/system/test.
273 Api_tag_name *string
274
275 // the generated public API filename by Doclava.
276 Api_filename *string
277
David Brazdilfbe4cc32018-05-31 13:56:46 +0100278 // the generated public Dex API filename by Doclava.
279 Dex_api_filename *string
280
Nan Zhang28c68b92018-03-13 16:17:01 -0700281 // the generated private API filename by Doclava.
282 Private_api_filename *string
283
284 // the generated private Dex API filename by Doclava.
285 Private_dex_api_filename *string
286
287 // the generated removed API filename by Doclava.
288 Removed_api_filename *string
289
David Brazdilaac0c3c2018-04-24 16:23:29 +0100290 // the generated removed Dex API filename by Doclava.
291 Removed_dex_api_filename *string
292
Mathew Inwood76c3de12018-06-22 15:28:11 +0100293 // mapping of dex signatures to source file and line number. This is a temporary property and
294 // will be deleted; you probably shouldn't be using it.
295 Dex_mapping_filename *string
296
Nan Zhang28c68b92018-03-13 16:17:01 -0700297 // the generated exact API filename by Doclava.
298 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700299
Nan Zhang66dc2362018-08-14 20:41:04 -0700300 // the generated proguard filename by Doclava.
301 Proguard_filename *string
302
Nan Zhang853f4202018-04-12 16:55:56 -0700303 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
304 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700305
306 Check_api struct {
307 Last_released ApiToCheck
308
309 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900310
311 // do not perform API check against Last_released, in the case that both two specified API
312 // files by Last_released are modules which don't exist.
313 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700314 }
Nan Zhang79614d12018-04-19 18:03:39 -0700315
Nan Zhang1598a9e2018-09-04 17:14:32 -0700316 // if set to true, generate docs through Dokka instead of Doclava.
317 Dokka_enabled *bool
318}
319
320type DroidstubsProperties struct {
321 // the tag name used to distinguish if the API files belong to public/system/test.
322 Api_tag_name *string
323
Nan Zhang199645c2018-09-19 12:40:06 -0700324 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700325 Api_filename *string
326
Nan Zhang199645c2018-09-19 12:40:06 -0700327 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700328 Dex_api_filename *string
329
Nan Zhang199645c2018-09-19 12:40:06 -0700330 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700331 Private_api_filename *string
332
Nan Zhang199645c2018-09-19 12:40:06 -0700333 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700334 Private_dex_api_filename *string
335
Nan Zhang199645c2018-09-19 12:40:06 -0700336 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700337 Removed_api_filename *string
338
Nan Zhang199645c2018-09-19 12:40:06 -0700339 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700340 Removed_dex_api_filename *string
341
Nan Zhang9c69a122018-08-22 10:22:08 -0700342 // mapping of dex signatures to source file and line number. This is a temporary property and
343 // will be deleted; you probably shouldn't be using it.
344 Dex_mapping_filename *string
345
Nan Zhang199645c2018-09-19 12:40:06 -0700346 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700347 Exact_api_filename *string
348
Nan Zhang199645c2018-09-19 12:40:06 -0700349 // the generated proguard filename by Metalava.
350 Proguard_filename *string
351
Nan Zhang1598a9e2018-09-04 17:14:32 -0700352 Check_api struct {
353 Last_released ApiToCheck
354
355 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900356
357 // do not perform API check against Last_released, in the case that both two specified API
358 // files by Last_released are modules which don't exist.
359 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700360 }
Nan Zhang79614d12018-04-19 18:03:39 -0700361
362 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800363 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700364
365 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700366 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700367
Pete Gillin77167902018-09-19 18:16:26 +0100368 // 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 -0700369 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700370
Pete Gillin77167902018-09-19 18:16:26 +0100371 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
372 Merge_inclusion_annotations_dirs []string
373
Pete Gillinc382a562018-11-14 18:45:46 +0000374 // a file containing a list of classes to do nullability validation for.
375 Validate_nullability_from_list *string
376
Pete Gillin581d6082018-10-22 15:55:04 +0100377 // a file containing expected warnings produced by validation of nullability annotations.
378 Check_nullability_warnings *string
379
Nan Zhang1598a9e2018-09-04 17:14:32 -0700380 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
381 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700382
383 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
384 Api_levels_annotations_enabled *bool
385
386 // the dirs which Metalava extracts API levels annotations from.
387 Api_levels_annotations_dirs []string
388
389 // if set to true, collect the values used by the Dev tools and
390 // write them in files packaged with the SDK. Defaults to false.
391 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700392
393 // If set to true, .xml based public API file will be also generated, and
394 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
395 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800396}
397
Nan Zhanga40da042018-08-01 12:48:00 -0700398//
399// Common flags passed down to build rule
400//
401type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700402 bootClasspathArgs string
403 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700404 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700405 dokkaClasspathArgs string
406 aidlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700407
Nan Zhanga40da042018-08-01 12:48:00 -0700408 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700409 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700410 postDoclavaCmds string
411
Nan Zhang9c69a122018-08-22 10:22:08 -0700412 metalavaStubsFlags string
413 metalavaAnnotationsFlags string
Nan Zhangdee152b2018-12-26 16:06:37 -0800414 metalavaMergeAnnoDirFlags string
Neil Fullerb2f14ec2018-10-21 22:13:19 +0100415 metalavaInclusionAnnotationsFlags string
Nan Zhang9c69a122018-08-22 10:22:08 -0700416 metalavaApiLevelsAnnotationsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700417
Nan Zhang71bbe632018-09-17 14:32:21 -0700418 metalavaApiToXmlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700419}
420
421func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
422 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
423 android.InitDefaultableModule(module)
424}
425
Nan Zhang1598a9e2018-09-04 17:14:32 -0700426func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
427 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
428 return true
429 } else if String(apiToCheck.Api_file) != "" {
430 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
431 } else if String(apiToCheck.Removed_api_file) != "" {
432 panic("for " + apiVersionTag + " api_file has to be non-empty!")
433 }
434
435 return false
436}
437
Inseob Kim38449af2019-02-28 14:24:05 +0900438func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
439 api_file := String(apiToCheck.Api_file)
440 removed_api_file := String(apiToCheck.Removed_api_file)
441
442 api_module := android.SrcIsModule(api_file)
443 removed_api_module := android.SrcIsModule(removed_api_file)
444
445 if api_module == "" || removed_api_module == "" {
446 return
447 }
448
449 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
450 return
451 }
452
453 apiToCheck.Api_file = nil
454 apiToCheck.Removed_api_file = nil
455}
456
Nan Zhang1598a9e2018-09-04 17:14:32 -0700457type ApiFilePath interface {
458 ApiFilePath() android.Path
459}
460
461func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
462 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
463 ctx.Build(pctx, android.BuildParams{
464 Rule: updateApi,
465 Description: "Update API",
466 Output: output,
467 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
468 destApiFile, destRemovedApiFile),
469 Args: map[string]string{
470 "destApiFile": destApiFile.String(),
471 "srcApiFile": srcApiFile.String(),
472 "destRemovedApiFile": destRemovedApiFile.String(),
473 "srcRemovedApiFile": srcRemovedApiFile.String(),
474 },
475 })
476}
477
Nan Zhanga40da042018-08-01 12:48:00 -0700478//
479// Javadoc
480//
Nan Zhang581fd212018-01-10 16:06:12 -0800481type Javadoc struct {
482 android.ModuleBase
483 android.DefaultableModuleBase
484
485 properties JavadocProperties
486
487 srcJars android.Paths
488 srcFiles android.Paths
489 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700490 argFiles android.Paths
491
492 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800493
Nan Zhangccff0f72018-03-08 17:26:16 -0800494 docZip android.WritablePath
495 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800496}
497
Nan Zhangb2b33de2018-02-23 11:18:47 -0800498func (j *Javadoc) Srcs() android.Paths {
499 return android.Paths{j.stubsSrcJar}
500}
501
Nan Zhang581fd212018-01-10 16:06:12 -0800502func JavadocFactory() android.Module {
503 module := &Javadoc{}
504
505 module.AddProperties(&module.properties)
506
507 InitDroiddocModule(module, android.HostAndDeviceSupported)
508 return module
509}
510
511func JavadocHostFactory() android.Module {
512 module := &Javadoc{}
513
514 module.AddProperties(&module.properties)
515
516 InitDroiddocModule(module, android.HostSupported)
517 return module
518}
519
Nan Zhanga40da042018-08-01 12:48:00 -0700520var _ android.SourceFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800521
Colin Cross83bb3162018-06-25 15:48:06 -0700522func (j *Javadoc) sdkVersion() string {
523 return String(j.properties.Sdk_version)
524}
525
526func (j *Javadoc) minSdkVersion() string {
527 return j.sdkVersion()
528}
529
Dan Willemsen419290a2018-10-31 15:28:47 -0700530func (j *Javadoc) targetSdkVersion() string {
531 return j.sdkVersion()
532}
533
Nan Zhang581fd212018-01-10 16:06:12 -0800534func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
535 if ctx.Device() {
Nan Zhang5994b622018-09-21 16:39:51 -0700536 if !Bool(j.properties.No_standard_libs) {
537 sdkDep := decodeSdkDep(ctx, sdkContext(j))
538 if sdkDep.useDefaultLibs {
539 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
540 if ctx.Config().TargetOpenJDK9() {
541 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
542 }
543 if !Bool(j.properties.No_framework_libs) {
544 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
545 }
546 } else if sdkDep.useModule {
547 if ctx.Config().TargetOpenJDK9() {
548 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
549 }
550 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700551 }
Nan Zhang581fd212018-01-10 16:06:12 -0800552 }
553 }
554
Colin Cross42d48b72018-08-29 14:10:52 -0700555 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700556 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700557 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700558 }
Nan Zhang581fd212018-01-10 16:06:12 -0800559}
560
Nan Zhangb2b33de2018-02-23 11:18:47 -0800561func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
562 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
563 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900564 // convert foo.bar.baz to foo/bar/baz
565 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
566 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800567 if _, found := whitelistPathPrefixes[prefix]; !found {
568 whitelistPathPrefixes[prefix] = true
569 }
570 }
571 }
572}
573
Nan Zhanga40da042018-08-01 12:48:00 -0700574func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
575 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900576
577 // aidl flags.
578 aidlFlags := j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
579 if len(aidlFlags) > 0 {
580 // optimization.
581 ctx.Variable(pctx, "aidlFlags", strings.Join(aidlFlags, " "))
582 flags.aidlFlags = "$aidlFlags"
583 }
584
585 return flags
586}
587
588func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
589 aidlIncludeDirs android.Paths) []string {
590
591 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
592 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
593
594 var flags []string
595 if aidlPreprocess.Valid() {
596 flags = append(flags, "-p"+aidlPreprocess.String())
597 } 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
607 return flags
608}
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":
618 javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
619 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)
691 if sm.outputFile == nil {
692 panic("Missing directory for system module dependency")
693 }
694 deps.systemModules = sm.outputFile
Nan Zhang581fd212018-01-10 16:06:12 -0800695 }
696 })
697 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
698 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800699 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700700 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900701 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800702
703 // srcs may depend on some genrule output.
704 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800705 j.srcJars = append(j.srcJars, deps.srcJars...)
706
Nan Zhang581fd212018-01-10 16:06:12 -0800707 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800708 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800709
710 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800711 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800712
Nan Zhang9c69a122018-08-22 10:22:08 -0700713 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800714 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
715 }
716 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800717
Colin Cross8a497952019-03-05 22:25:09 -0800718 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000719 argFilesMap := map[string]string{}
720 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700721
Paul Duffin99e4a502019-02-11 15:38:42 +0000722 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800723 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000724 if _, exists := argFilesMap[label]; !exists {
725 argFilesMap[label] = strings.Join(paths.Strings(), " ")
726 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700727 } else {
728 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000729 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700730 }
731 }
732
733 var err error
734 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
735 if strings.HasPrefix(name, "location ") {
736 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000737 if paths, ok := argFilesMap[label]; ok {
738 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700739 } else {
Paul Duffin99e4a502019-02-11 15:38:42 +0000740 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
741 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700742 }
743 } else if name == "genDir" {
744 return android.PathForModuleGen(ctx).String(), nil
745 }
746 return "", fmt.Errorf("unknown variable '$(%s)'", name)
747 })
748
749 if err != nil {
750 ctx.PropertyErrorf("args", "%s", err.Error())
751 }
752
Nan Zhang581fd212018-01-10 16:06:12 -0800753 return deps
754}
755
756func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
757 j.addDeps(ctx)
758}
759
760func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
761 deps := j.collectDeps(ctx)
762
763 var implicits android.Paths
764 implicits = append(implicits, deps.bootClasspath...)
765 implicits = append(implicits, deps.classpath...)
766
Nan Zhang1598a9e2018-09-04 17:14:32 -0700767 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700768
Colin Cross83bb3162018-06-25 15:48:06 -0700769 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700770 if len(deps.bootClasspath) > 0 {
771 var systemModules classpath
772 if deps.systemModules != nil {
773 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800774 }
Colin Cross997262f2018-06-19 22:49:39 -0700775 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
776 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800777 }
778 if len(deps.classpath.Strings()) > 0 {
779 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
780 }
781
782 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700783 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800784
Nan Zhangaf322cc2018-06-19 15:15:38 -0700785 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800786
Nan Zhang1598a9e2018-09-04 17:14:32 -0700787 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
788
Nan Zhang581fd212018-01-10 16:06:12 -0800789 ctx.Build(pctx, android.BuildParams{
790 Rule: javadoc,
791 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800792 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800793 ImplicitOutput: j.docZip,
794 Inputs: j.srcFiles,
795 Implicits: implicits,
796 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700797 "outDir": android.PathForModuleOut(ctx, "out").String(),
798 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
799 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800800 "srcJars": strings.Join(j.srcJars.Strings(), " "),
801 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700802 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800803 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700804 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800805 "docZip": j.docZip.String(),
806 },
807 })
808}
809
Nan Zhanga40da042018-08-01 12:48:00 -0700810//
811// Droiddoc
812//
813type Droiddoc struct {
814 Javadoc
815
816 properties DroiddocProperties
817 apiFile android.WritablePath
818 dexApiFile android.WritablePath
819 privateApiFile android.WritablePath
820 privateDexApiFile android.WritablePath
821 removedApiFile android.WritablePath
822 removedDexApiFile android.WritablePath
823 exactApiFile android.WritablePath
824 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700825 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700826
827 checkCurrentApiTimestamp android.WritablePath
828 updateCurrentApiTimestamp android.WritablePath
829 checkLastReleasedApiTimestamp android.WritablePath
830
Nan Zhanga40da042018-08-01 12:48:00 -0700831 apiFilePath android.Path
832}
833
Nan Zhanga40da042018-08-01 12:48:00 -0700834func DroiddocFactory() android.Module {
835 module := &Droiddoc{}
836
837 module.AddProperties(&module.properties,
838 &module.Javadoc.properties)
839
840 InitDroiddocModule(module, android.HostAndDeviceSupported)
841 return module
842}
843
844func DroiddocHostFactory() android.Module {
845 module := &Droiddoc{}
846
847 module.AddProperties(&module.properties,
848 &module.Javadoc.properties)
849
850 InitDroiddocModule(module, android.HostSupported)
851 return module
852}
853
854func (d *Droiddoc) ApiFilePath() android.Path {
855 return d.apiFilePath
856}
857
Nan Zhang581fd212018-01-10 16:06:12 -0800858func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
859 d.Javadoc.addDeps(ctx)
860
Inseob Kim38449af2019-02-28 14:24:05 +0900861 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
862 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
863 }
864
Nan Zhang79614d12018-04-19 18:03:39 -0700865 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800866 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
867 }
Nan Zhang581fd212018-01-10 16:06:12 -0800868}
869
Nan Zhang66dc2362018-08-14 20:41:04 -0700870func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
871 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700872 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800873
Nan Zhanga40da042018-08-01 12:48:00 -0700874 *implicits = append(*implicits, deps.bootClasspath...)
875 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800876
Nan Zhangc94f9d82018-06-26 10:02:26 -0700877 if len(deps.bootClasspath.Strings()) > 0 {
878 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700879 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700880 }
Nan Zhanga40da042018-08-01 12:48:00 -0700881 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700882 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700883 dokkaClasspath := classpath{}
884 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
885 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
886 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700887
Nan Zhang9c69a122018-08-22 10:22:08 -0700888 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
889 // based stubs generation.
890 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
891 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
892 // the correct package name base path.
893 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
894 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
895 } else {
896 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
897 }
Nan Zhang581fd212018-01-10 16:06:12 -0800898
Nan Zhanga40da042018-08-01 12:48:00 -0700899 return flags, nil
900}
Nan Zhang581fd212018-01-10 16:06:12 -0800901
Nan Zhanga40da042018-08-01 12:48:00 -0700902func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700903 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800904
Nan Zhanga40da042018-08-01 12:48:00 -0700905 *implicits = append(*implicits, jsilver)
906 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700907
Nan Zhang46130972018-06-04 11:28:01 -0700908 var date string
909 if runtime.GOOS == "darwin" {
910 date = `date -r`
911 } else {
912 date = `date -d`
913 }
914
Nan Zhang443fa522018-08-20 20:58:28 -0700915 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
916 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
917 // 1.9 language features.
918 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700919 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800920 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang79614d12018-04-19 18:03:39 -0700921 `-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700922
Nan Zhanga40da042018-08-01 12:48:00 -0700923 if String(d.properties.Custom_template) == "" {
924 // TODO: This is almost always droiddoc-templates-sdk
925 ctx.PropertyErrorf("custom_template", "must specify a template")
926 }
927
928 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700929 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700930 *implicits = append(*implicits, t.deps...)
931 args = args + " -templatedir " + t.dir.String()
932 } else {
933 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
934 }
935 })
936
937 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800938 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800939 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800940 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700941 }
942
943 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800944 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800945 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800946 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700947 }
948
949 if len(d.properties.Html_dirs) > 2 {
950 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
951 }
952
Colin Cross8a497952019-03-05 22:25:09 -0800953 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700954 *implicits = append(*implicits, knownTags...)
955
956 for _, kt := range knownTags {
957 args = args + " -knowntags " + kt.String()
958 }
959
960 for _, hdf := range d.properties.Hdf {
961 args = args + " -hdf " + hdf
962 }
963
964 if String(d.properties.Proofread_file) != "" {
965 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
966 args = args + " -proofread " + proofreadFile.String()
967 }
968
969 if String(d.properties.Todo_file) != "" {
970 // tricky part:
971 // we should not compute full path for todo_file through PathForModuleOut().
972 // the non-standard doclet will get the full path relative to "-o".
973 args = args + " -todo " + String(d.properties.Todo_file)
974 }
975
976 if String(d.properties.Resourcesdir) != "" {
977 // TODO: should we add files under resourcesDir to the implicits? It seems that
978 // resourcesDir is one sub dir of htmlDir
979 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
980 args = args + " -resourcesdir " + resourcesDir.String()
981 }
982
983 if String(d.properties.Resourcesoutdir) != "" {
984 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
985 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
986 }
987 return args
988}
989
Nan Zhang1598a9e2018-09-04 17:14:32 -0700990func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
991 implicitOutputs *android.WritablePaths) string {
992 var doclavaFlags string
993 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
994 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
995 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700996 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
997 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700998 *implicitOutputs = append(*implicitOutputs, d.apiFile)
999 d.apiFilePath = d.apiFile
1000 }
1001
Nan Zhang1598a9e2018-09-04 17:14:32 -07001002 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1003 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1004 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001005 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1006 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001007 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1008 }
1009
1010 if String(d.properties.Private_api_filename) != "" {
1011 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1012 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001013 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1014 }
1015
1016 if String(d.properties.Dex_api_filename) != "" {
1017 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1018 doclavaFlags += " -dexApi " + d.dexApiFile.String()
1019 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1020 }
1021
1022 if String(d.properties.Private_dex_api_filename) != "" {
1023 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1024 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001025 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1026 }
1027
1028 if String(d.properties.Removed_dex_api_filename) != "" {
1029 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1030 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001031 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1032 }
1033
1034 if String(d.properties.Exact_api_filename) != "" {
1035 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1036 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001037 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1038 }
1039
1040 if String(d.properties.Dex_mapping_filename) != "" {
1041 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1042 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001043 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1044 }
1045
Nan Zhang66dc2362018-08-14 20:41:04 -07001046 if String(d.properties.Proguard_filename) != "" {
1047 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1048 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -07001049 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1050 }
1051
Nan Zhanga40da042018-08-01 12:48:00 -07001052 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001053 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001054 }
1055
1056 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001057 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001058 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001059
1060 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001061}
1062
1063func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1064 var cmds string
1065 if String(d.properties.Static_doc_index_redirect) != "" {
1066 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1067 "static_doc_index_redirect")
1068 *implicits = append(*implicits, static_doc_index_redirect)
1069 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001070 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001071 }
1072
1073 if String(d.properties.Static_doc_properties) != "" {
1074 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1075 "static_doc_properties")
1076 *implicits = append(*implicits, static_doc_properties)
1077 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001078 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001079 }
1080 return cmds
1081}
1082
Nan Zhang1598a9e2018-09-04 17:14:32 -07001083func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1084 implicitOutputs android.WritablePaths,
1085 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1086 ctx.Build(pctx, android.BuildParams{
1087 Rule: javadoc,
1088 Description: "Doclava",
1089 Output: d.Javadoc.stubsSrcJar,
1090 Inputs: d.Javadoc.srcFiles,
1091 Implicits: implicits,
1092 ImplicitOutputs: implicitOutputs,
1093 Args: map[string]string{
1094 "outDir": android.PathForModuleOut(ctx, "out").String(),
1095 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1096 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1097 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1098 "opts": opts,
1099 "bootclasspathArgs": bootclasspathArgs,
1100 "classpathArgs": classpathArgs,
1101 "sourcepathArgs": sourcepathArgs,
1102 "docZip": d.Javadoc.docZip.String(),
1103 "postDoclavaCmds": postDoclavaCmds,
1104 },
1105 })
1106}
1107
1108func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1109 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1110 ctx.Build(pctx, android.BuildParams{
1111 Rule: apiCheck,
1112 Description: "Doclava Check API",
1113 Output: output,
1114 Inputs: nil,
1115 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1116 checkApiClasspath...),
1117 Args: map[string]string{
1118 "msg": msg,
1119 "classpath": checkApiClasspath.FormJavaClassPath(""),
1120 "opts": opts,
1121 "apiFile": apiFile.String(),
1122 "apiFileToCheck": d.apiFile.String(),
1123 "removedApiFile": removedApiFile.String(),
1124 "removedApiFileToCheck": d.removedApiFile.String(),
1125 },
1126 })
1127}
1128
1129func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1130 classpathArgs, opts string) {
1131 ctx.Build(pctx, android.BuildParams{
1132 Rule: dokka,
1133 Description: "Dokka",
1134 Output: d.Javadoc.stubsSrcJar,
1135 Inputs: d.Javadoc.srcFiles,
1136 Implicits: implicits,
1137 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001138 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1139 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1140 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001141 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1142 "classpathArgs": classpathArgs,
1143 "opts": opts,
1144 "docZip": d.Javadoc.docZip.String(),
1145 },
1146 })
1147}
1148
1149func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1150 deps := d.Javadoc.collectDeps(ctx)
1151
1152 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1153 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1154 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1155 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1156
1157 var implicits android.Paths
1158 implicits = append(implicits, d.Javadoc.srcJars...)
1159 implicits = append(implicits, d.Javadoc.argFiles...)
1160
1161 var implicitOutputs android.WritablePaths
1162 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1163 for _, o := range d.Javadoc.properties.Out {
1164 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1165 }
1166
1167 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1168 if err != nil {
1169 return
1170 }
1171
1172 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1173 if Bool(d.properties.Dokka_enabled) {
1174 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1175 } else {
1176 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1177 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1178 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1179 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1180 flags.postDoclavaCmds)
1181 }
1182
1183 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1184 !ctx.Config().IsPdkBuild() {
1185 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1186 "check_api.current.api_file")
1187 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1188 "check_api.current_removed_api_file")
1189
1190 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1191 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1192 fmt.Sprintf(`\n******************************\n`+
1193 `You have tried to change the API from what has been previously approved.\n\n`+
1194 `To make these errors go away, you have two choices:\n`+
1195 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1196 ` errors above.\n\n`+
1197 ` 2. You can update current.txt by executing the following command:\n`+
1198 ` make %s-update-current-api\n\n`+
1199 ` To submit the revised current.txt to the main Android repository,\n`+
1200 ` you will need approval.\n`+
1201 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1202 d.checkCurrentApiTimestamp)
1203
1204 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1205 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1206 d.updateCurrentApiTimestamp)
1207 }
1208
1209 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1210 !ctx.Config().IsPdkBuild() {
1211 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1212 "check_api.last_released.api_file")
1213 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1214 "check_api.last_released.removed_api_file")
1215
1216 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1217 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1218 `\n******************************\n`+
1219 `You have tried to change the API from what has been previously released in\n`+
1220 `an SDK. Please fix the errors listed above.\n`+
1221 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1222 d.checkLastReleasedApiTimestamp)
1223 }
1224}
1225
1226//
1227// Droidstubs
1228//
1229type Droidstubs struct {
1230 Javadoc
1231
Pete Gillin581d6082018-10-22 15:55:04 +01001232 properties DroidstubsProperties
1233 apiFile android.WritablePath
1234 apiXmlFile android.WritablePath
1235 lastReleasedApiXmlFile android.WritablePath
1236 dexApiFile android.WritablePath
1237 privateApiFile android.WritablePath
1238 privateDexApiFile android.WritablePath
1239 removedApiFile android.WritablePath
1240 removedDexApiFile android.WritablePath
1241 apiMappingFile android.WritablePath
1242 exactApiFile android.WritablePath
1243 proguardFile android.WritablePath
1244 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001245
1246 checkCurrentApiTimestamp android.WritablePath
1247 updateCurrentApiTimestamp android.WritablePath
1248 checkLastReleasedApiTimestamp android.WritablePath
1249
Pete Gillin581d6082018-10-22 15:55:04 +01001250 checkNullabilityWarningsTimestamp android.WritablePath
1251
Nan Zhang1598a9e2018-09-04 17:14:32 -07001252 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001253 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001254
1255 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001256
1257 jdiffDocZip android.WritablePath
1258 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001259}
1260
1261func DroidstubsFactory() android.Module {
1262 module := &Droidstubs{}
1263
1264 module.AddProperties(&module.properties,
1265 &module.Javadoc.properties)
1266
1267 InitDroiddocModule(module, android.HostAndDeviceSupported)
1268 return module
1269}
1270
1271func DroidstubsHostFactory() android.Module {
1272 module := &Droidstubs{}
1273
1274 module.AddProperties(&module.properties,
1275 &module.Javadoc.properties)
1276
1277 InitDroiddocModule(module, android.HostSupported)
1278 return module
1279}
1280
1281func (d *Droidstubs) ApiFilePath() android.Path {
1282 return d.apiFilePath
1283}
1284
1285func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1286 d.Javadoc.addDeps(ctx)
1287
Inseob Kim38449af2019-02-28 14:24:05 +09001288 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1289 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1290 }
1291
Nan Zhang1598a9e2018-09-04 17:14:32 -07001292 if len(d.properties.Merge_annotations_dirs) != 0 {
1293 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1294 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1295 }
1296 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001297
Pete Gillin77167902018-09-19 18:16:26 +01001298 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1299 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1300 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1301 }
1302 }
1303
Nan Zhang9c69a122018-08-22 10:22:08 -07001304 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1305 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1306 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1307 }
1308 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001309}
1310
1311func (d *Droidstubs) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
1312 deps deps) (droiddocBuilderFlags, error) {
1313 var flags droiddocBuilderFlags
1314
1315 *implicits = append(*implicits, deps.bootClasspath...)
1316 *implicits = append(*implicits, deps.classpath...)
1317
1318 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
1319 // since it doesn't support system modules yet.
1320 if len(deps.bootClasspath.Strings()) > 0 {
1321 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
1322 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
1323 }
1324 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
1325
Sundong Ahn56dce442018-10-05 18:41:09 +09001326 flags.sourcepathArgs = "-sourcepath \"" + strings.Join(d.Javadoc.sourcepaths.Strings(), ":") + "\""
Nan Zhang1598a9e2018-09-04 17:14:32 -07001327 return flags, nil
1328}
1329
1330func (d *Droidstubs) collectStubsFlags(ctx android.ModuleContext,
1331 implicitOutputs *android.WritablePaths) string {
1332 var metalavaFlags string
1333 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1334 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1335 String(d.properties.Api_filename) != "" {
1336 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1337 metalavaFlags = metalavaFlags + " --api " + d.apiFile.String()
1338 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1339 d.apiFilePath = d.apiFile
1340 }
1341
1342 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1343 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1344 String(d.properties.Removed_api_filename) != "" {
1345 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1346 metalavaFlags = metalavaFlags + " --removed-api " + d.removedApiFile.String()
1347 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1348 }
1349
1350 if String(d.properties.Private_api_filename) != "" {
1351 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1352 metalavaFlags = metalavaFlags + " --private-api " + d.privateApiFile.String()
1353 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1354 }
1355
1356 if String(d.properties.Dex_api_filename) != "" {
1357 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1358 metalavaFlags += " --dex-api " + d.dexApiFile.String()
1359 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1360 }
1361
1362 if String(d.properties.Private_dex_api_filename) != "" {
1363 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1364 metalavaFlags = metalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
1365 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1366 }
1367
1368 if String(d.properties.Removed_dex_api_filename) != "" {
1369 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1370 metalavaFlags = metalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
1371 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1372 }
1373
1374 if String(d.properties.Exact_api_filename) != "" {
1375 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1376 metalavaFlags = metalavaFlags + " --exact-api " + d.exactApiFile.String()
1377 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1378 }
1379
Nan Zhang9c69a122018-08-22 10:22:08 -07001380 if String(d.properties.Dex_mapping_filename) != "" {
1381 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1382 metalavaFlags = metalavaFlags + " --dex-api-mapping " + d.apiMappingFile.String()
1383 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1384 }
1385
Nan Zhang199645c2018-09-19 12:40:06 -07001386 if String(d.properties.Proguard_filename) != "" {
1387 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1388 metalavaFlags += " --proguard " + d.proguardFile.String()
1389 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1390 }
1391
Nan Zhang9c69a122018-08-22 10:22:08 -07001392 if Bool(d.properties.Write_sdk_values) {
1393 metalavaFlags = metalavaFlags + " --sdk-values " + android.PathForModuleOut(ctx, "out").String()
1394 }
1395
Nan Zhang1598a9e2018-09-04 17:14:32 -07001396 if Bool(d.properties.Create_doc_stubs) {
1397 metalavaFlags += " --doc-stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1398 } else {
1399 metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1400 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001401 return metalavaFlags
1402}
1403
1404func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
Nan Zhangdee152b2018-12-26 16:06:37 -08001405 implicits *android.Paths, implicitOutputs *android.WritablePaths) (string, string) {
1406 var flags, mergeAnnoDirFlags string
Nan Zhang1598a9e2018-09-04 17:14:32 -07001407 if Bool(d.properties.Annotations_enabled) {
Pete Gillina262c052018-09-14 14:25:48 +01001408 flags += " --include-annotations"
Pete Gillinc382a562018-11-14 18:45:46 +00001409 validatingNullability :=
1410 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1411 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001412 migratingNullability := String(d.properties.Previous_api) != ""
1413 if !(migratingNullability || validatingNullability) {
1414 ctx.PropertyErrorf("previous_api",
1415 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001416 }
Pete Gillina262c052018-09-14 14:25:48 +01001417 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001418 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Pete Gillina262c052018-09-14 14:25:48 +01001419 *implicits = append(*implicits, previousApi)
1420 flags += " --migrate-nullness " + previousApi.String()
1421 }
Pete Gillinc382a562018-11-14 18:45:46 +00001422 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross8a497952019-03-05 22:25:09 -08001423 flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
Pete Gillinc382a562018-11-14 18:45:46 +00001424 }
Pete Gillina262c052018-09-14 14:25:48 +01001425 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001426 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
1427 *implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
1428 flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
Pete Gillina262c052018-09-14 14:25:48 +01001429 }
Nan Zhanga40da042018-08-01 12:48:00 -07001430
1431 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
1432 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
1433
Nan Zhangf4936b02018-08-01 15:00:28 -07001434 flags += " --extract-annotations " + d.annotationsZip.String()
1435
Nan Zhang1598a9e2018-09-04 17:14:32 -07001436 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001437 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001438 "has to be non-empty if annotations was enabled!")
1439 }
Nan Zhangf4936b02018-08-01 15:00:28 -07001440 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1441 if t, ok := m.(*ExportedDroiddocDir); ok {
1442 *implicits = append(*implicits, t.deps...)
Nan Zhangdee152b2018-12-26 16:06:37 -08001443 mergeAnnoDirFlags += " --merge-qualifier-annotations " + t.dir.String()
Nan Zhangf4936b02018-08-01 15:00:28 -07001444 } else {
Nan Zhang9c69a122018-08-22 10:22:08 -07001445 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhangf4936b02018-08-01 15:00:28 -07001446 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1447 }
1448 })
Nan Zhangdee152b2018-12-26 16:06:37 -08001449 flags += mergeAnnoDirFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001450 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001451 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
Nan Zhanga40da042018-08-01 12:48:00 -07001452 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001453
Nan Zhangdee152b2018-12-26 16:06:37 -08001454 return flags, mergeAnnoDirFlags
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001455}
1456
1457func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
1458 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1459 var flags string
Pete Gillin77167902018-09-19 18:16:26 +01001460 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1461 if t, ok := m.(*ExportedDroiddocDir); ok {
1462 *implicits = append(*implicits, t.deps...)
1463 flags += " --merge-inclusion-annotations " + t.dir.String()
1464 } else {
1465 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1466 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1467 }
1468 })
Nan Zhanga40da042018-08-01 12:48:00 -07001469
1470 return flags
1471}
1472
Nan Zhang9c69a122018-08-22 10:22:08 -07001473func (d *Droidstubs) collectAPILevelsAnnotationsFlags(ctx android.ModuleContext,
1474 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1475 var flags string
1476 if Bool(d.properties.Api_levels_annotations_enabled) {
1477 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1478 *implicitOutputs = append(*implicitOutputs, d.apiVersionsXml)
1479
1480 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1481 ctx.PropertyErrorf("api_levels_annotations_dirs",
1482 "has to be non-empty if api levels annotations was enabled!")
1483 }
1484
1485 flags = " --generate-api-levels " + d.apiVersionsXml.String() + " --apply-api-levels " +
1486 d.apiVersionsXml.String() + " --current-version " + ctx.Config().PlatformSdkVersion() +
1487 " --current-codename " + ctx.Config().PlatformSdkCodename() + " "
1488
1489 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1490 if t, ok := m.(*ExportedDroiddocDir); ok {
1491 var androidJars android.Paths
1492 for _, dep := range t.deps {
1493 if strings.HasSuffix(dep.String(), "android.jar") {
1494 androidJars = append(androidJars, dep)
1495 }
1496 }
1497 *implicits = append(*implicits, androidJars...)
Tor Norbyeebcdfed2019-01-24 11:05:46 -08001498 flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
Nan Zhang9c69a122018-08-22 10:22:08 -07001499 } else {
1500 ctx.PropertyErrorf("api_levels_annotations_dirs",
1501 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1502 }
1503 })
1504
1505 }
1506
1507 return flags
1508}
1509
Nan Zhang71bbe632018-09-17 14:32:21 -07001510func (d *Droidstubs) collectApiToXmlFlags(ctx android.ModuleContext, implicits *android.Paths,
1511 implicitOutputs *android.WritablePaths) string {
1512 var flags string
1513 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1514 if d.apiFile.String() == "" {
1515 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1516 }
1517
1518 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
1519 *implicitOutputs = append(*implicitOutputs, d.apiXmlFile)
1520
1521 flags = " --api-xml " + d.apiXmlFile.String()
1522
1523 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1524 ctx.PropertyErrorf("check_api.last_released.api_file",
1525 "has to be non-empty if jdiff was enabled!")
1526 }
1527 lastReleasedApi := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1528 "check_api.last_released.api_file")
1529 *implicits = append(*implicits, lastReleasedApi)
1530
1531 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
1532 *implicitOutputs = append(*implicitOutputs, d.lastReleasedApiXmlFile)
1533
1534 flags += " --convert-to-jdiff " + lastReleasedApi.String() + " " +
1535 d.lastReleasedApiXmlFile.String()
1536 }
1537
1538 return flags
1539}
1540
Nan Zhang1598a9e2018-09-04 17:14:32 -07001541func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
1542 implicitOutputs android.WritablePaths, javaVersion,
1543 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001544
Nan Zhang86d2d552018-08-09 15:33:27 -07001545 ctx.Build(pctx, android.BuildParams{
1546 Rule: metalava,
1547 Description: "Metalava",
1548 Output: d.Javadoc.stubsSrcJar,
1549 Inputs: d.Javadoc.srcFiles,
1550 Implicits: implicits,
1551 ImplicitOutputs: implicitOutputs,
1552 Args: map[string]string{
Nan Zhang86d2d552018-08-09 15:33:27 -07001553 "outDir": android.PathForModuleOut(ctx, "out").String(),
1554 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1555 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1556 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001557 "javaVersion": javaVersion,
Nan Zhang86d2d552018-08-09 15:33:27 -07001558 "bootclasspathArgs": bootclasspathArgs,
1559 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001560 "sourcepathArgs": sourcepathArgs,
1561 "opts": opts,
Nan Zhang86d2d552018-08-09 15:33:27 -07001562 },
1563 })
1564}
1565
Nan Zhang1598a9e2018-09-04 17:14:32 -07001566func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
1567 apiFile, removedApiFile android.Path, implicits android.Paths,
Colin Cross39c16792019-01-24 16:32:44 -08001568 javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001569 output android.WritablePath) {
1570 ctx.Build(pctx, android.BuildParams{
1571 Rule: metalavaApiCheck,
1572 Description: "Metalava Check API",
1573 Output: output,
1574 Inputs: d.Javadoc.srcFiles,
1575 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1576 implicits...),
1577 Args: map[string]string{
Colin Cross39c16792019-01-24 16:32:44 -08001578 "srcJarDir": android.PathForModuleOut(ctx, subdir, "srcjars").String(),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001579 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1580 "javaVersion": javaVersion,
1581 "bootclasspathArgs": bootclasspathArgs,
1582 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001583 "sourcepathArgs": sourcepathArgs,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001584 "opts": opts,
1585 "msg": msg,
1586 },
1587 })
1588}
1589
Nan Zhang71bbe632018-09-17 14:32:21 -07001590func (d *Droidstubs) transformJdiff(ctx android.ModuleContext, implicits android.Paths,
1591 implicitOutputs android.WritablePaths,
1592 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
1593 ctx.Build(pctx, android.BuildParams{
1594 Rule: javadoc,
1595 Description: "Jdiff",
1596 Output: d.jdiffStubsSrcJar,
1597 Inputs: d.Javadoc.srcFiles,
1598 Implicits: implicits,
1599 ImplicitOutputs: implicitOutputs,
1600 Args: map[string]string{
Nan Zhang23a1ba62018-09-19 11:19:39 -07001601 "outDir": android.PathForModuleOut(ctx, "jdiff-out").String(),
1602 "srcJarDir": android.PathForModuleOut(ctx, "jdiff-srcjars").String(),
1603 "stubsDir": android.PathForModuleOut(ctx, "jdiff-stubsDir").String(),
Nan Zhang71bbe632018-09-17 14:32:21 -07001604 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1605 "opts": opts,
1606 "bootclasspathArgs": bootclasspathArgs,
1607 "classpathArgs": classpathArgs,
1608 "sourcepathArgs": sourcepathArgs,
1609 "docZip": d.jdiffDocZip.String(),
1610 },
1611 })
1612}
1613
Nan Zhang1598a9e2018-09-04 17:14:32 -07001614func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001615 deps := d.Javadoc.collectDeps(ctx)
1616
1617 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001618
Nan Zhanga40da042018-08-01 12:48:00 -07001619 var implicits android.Paths
1620 implicits = append(implicits, d.Javadoc.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001621 implicits = append(implicits, d.Javadoc.argFiles...)
Nan Zhanga40da042018-08-01 12:48:00 -07001622
1623 var implicitOutputs android.WritablePaths
Nan Zhang1598a9e2018-09-04 17:14:32 -07001624 for _, o := range d.Javadoc.properties.Out {
Nan Zhanga40da042018-08-01 12:48:00 -07001625 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1626 }
1627
1628 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
Nan Zhang2760dfc2018-08-24 17:32:54 +00001629 metalavaCheckApiImplicits := implicits
Nan Zhang71bbe632018-09-17 14:32:21 -07001630 jdiffImplicits := implicits
1631
Nan Zhanga40da042018-08-01 12:48:00 -07001632 if err != nil {
1633 return
1634 }
1635
Nan Zhang1598a9e2018-09-04 17:14:32 -07001636 flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
Nan Zhangdee152b2018-12-26 16:06:37 -08001637 flags.metalavaAnnotationsFlags, flags.metalavaMergeAnnoDirFlags =
1638 d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001639 flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang9c69a122018-08-22 10:22:08 -07001640 flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang71bbe632018-09-17 14:32:21 -07001641 flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
1642
Nan Zhang1598a9e2018-09-04 17:14:32 -07001643 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1644 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1645 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1646 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1647 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001648 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001649 d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
1650 flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001651 flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
Nan Zhang71bbe632018-09-17 14:32:21 -07001652 flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
Nan Zhang61819ce2018-05-04 18:49:16 -07001653
Nan Zhang1598a9e2018-09-04 17:14:32 -07001654 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1655 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001656 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1657 "check_api.current.api_file")
1658 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1659 "check_api.current_removed_api_file")
1660
Nan Zhang2760dfc2018-08-24 17:32:54 +00001661 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001662 opts := " " + d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
1663 " --check-compatibility:removed:current " + removedApiFile.String() +
Nan Zhangdee152b2018-12-26 16:06:37 -08001664 flags.metalavaInclusionAnnotationsFlags + flags.metalavaMergeAnnoDirFlags + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001665
Nan Zhang1598a9e2018-09-04 17:14:32 -07001666 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001667 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001668 fmt.Sprintf(`\n******************************\n`+
1669 `You have tried to change the API from what has been previously approved.\n\n`+
1670 `To make these errors go away, you have two choices:\n`+
1671 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1672 ` errors above.\n\n`+
1673 ` 2. You can update current.txt by executing the following command:\n`+
1674 ` make %s-update-current-api\n\n`+
1675 ` To submit the revised current.txt to the main Android repository,\n`+
1676 ` you will need approval.\n`+
1677 `******************************\n`, ctx.ModuleName()),
1678 d.checkCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001679
1680 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001681 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1682 d.updateCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001683 }
Nan Zhanga40da042018-08-01 12:48:00 -07001684
Nan Zhang1598a9e2018-09-04 17:14:32 -07001685 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1686 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001687 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1688 "check_api.last_released.api_file")
1689 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1690 "check_api.last_released.removed_api_file")
1691
Nan Zhang2760dfc2018-08-24 17:32:54 +00001692 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001693 opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
1694 flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
Nan Zhangdee152b2018-12-26 16:06:37 -08001695 removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001696
Nan Zhang1598a9e2018-09-04 17:14:32 -07001697 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001698 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001699 `\n******************************\n`+
1700 `You have tried to change the API from what has been previously released in\n`+
1701 `an SDK. Please fix the errors listed above.\n`+
1702 `******************************\n`,
1703 d.checkLastReleasedApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001704 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001705
Pete Gillin581d6082018-10-22 15:55:04 +01001706 if String(d.properties.Check_nullability_warnings) != "" {
1707 if d.nullabilityWarningsFile == nil {
1708 ctx.PropertyErrorf("check_nullability_warnings",
1709 "Cannot specify check_nullability_warnings unless validating nullability")
1710 }
1711 checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
1712 "check_nullability_warnings")
1713 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
1714 msg := fmt.Sprintf(`\n******************************\n`+
1715 `The warnings encountered during nullability annotation validation did\n`+
1716 `not match the checked in file of expected warnings. The diffs are shown\n`+
1717 `above. You have two options:\n`+
1718 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1719 ` 2. Update the file of expected warnings by running:\n`+
1720 ` cp %s %s\n`+
1721 ` and submitting the updated file as part of your change.`,
1722 d.nullabilityWarningsFile, checkNullabilityWarnings)
1723 ctx.Build(pctx, android.BuildParams{
1724 Rule: nullabilityWarningsCheck,
1725 Description: "Nullability Warnings Check",
1726 Output: d.checkNullabilityWarningsTimestamp,
1727 Implicits: android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
1728 Args: map[string]string{
1729 "expected": checkNullabilityWarnings.String(),
1730 "actual": d.nullabilityWarningsFile.String(),
1731 "msg": msg,
1732 },
1733 })
1734 }
1735
Nan Zhang71bbe632018-09-17 14:32:21 -07001736 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1737
Nan Zhang86b06202018-09-21 17:09:21 -07001738 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1739 // since there's cron job downstream that fetch this .zip file periodically.
1740 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001741 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1742 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1743
1744 var jdiffImplicitOutputs android.WritablePaths
1745 jdiffImplicitOutputs = append(jdiffImplicitOutputs, d.jdiffDocZip)
1746
1747 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
1748 jdiffImplicits = append(jdiffImplicits, android.Paths{jdiff, d.apiXmlFile, d.lastReleasedApiXmlFile}...)
1749
1750 opts := " -encoding UTF-8 -source 1.8 -J-Xmx1600m -XDignore.symbol.file " +
1751 "-doclet jdiff.JDiff -docletpath " + jdiff.String() + " -quiet " +
1752 "-newapi " + strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext()) +
1753 " -newapidir " + filepath.Dir(d.apiXmlFile.String()) +
1754 " -oldapi " + strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext()) +
1755 " -oldapidir " + filepath.Dir(d.lastReleasedApiXmlFile.String())
1756
1757 d.transformJdiff(ctx, jdiffImplicits, jdiffImplicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1758 flags.sourcepathArgs, opts)
1759 }
Nan Zhang581fd212018-01-10 16:06:12 -08001760}
Dan Willemsencc090972018-02-26 14:33:31 -08001761
Nan Zhanga40da042018-08-01 12:48:00 -07001762//
Nan Zhangf4936b02018-08-01 15:00:28 -07001763// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001764//
Dan Willemsencc090972018-02-26 14:33:31 -08001765var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001766var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001767var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001768var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001769
Nan Zhangf4936b02018-08-01 15:00:28 -07001770type ExportedDroiddocDirProperties struct {
1771 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001772 Path *string
1773}
1774
Nan Zhangf4936b02018-08-01 15:00:28 -07001775type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001776 android.ModuleBase
1777
Nan Zhangf4936b02018-08-01 15:00:28 -07001778 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001779
1780 deps android.Paths
1781 dir android.Path
1782}
1783
Nan Zhangf4936b02018-08-01 15:00:28 -07001784func ExportedDroiddocDirFactory() android.Module {
1785 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001786 module.AddProperties(&module.properties)
1787 android.InitAndroidModule(module)
1788 return module
1789}
1790
Nan Zhangf4936b02018-08-01 15:00:28 -07001791func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001792
Nan Zhangf4936b02018-08-01 15:00:28 -07001793func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001794 path := String(d.properties.Path)
1795 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001796 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001797}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001798
1799//
1800// Defaults
1801//
1802type DocDefaults struct {
1803 android.ModuleBase
1804 android.DefaultsModuleBase
1805}
1806
1807func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1808}
1809
Nan Zhangb2b33de2018-02-23 11:18:47 -08001810func DocDefaultsFactory() android.Module {
1811 module := &DocDefaults{}
1812
1813 module.AddProperties(
1814 &JavadocProperties{},
1815 &DroiddocProperties{},
1816 )
1817
1818 android.InitDefaultsModule(module)
1819
1820 return module
1821}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001822
1823func StubsDefaultsFactory() android.Module {
1824 module := &DocDefaults{}
1825
1826 module.AddProperties(
1827 &JavadocProperties{},
1828 &DroidstubsProperties{},
1829 )
1830
1831 android.InitDefaultsModule(module)
1832
1833 return module
1834}