blob: 6bac5bb7dbc2b6b92e041e5bab2fde2ccc2012ac [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
Adrian Roos4937c4a2019-08-12 17:54:09 +0200230 // If not blank, path to the baseline txt file for approved API check violations.
231 Baseline_file *string `android:"path"`
232
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900233 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700234 Args *string
235}
236
Nan Zhang581fd212018-01-10 16:06:12 -0800237type DroiddocProperties struct {
238 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800239 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800240
Nan Zhanga40da042018-08-01 12:48:00 -0700241 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800242 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800243
244 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800245 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800246
247 // proofread file contains all of the text content of the javadocs concatenated into one file,
248 // suitable for spell-checking and other goodness.
Colin Cross27b922f2019-03-04 22:35:41 -0800249 Proofread_file *string `android:"path"`
Nan Zhang581fd212018-01-10 16:06:12 -0800250
251 // a todo file lists the program elements that are missing documentation.
252 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800253 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800254
255 // directory under current module source that provide additional resources (images).
256 Resourcesdir *string
257
258 // resources output directory under out/soong/.intermediates.
259 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800260
Nan Zhange2ba5d42018-07-11 15:16:55 -0700261 // if set to true, collect the values used by the Dev tools and
262 // write them in files packaged with the SDK. Defaults to false.
263 Write_sdk_values *bool
264
265 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800266 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700267
268 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800269 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700270
Nan Zhang581fd212018-01-10 16:06:12 -0800271 // a list of files under current module source dir which contains known tags in Java sources.
272 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800273 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700274
275 // the tag name used to distinguish if the API files belong to public/system/test.
276 Api_tag_name *string
277
278 // the generated public API filename by Doclava.
279 Api_filename *string
280
David Brazdilfbe4cc32018-05-31 13:56:46 +0100281 // the generated public Dex API filename by Doclava.
282 Dex_api_filename *string
283
Nan Zhang28c68b92018-03-13 16:17:01 -0700284 // the generated private API filename by Doclava.
285 Private_api_filename *string
286
287 // the generated private Dex API filename by Doclava.
288 Private_dex_api_filename *string
289
290 // the generated removed API filename by Doclava.
291 Removed_api_filename *string
292
David Brazdilaac0c3c2018-04-24 16:23:29 +0100293 // the generated removed Dex API filename by Doclava.
294 Removed_dex_api_filename *string
295
Mathew Inwood76c3de12018-06-22 15:28:11 +0100296 // mapping of dex signatures to source file and line number. This is a temporary property and
297 // will be deleted; you probably shouldn't be using it.
298 Dex_mapping_filename *string
299
Nan Zhang28c68b92018-03-13 16:17:01 -0700300 // the generated exact API filename by Doclava.
301 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700302
Nan Zhang66dc2362018-08-14 20:41:04 -0700303 // the generated proguard filename by Doclava.
304 Proguard_filename *string
305
Nan Zhang853f4202018-04-12 16:55:56 -0700306 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
307 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700308
309 Check_api struct {
310 Last_released ApiToCheck
311
312 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900313
314 // do not perform API check against Last_released, in the case that both two specified API
315 // files by Last_released are modules which don't exist.
316 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700317 }
Nan Zhang79614d12018-04-19 18:03:39 -0700318
Nan Zhang1598a9e2018-09-04 17:14:32 -0700319 // if set to true, generate docs through Dokka instead of Doclava.
320 Dokka_enabled *bool
321}
322
323type DroidstubsProperties struct {
324 // the tag name used to distinguish if the API files belong to public/system/test.
325 Api_tag_name *string
326
Nan Zhang199645c2018-09-19 12:40:06 -0700327 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700328 Api_filename *string
329
Nan Zhang199645c2018-09-19 12:40:06 -0700330 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700331 Dex_api_filename *string
332
Nan Zhang199645c2018-09-19 12:40:06 -0700333 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700334 Private_api_filename *string
335
Nan Zhang199645c2018-09-19 12:40:06 -0700336 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700337 Private_dex_api_filename *string
338
Nan Zhang199645c2018-09-19 12:40:06 -0700339 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700340 Removed_api_filename *string
341
Nan Zhang199645c2018-09-19 12:40:06 -0700342 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700343 Removed_dex_api_filename *string
344
Nan Zhang9c69a122018-08-22 10:22:08 -0700345 // mapping of dex signatures to source file and line number. This is a temporary property and
346 // will be deleted; you probably shouldn't be using it.
347 Dex_mapping_filename *string
348
Nan Zhang199645c2018-09-19 12:40:06 -0700349 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700350 Exact_api_filename *string
351
Nan Zhang199645c2018-09-19 12:40:06 -0700352 // the generated proguard filename by Metalava.
353 Proguard_filename *string
354
Nan Zhang1598a9e2018-09-04 17:14:32 -0700355 Check_api struct {
356 Last_released ApiToCheck
357
358 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900359
360 // do not perform API check against Last_released, in the case that both two specified API
361 // files by Last_released are modules which don't exist.
362 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700363 }
Nan Zhang79614d12018-04-19 18:03:39 -0700364
365 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800366 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700367
368 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700369 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700370
Pete Gillin77167902018-09-19 18:16:26 +0100371 // 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 -0700372 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700373
Pete Gillin77167902018-09-19 18:16:26 +0100374 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
375 Merge_inclusion_annotations_dirs []string
376
Pete Gillinc382a562018-11-14 18:45:46 +0000377 // a file containing a list of classes to do nullability validation for.
378 Validate_nullability_from_list *string
379
Pete Gillin581d6082018-10-22 15:55:04 +0100380 // a file containing expected warnings produced by validation of nullability annotations.
381 Check_nullability_warnings *string
382
Nan Zhang1598a9e2018-09-04 17:14:32 -0700383 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
384 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700385
386 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
387 Api_levels_annotations_enabled *bool
388
389 // the dirs which Metalava extracts API levels annotations from.
390 Api_levels_annotations_dirs []string
391
392 // if set to true, collect the values used by the Dev tools and
393 // write them in files packaged with the SDK. Defaults to false.
394 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700395
396 // If set to true, .xml based public API file will be also generated, and
397 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
398 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800399}
400
Nan Zhanga40da042018-08-01 12:48:00 -0700401//
402// Common flags passed down to build rule
403//
404type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700405 bootClasspathArgs string
406 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700407 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700408 dokkaClasspathArgs string
409 aidlFlags string
Colin Cross9bdfaf02019-04-18 10:56:44 -0700410 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700411
Nan Zhanga40da042018-08-01 12:48:00 -0700412 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700413 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700414 postDoclavaCmds string
415
Nan Zhang9c69a122018-08-22 10:22:08 -0700416 metalavaStubsFlags string
417 metalavaAnnotationsFlags string
Nan Zhangdee152b2018-12-26 16:06:37 -0800418 metalavaMergeAnnoDirFlags string
Neil Fullerb2f14ec2018-10-21 22:13:19 +0100419 metalavaInclusionAnnotationsFlags string
Nan Zhang9c69a122018-08-22 10:22:08 -0700420 metalavaApiLevelsAnnotationsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700421
Nan Zhang71bbe632018-09-17 14:32:21 -0700422 metalavaApiToXmlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700423}
424
425func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
426 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
427 android.InitDefaultableModule(module)
428}
429
Nan Zhang1598a9e2018-09-04 17:14:32 -0700430func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
431 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
432 return true
433 } else if String(apiToCheck.Api_file) != "" {
434 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
435 } else if String(apiToCheck.Removed_api_file) != "" {
436 panic("for " + apiVersionTag + " api_file has to be non-empty!")
437 }
438
439 return false
440}
441
Inseob Kim38449af2019-02-28 14:24:05 +0900442func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
443 api_file := String(apiToCheck.Api_file)
444 removed_api_file := String(apiToCheck.Removed_api_file)
445
446 api_module := android.SrcIsModule(api_file)
447 removed_api_module := android.SrcIsModule(removed_api_file)
448
449 if api_module == "" || removed_api_module == "" {
450 return
451 }
452
453 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
454 return
455 }
456
457 apiToCheck.Api_file = nil
458 apiToCheck.Removed_api_file = nil
459}
460
Nan Zhang1598a9e2018-09-04 17:14:32 -0700461type ApiFilePath interface {
462 ApiFilePath() android.Path
463}
464
465func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
466 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
467 ctx.Build(pctx, android.BuildParams{
468 Rule: updateApi,
469 Description: "Update API",
470 Output: output,
471 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
472 destApiFile, destRemovedApiFile),
473 Args: map[string]string{
474 "destApiFile": destApiFile.String(),
475 "srcApiFile": srcApiFile.String(),
476 "destRemovedApiFile": destRemovedApiFile.String(),
477 "srcRemovedApiFile": srcRemovedApiFile.String(),
478 },
479 })
480}
481
Nan Zhanga40da042018-08-01 12:48:00 -0700482//
483// Javadoc
484//
Nan Zhang581fd212018-01-10 16:06:12 -0800485type Javadoc struct {
486 android.ModuleBase
487 android.DefaultableModuleBase
488
489 properties JavadocProperties
490
491 srcJars android.Paths
492 srcFiles android.Paths
493 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700494 argFiles android.Paths
495
496 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800497
Nan Zhangccff0f72018-03-08 17:26:16 -0800498 docZip android.WritablePath
499 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800500}
501
Nan Zhangb2b33de2018-02-23 11:18:47 -0800502func (j *Javadoc) Srcs() android.Paths {
503 return android.Paths{j.stubsSrcJar}
504}
505
Nan Zhang581fd212018-01-10 16:06:12 -0800506func JavadocFactory() android.Module {
507 module := &Javadoc{}
508
509 module.AddProperties(&module.properties)
510
511 InitDroiddocModule(module, android.HostAndDeviceSupported)
512 return module
513}
514
515func JavadocHostFactory() android.Module {
516 module := &Javadoc{}
517
518 module.AddProperties(&module.properties)
519
520 InitDroiddocModule(module, android.HostSupported)
521 return module
522}
523
Nan Zhanga40da042018-08-01 12:48:00 -0700524var _ android.SourceFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800525
Colin Cross83bb3162018-06-25 15:48:06 -0700526func (j *Javadoc) sdkVersion() string {
527 return String(j.properties.Sdk_version)
528}
529
530func (j *Javadoc) minSdkVersion() string {
531 return j.sdkVersion()
532}
533
Dan Willemsen419290a2018-10-31 15:28:47 -0700534func (j *Javadoc) targetSdkVersion() string {
535 return j.sdkVersion()
536}
537
Nan Zhang581fd212018-01-10 16:06:12 -0800538func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
539 if ctx.Device() {
Nan Zhang5994b622018-09-21 16:39:51 -0700540 if !Bool(j.properties.No_standard_libs) {
541 sdkDep := decodeSdkDep(ctx, sdkContext(j))
542 if sdkDep.useDefaultLibs {
543 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
544 if ctx.Config().TargetOpenJDK9() {
545 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
546 }
547 if !Bool(j.properties.No_framework_libs) {
548 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
549 }
550 } else if sdkDep.useModule {
551 if ctx.Config().TargetOpenJDK9() {
552 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
553 }
554 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700555 }
Nan Zhang581fd212018-01-10 16:06:12 -0800556 }
557 }
558
Colin Cross42d48b72018-08-29 14:10:52 -0700559 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700560 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700561 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700562 }
Nan Zhang581fd212018-01-10 16:06:12 -0800563}
564
Nan Zhangb2b33de2018-02-23 11:18:47 -0800565func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
566 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
567 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900568 // convert foo.bar.baz to foo/bar/baz
569 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
570 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800571 if _, found := whitelistPathPrefixes[prefix]; !found {
572 whitelistPathPrefixes[prefix] = true
573 }
574 }
575 }
576}
577
Nan Zhanga40da042018-08-01 12:48:00 -0700578func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
579 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900580
Colin Cross9bdfaf02019-04-18 10:56:44 -0700581 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900582
583 return flags
584}
585
586func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross9bdfaf02019-04-18 10:56:44 -0700587 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900588
589 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
590 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
591
592 var flags []string
Colin Cross9bdfaf02019-04-18 10:56:44 -0700593 var deps android.Paths
594
Jiyong Park1e440682018-05-23 18:42:04 +0900595 if aidlPreprocess.Valid() {
596 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross9bdfaf02019-04-18 10:56:44 -0700597 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900598 } else {
599 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
600 }
601
602 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
603 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
604 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
605 flags = append(flags, "-I"+src.String())
606 }
607
Colin Cross9bdfaf02019-04-18 10:56:44 -0700608 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900609}
610
611func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700612 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900613
614 outSrcFiles := make(android.Paths, 0, len(srcFiles))
615
616 for _, srcFile := range srcFiles {
617 switch srcFile.Ext() {
618 case ".aidl":
Colin Cross9bdfaf02019-04-18 10:56:44 -0700619 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900620 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900621 case ".sysprop":
622 javaFile := genSysprop(ctx, srcFile)
623 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900624 default:
625 outSrcFiles = append(outSrcFiles, srcFile)
626 }
627 }
628
629 return outSrcFiles
630}
631
Nan Zhang581fd212018-01-10 16:06:12 -0800632func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
633 var deps deps
634
Colin Cross83bb3162018-06-25 15:48:06 -0700635 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800636 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700637 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800638 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700639 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800640 }
641
642 ctx.VisitDirectDeps(func(module android.Module) {
643 otherName := ctx.OtherModuleName(module)
644 tag := ctx.OtherModuleDependencyTag(module)
645
Colin Cross2d24c1b2018-05-23 10:59:18 -0700646 switch tag {
647 case bootClasspathTag:
648 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800649 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700650 } else {
651 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
652 }
653 case libTag:
654 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800655 case SdkLibraryDependency:
656 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700657 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900658 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700659 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800660 checkProducesJars(ctx, dep)
661 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800662 default:
663 ctx.ModuleErrorf("depends on non-java module %q", otherName)
664 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700665 case srcsLibTag:
666 switch dep := module.(type) {
667 case Dependency:
668 srcs := dep.(SrcDependency).CompiledSrcs()
669 whitelistPathPrefixes := make(map[string]bool)
670 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
671 for _, src := range srcs {
672 if _, ok := src.(android.WritablePath); ok { // generated sources
673 deps.srcs = append(deps.srcs, src)
674 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700675 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700676 if strings.HasPrefix(src.Rel(), k) {
677 deps.srcs = append(deps.srcs, src)
678 break
679 }
680 }
681 }
682 }
683 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
684 default:
685 ctx.ModuleErrorf("depends on non-java module %q", otherName)
686 }
Nan Zhang357466b2018-04-17 17:38:36 -0700687 case systemModulesTag:
688 if deps.systemModules != nil {
689 panic("Found two system module dependencies")
690 }
691 sm := module.(*SystemModules)
692 if sm.outputFile == nil {
693 panic("Missing directory for system module dependency")
694 }
695 deps.systemModules = sm.outputFile
Nan Zhang581fd212018-01-10 16:06:12 -0800696 }
697 })
698 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
699 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800700 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700701 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900702 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800703
704 // srcs may depend on some genrule output.
705 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800706 j.srcJars = append(j.srcJars, deps.srcJars...)
707
Nan Zhang581fd212018-01-10 16:06:12 -0800708 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800709 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800710
711 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800712 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800713
Nan Zhang9c69a122018-08-22 10:22:08 -0700714 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800715 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
716 }
717 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800718
Colin Cross8a497952019-03-05 22:25:09 -0800719 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000720 argFilesMap := map[string]string{}
721 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700722
Paul Duffin99e4a502019-02-11 15:38:42 +0000723 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800724 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000725 if _, exists := argFilesMap[label]; !exists {
726 argFilesMap[label] = strings.Join(paths.Strings(), " ")
727 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700728 } else {
729 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000730 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700731 }
732 }
733
734 var err error
735 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
736 if strings.HasPrefix(name, "location ") {
737 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000738 if paths, ok := argFilesMap[label]; ok {
739 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700740 } else {
Paul Duffin99e4a502019-02-11 15:38:42 +0000741 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
742 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700743 }
744 } else if name == "genDir" {
745 return android.PathForModuleGen(ctx).String(), nil
746 }
747 return "", fmt.Errorf("unknown variable '$(%s)'", name)
748 })
749
750 if err != nil {
751 ctx.PropertyErrorf("args", "%s", err.Error())
752 }
753
Nan Zhang581fd212018-01-10 16:06:12 -0800754 return deps
755}
756
757func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
758 j.addDeps(ctx)
759}
760
761func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
762 deps := j.collectDeps(ctx)
763
764 var implicits android.Paths
765 implicits = append(implicits, deps.bootClasspath...)
766 implicits = append(implicits, deps.classpath...)
767
Nan Zhang1598a9e2018-09-04 17:14:32 -0700768 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700769
Colin Cross83bb3162018-06-25 15:48:06 -0700770 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700771 if len(deps.bootClasspath) > 0 {
772 var systemModules classpath
773 if deps.systemModules != nil {
774 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800775 }
Colin Cross997262f2018-06-19 22:49:39 -0700776 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
777 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800778 }
779 if len(deps.classpath.Strings()) > 0 {
780 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
781 }
782
783 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700784 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800785
Nan Zhangaf322cc2018-06-19 15:15:38 -0700786 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800787
Nan Zhang1598a9e2018-09-04 17:14:32 -0700788 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
789
Nan Zhang581fd212018-01-10 16:06:12 -0800790 ctx.Build(pctx, android.BuildParams{
791 Rule: javadoc,
792 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800793 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800794 ImplicitOutput: j.docZip,
795 Inputs: j.srcFiles,
796 Implicits: implicits,
797 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700798 "outDir": android.PathForModuleOut(ctx, "out").String(),
799 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
800 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800801 "srcJars": strings.Join(j.srcJars.Strings(), " "),
802 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700803 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800804 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700805 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800806 "docZip": j.docZip.String(),
807 },
808 })
809}
810
Nan Zhanga40da042018-08-01 12:48:00 -0700811//
812// Droiddoc
813//
814type Droiddoc struct {
815 Javadoc
816
817 properties DroiddocProperties
818 apiFile android.WritablePath
819 dexApiFile android.WritablePath
820 privateApiFile android.WritablePath
821 privateDexApiFile android.WritablePath
822 removedApiFile android.WritablePath
823 removedDexApiFile android.WritablePath
824 exactApiFile android.WritablePath
825 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700826 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700827
828 checkCurrentApiTimestamp android.WritablePath
829 updateCurrentApiTimestamp android.WritablePath
830 checkLastReleasedApiTimestamp android.WritablePath
831
Nan Zhanga40da042018-08-01 12:48:00 -0700832 apiFilePath android.Path
833}
834
Nan Zhanga40da042018-08-01 12:48:00 -0700835func DroiddocFactory() android.Module {
836 module := &Droiddoc{}
837
838 module.AddProperties(&module.properties,
839 &module.Javadoc.properties)
840
841 InitDroiddocModule(module, android.HostAndDeviceSupported)
842 return module
843}
844
845func DroiddocHostFactory() android.Module {
846 module := &Droiddoc{}
847
848 module.AddProperties(&module.properties,
849 &module.Javadoc.properties)
850
851 InitDroiddocModule(module, android.HostSupported)
852 return module
853}
854
855func (d *Droiddoc) ApiFilePath() android.Path {
856 return d.apiFilePath
857}
858
Nan Zhang581fd212018-01-10 16:06:12 -0800859func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
860 d.Javadoc.addDeps(ctx)
861
Inseob Kim38449af2019-02-28 14:24:05 +0900862 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
863 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
864 }
865
Nan Zhang79614d12018-04-19 18:03:39 -0700866 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800867 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
868 }
Nan Zhang581fd212018-01-10 16:06:12 -0800869}
870
Nan Zhang66dc2362018-08-14 20:41:04 -0700871func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
872 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700873 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800874
Nan Zhanga40da042018-08-01 12:48:00 -0700875 *implicits = append(*implicits, deps.bootClasspath...)
876 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800877
Nan Zhangc94f9d82018-06-26 10:02:26 -0700878 if len(deps.bootClasspath.Strings()) > 0 {
879 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700880 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700881 }
Nan Zhanga40da042018-08-01 12:48:00 -0700882 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700883 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700884 dokkaClasspath := classpath{}
885 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
886 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
887 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700888
Nan Zhang9c69a122018-08-22 10:22:08 -0700889 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
890 // based stubs generation.
891 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
892 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
893 // the correct package name base path.
894 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
895 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
896 } else {
897 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
898 }
Nan Zhang581fd212018-01-10 16:06:12 -0800899
Nan Zhanga40da042018-08-01 12:48:00 -0700900 return flags, nil
901}
Nan Zhang581fd212018-01-10 16:06:12 -0800902
Nan Zhanga40da042018-08-01 12:48:00 -0700903func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700904 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800905
Nan Zhanga40da042018-08-01 12:48:00 -0700906 *implicits = append(*implicits, jsilver)
907 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700908
Nan Zhang46130972018-06-04 11:28:01 -0700909 var date string
910 if runtime.GOOS == "darwin" {
911 date = `date -r`
912 } else {
913 date = `date -d`
914 }
915
Nan Zhang443fa522018-08-20 20:58:28 -0700916 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
917 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
918 // 1.9 language features.
919 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700920 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800921 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang79614d12018-04-19 18:03:39 -0700922 `-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700923
Nan Zhanga40da042018-08-01 12:48:00 -0700924 if String(d.properties.Custom_template) == "" {
925 // TODO: This is almost always droiddoc-templates-sdk
926 ctx.PropertyErrorf("custom_template", "must specify a template")
927 }
928
929 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700930 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700931 *implicits = append(*implicits, t.deps...)
932 args = args + " -templatedir " + t.dir.String()
933 } else {
934 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
935 }
936 })
937
938 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800939 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800940 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800941 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700942 }
943
944 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800945 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800946 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800947 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700948 }
949
950 if len(d.properties.Html_dirs) > 2 {
951 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
952 }
953
Colin Cross8a497952019-03-05 22:25:09 -0800954 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700955 *implicits = append(*implicits, knownTags...)
956
957 for _, kt := range knownTags {
958 args = args + " -knowntags " + kt.String()
959 }
960
961 for _, hdf := range d.properties.Hdf {
962 args = args + " -hdf " + hdf
963 }
964
965 if String(d.properties.Proofread_file) != "" {
966 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
967 args = args + " -proofread " + proofreadFile.String()
968 }
969
970 if String(d.properties.Todo_file) != "" {
971 // tricky part:
972 // we should not compute full path for todo_file through PathForModuleOut().
973 // the non-standard doclet will get the full path relative to "-o".
974 args = args + " -todo " + String(d.properties.Todo_file)
975 }
976
977 if String(d.properties.Resourcesdir) != "" {
978 // TODO: should we add files under resourcesDir to the implicits? It seems that
979 // resourcesDir is one sub dir of htmlDir
980 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
981 args = args + " -resourcesdir " + resourcesDir.String()
982 }
983
984 if String(d.properties.Resourcesoutdir) != "" {
985 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
986 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
987 }
988 return args
989}
990
Nan Zhang1598a9e2018-09-04 17:14:32 -0700991func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
992 implicitOutputs *android.WritablePaths) string {
993 var doclavaFlags string
994 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
995 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
996 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -0700997 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
998 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -0700999 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1000 d.apiFilePath = d.apiFile
1001 }
1002
Nan Zhang1598a9e2018-09-04 17:14:32 -07001003 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1004 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1005 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001006 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1007 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001008 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1009 }
1010
1011 if String(d.properties.Private_api_filename) != "" {
1012 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1013 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001014 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1015 }
1016
1017 if String(d.properties.Dex_api_filename) != "" {
1018 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1019 doclavaFlags += " -dexApi " + d.dexApiFile.String()
1020 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1021 }
1022
1023 if String(d.properties.Private_dex_api_filename) != "" {
1024 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1025 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001026 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1027 }
1028
1029 if String(d.properties.Removed_dex_api_filename) != "" {
1030 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1031 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001032 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1033 }
1034
1035 if String(d.properties.Exact_api_filename) != "" {
1036 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1037 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001038 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1039 }
1040
1041 if String(d.properties.Dex_mapping_filename) != "" {
1042 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1043 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001044 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1045 }
1046
Nan Zhang66dc2362018-08-14 20:41:04 -07001047 if String(d.properties.Proguard_filename) != "" {
1048 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1049 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -07001050 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1051 }
1052
Nan Zhanga40da042018-08-01 12:48:00 -07001053 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001054 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001055 }
1056
1057 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001058 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001059 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001060
1061 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001062}
1063
1064func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1065 var cmds string
1066 if String(d.properties.Static_doc_index_redirect) != "" {
1067 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1068 "static_doc_index_redirect")
1069 *implicits = append(*implicits, static_doc_index_redirect)
1070 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001071 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001072 }
1073
1074 if String(d.properties.Static_doc_properties) != "" {
1075 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1076 "static_doc_properties")
1077 *implicits = append(*implicits, static_doc_properties)
1078 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001079 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001080 }
1081 return cmds
1082}
1083
Nan Zhang1598a9e2018-09-04 17:14:32 -07001084func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1085 implicitOutputs android.WritablePaths,
1086 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1087 ctx.Build(pctx, android.BuildParams{
1088 Rule: javadoc,
1089 Description: "Doclava",
1090 Output: d.Javadoc.stubsSrcJar,
1091 Inputs: d.Javadoc.srcFiles,
1092 Implicits: implicits,
1093 ImplicitOutputs: implicitOutputs,
1094 Args: map[string]string{
1095 "outDir": android.PathForModuleOut(ctx, "out").String(),
1096 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1097 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1098 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1099 "opts": opts,
1100 "bootclasspathArgs": bootclasspathArgs,
1101 "classpathArgs": classpathArgs,
1102 "sourcepathArgs": sourcepathArgs,
1103 "docZip": d.Javadoc.docZip.String(),
1104 "postDoclavaCmds": postDoclavaCmds,
1105 },
1106 })
1107}
1108
1109func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1110 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1111 ctx.Build(pctx, android.BuildParams{
1112 Rule: apiCheck,
1113 Description: "Doclava Check API",
1114 Output: output,
1115 Inputs: nil,
1116 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1117 checkApiClasspath...),
1118 Args: map[string]string{
1119 "msg": msg,
1120 "classpath": checkApiClasspath.FormJavaClassPath(""),
1121 "opts": opts,
1122 "apiFile": apiFile.String(),
1123 "apiFileToCheck": d.apiFile.String(),
1124 "removedApiFile": removedApiFile.String(),
1125 "removedApiFileToCheck": d.removedApiFile.String(),
1126 },
1127 })
1128}
1129
1130func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1131 classpathArgs, opts string) {
1132 ctx.Build(pctx, android.BuildParams{
1133 Rule: dokka,
1134 Description: "Dokka",
1135 Output: d.Javadoc.stubsSrcJar,
1136 Inputs: d.Javadoc.srcFiles,
1137 Implicits: implicits,
1138 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001139 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1140 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1141 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001142 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1143 "classpathArgs": classpathArgs,
1144 "opts": opts,
1145 "docZip": d.Javadoc.docZip.String(),
1146 },
1147 })
1148}
1149
1150func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1151 deps := d.Javadoc.collectDeps(ctx)
1152
1153 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1154 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1155 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1156 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1157
1158 var implicits android.Paths
1159 implicits = append(implicits, d.Javadoc.srcJars...)
1160 implicits = append(implicits, d.Javadoc.argFiles...)
1161
1162 var implicitOutputs android.WritablePaths
1163 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1164 for _, o := range d.Javadoc.properties.Out {
1165 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1166 }
1167
1168 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1169 if err != nil {
1170 return
1171 }
1172
1173 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1174 if Bool(d.properties.Dokka_enabled) {
1175 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1176 } else {
1177 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1178 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1179 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1180 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1181 flags.postDoclavaCmds)
1182 }
1183
1184 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1185 !ctx.Config().IsPdkBuild() {
1186 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1187 "check_api.current.api_file")
1188 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1189 "check_api.current_removed_api_file")
1190
1191 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1192 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1193 fmt.Sprintf(`\n******************************\n`+
1194 `You have tried to change the API from what has been previously approved.\n\n`+
1195 `To make these errors go away, you have two choices:\n`+
1196 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1197 ` errors above.\n\n`+
1198 ` 2. You can update current.txt by executing the following command:\n`+
1199 ` make %s-update-current-api\n\n`+
1200 ` To submit the revised current.txt to the main Android repository,\n`+
1201 ` you will need approval.\n`+
1202 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1203 d.checkCurrentApiTimestamp)
1204
1205 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1206 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1207 d.updateCurrentApiTimestamp)
1208 }
1209
1210 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1211 !ctx.Config().IsPdkBuild() {
1212 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1213 "check_api.last_released.api_file")
1214 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1215 "check_api.last_released.removed_api_file")
1216
1217 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1218 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1219 `\n******************************\n`+
1220 `You have tried to change the API from what has been previously released in\n`+
1221 `an SDK. Please fix the errors listed above.\n`+
1222 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1223 d.checkLastReleasedApiTimestamp)
1224 }
1225}
1226
1227//
1228// Droidstubs
1229//
1230type Droidstubs struct {
1231 Javadoc
1232
Pete Gillin581d6082018-10-22 15:55:04 +01001233 properties DroidstubsProperties
1234 apiFile android.WritablePath
1235 apiXmlFile android.WritablePath
1236 lastReleasedApiXmlFile android.WritablePath
1237 dexApiFile android.WritablePath
1238 privateApiFile android.WritablePath
1239 privateDexApiFile android.WritablePath
1240 removedApiFile android.WritablePath
1241 removedDexApiFile android.WritablePath
1242 apiMappingFile android.WritablePath
1243 exactApiFile android.WritablePath
1244 proguardFile android.WritablePath
1245 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001246
1247 checkCurrentApiTimestamp android.WritablePath
1248 updateCurrentApiTimestamp android.WritablePath
1249 checkLastReleasedApiTimestamp android.WritablePath
1250
Pete Gillin581d6082018-10-22 15:55:04 +01001251 checkNullabilityWarningsTimestamp android.WritablePath
1252
Nan Zhang1598a9e2018-09-04 17:14:32 -07001253 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001254 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001255
1256 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001257
1258 jdiffDocZip android.WritablePath
1259 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001260}
1261
1262func DroidstubsFactory() android.Module {
1263 module := &Droidstubs{}
1264
1265 module.AddProperties(&module.properties,
1266 &module.Javadoc.properties)
1267
1268 InitDroiddocModule(module, android.HostAndDeviceSupported)
1269 return module
1270}
1271
1272func DroidstubsHostFactory() android.Module {
1273 module := &Droidstubs{}
1274
1275 module.AddProperties(&module.properties,
1276 &module.Javadoc.properties)
1277
1278 InitDroiddocModule(module, android.HostSupported)
1279 return module
1280}
1281
1282func (d *Droidstubs) ApiFilePath() android.Path {
1283 return d.apiFilePath
1284}
1285
1286func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1287 d.Javadoc.addDeps(ctx)
1288
Inseob Kim38449af2019-02-28 14:24:05 +09001289 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1290 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1291 }
1292
Nan Zhang1598a9e2018-09-04 17:14:32 -07001293 if len(d.properties.Merge_annotations_dirs) != 0 {
1294 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1295 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1296 }
1297 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001298
Pete Gillin77167902018-09-19 18:16:26 +01001299 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1300 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1301 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1302 }
1303 }
1304
Nan Zhang9c69a122018-08-22 10:22:08 -07001305 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1306 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1307 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1308 }
1309 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001310}
1311
1312func (d *Droidstubs) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
1313 deps deps) (droiddocBuilderFlags, error) {
1314 var flags droiddocBuilderFlags
1315
1316 *implicits = append(*implicits, deps.bootClasspath...)
1317 *implicits = append(*implicits, deps.classpath...)
1318
1319 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
1320 // since it doesn't support system modules yet.
1321 if len(deps.bootClasspath.Strings()) > 0 {
1322 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
1323 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
1324 }
1325 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
1326
Sundong Ahn56dce442018-10-05 18:41:09 +09001327 flags.sourcepathArgs = "-sourcepath \"" + strings.Join(d.Javadoc.sourcepaths.Strings(), ":") + "\""
Nan Zhang1598a9e2018-09-04 17:14:32 -07001328 return flags, nil
1329}
1330
1331func (d *Droidstubs) collectStubsFlags(ctx android.ModuleContext,
1332 implicitOutputs *android.WritablePaths) string {
1333 var metalavaFlags string
1334 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1335 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1336 String(d.properties.Api_filename) != "" {
1337 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1338 metalavaFlags = metalavaFlags + " --api " + d.apiFile.String()
1339 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1340 d.apiFilePath = d.apiFile
1341 }
1342
1343 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1344 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1345 String(d.properties.Removed_api_filename) != "" {
1346 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1347 metalavaFlags = metalavaFlags + " --removed-api " + d.removedApiFile.String()
1348 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1349 }
1350
1351 if String(d.properties.Private_api_filename) != "" {
1352 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1353 metalavaFlags = metalavaFlags + " --private-api " + d.privateApiFile.String()
1354 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1355 }
1356
1357 if String(d.properties.Dex_api_filename) != "" {
1358 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1359 metalavaFlags += " --dex-api " + d.dexApiFile.String()
1360 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1361 }
1362
1363 if String(d.properties.Private_dex_api_filename) != "" {
1364 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1365 metalavaFlags = metalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
1366 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1367 }
1368
1369 if String(d.properties.Removed_dex_api_filename) != "" {
1370 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1371 metalavaFlags = metalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
1372 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1373 }
1374
1375 if String(d.properties.Exact_api_filename) != "" {
1376 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1377 metalavaFlags = metalavaFlags + " --exact-api " + d.exactApiFile.String()
1378 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1379 }
1380
Nan Zhang9c69a122018-08-22 10:22:08 -07001381 if String(d.properties.Dex_mapping_filename) != "" {
1382 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1383 metalavaFlags = metalavaFlags + " --dex-api-mapping " + d.apiMappingFile.String()
1384 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1385 }
1386
Nan Zhang199645c2018-09-19 12:40:06 -07001387 if String(d.properties.Proguard_filename) != "" {
1388 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1389 metalavaFlags += " --proguard " + d.proguardFile.String()
1390 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1391 }
1392
Nan Zhang9c69a122018-08-22 10:22:08 -07001393 if Bool(d.properties.Write_sdk_values) {
1394 metalavaFlags = metalavaFlags + " --sdk-values " + android.PathForModuleOut(ctx, "out").String()
1395 }
1396
Nan Zhang1598a9e2018-09-04 17:14:32 -07001397 if Bool(d.properties.Create_doc_stubs) {
1398 metalavaFlags += " --doc-stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1399 } else {
1400 metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1401 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001402 return metalavaFlags
1403}
1404
1405func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
Nan Zhangdee152b2018-12-26 16:06:37 -08001406 implicits *android.Paths, implicitOutputs *android.WritablePaths) (string, string) {
1407 var flags, mergeAnnoDirFlags string
Nan Zhang1598a9e2018-09-04 17:14:32 -07001408 if Bool(d.properties.Annotations_enabled) {
Pete Gillina262c052018-09-14 14:25:48 +01001409 flags += " --include-annotations"
Pete Gillinc382a562018-11-14 18:45:46 +00001410 validatingNullability :=
1411 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1412 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001413 migratingNullability := String(d.properties.Previous_api) != ""
1414 if !(migratingNullability || validatingNullability) {
1415 ctx.PropertyErrorf("previous_api",
1416 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001417 }
Pete Gillina262c052018-09-14 14:25:48 +01001418 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001419 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Pete Gillina262c052018-09-14 14:25:48 +01001420 *implicits = append(*implicits, previousApi)
1421 flags += " --migrate-nullness " + previousApi.String()
1422 }
Pete Gillinc382a562018-11-14 18:45:46 +00001423 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross8a497952019-03-05 22:25:09 -08001424 flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
Pete Gillinc382a562018-11-14 18:45:46 +00001425 }
Pete Gillina262c052018-09-14 14:25:48 +01001426 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001427 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
1428 *implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
1429 flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
Pete Gillina262c052018-09-14 14:25:48 +01001430 }
Nan Zhanga40da042018-08-01 12:48:00 -07001431
1432 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
1433 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
1434
Nan Zhangf4936b02018-08-01 15:00:28 -07001435 flags += " --extract-annotations " + d.annotationsZip.String()
1436
Nan Zhang1598a9e2018-09-04 17:14:32 -07001437 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001438 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001439 "has to be non-empty if annotations was enabled!")
1440 }
Nan Zhangf4936b02018-08-01 15:00:28 -07001441 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1442 if t, ok := m.(*ExportedDroiddocDir); ok {
1443 *implicits = append(*implicits, t.deps...)
Nan Zhangdee152b2018-12-26 16:06:37 -08001444 mergeAnnoDirFlags += " --merge-qualifier-annotations " + t.dir.String()
Nan Zhangf4936b02018-08-01 15:00:28 -07001445 } else {
Nan Zhang9c69a122018-08-22 10:22:08 -07001446 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhangf4936b02018-08-01 15:00:28 -07001447 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1448 }
1449 })
Nan Zhangdee152b2018-12-26 16:06:37 -08001450 flags += mergeAnnoDirFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001451 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001452 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
Nan Zhanga40da042018-08-01 12:48:00 -07001453 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001454
Nan Zhangdee152b2018-12-26 16:06:37 -08001455 return flags, mergeAnnoDirFlags
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001456}
1457
1458func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
1459 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1460 var flags string
Pete Gillin77167902018-09-19 18:16:26 +01001461 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1462 if t, ok := m.(*ExportedDroiddocDir); ok {
1463 *implicits = append(*implicits, t.deps...)
1464 flags += " --merge-inclusion-annotations " + t.dir.String()
1465 } else {
1466 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1467 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1468 }
1469 })
Nan Zhanga40da042018-08-01 12:48:00 -07001470
1471 return flags
1472}
1473
Nan Zhang9c69a122018-08-22 10:22:08 -07001474func (d *Droidstubs) collectAPILevelsAnnotationsFlags(ctx android.ModuleContext,
1475 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1476 var flags string
1477 if Bool(d.properties.Api_levels_annotations_enabled) {
1478 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1479 *implicitOutputs = append(*implicitOutputs, d.apiVersionsXml)
1480
1481 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1482 ctx.PropertyErrorf("api_levels_annotations_dirs",
1483 "has to be non-empty if api levels annotations was enabled!")
1484 }
1485
1486 flags = " --generate-api-levels " + d.apiVersionsXml.String() + " --apply-api-levels " +
1487 d.apiVersionsXml.String() + " --current-version " + ctx.Config().PlatformSdkVersion() +
1488 " --current-codename " + ctx.Config().PlatformSdkCodename() + " "
1489
1490 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1491 if t, ok := m.(*ExportedDroiddocDir); ok {
1492 var androidJars android.Paths
1493 for _, dep := range t.deps {
1494 if strings.HasSuffix(dep.String(), "android.jar") {
1495 androidJars = append(androidJars, dep)
1496 }
1497 }
1498 *implicits = append(*implicits, androidJars...)
Tor Norbyeebcdfed2019-01-24 11:05:46 -08001499 flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
Nan Zhang9c69a122018-08-22 10:22:08 -07001500 } else {
1501 ctx.PropertyErrorf("api_levels_annotations_dirs",
1502 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1503 }
1504 })
1505
1506 }
1507
1508 return flags
1509}
1510
Nan Zhang71bbe632018-09-17 14:32:21 -07001511func (d *Droidstubs) collectApiToXmlFlags(ctx android.ModuleContext, implicits *android.Paths,
1512 implicitOutputs *android.WritablePaths) string {
1513 var flags string
1514 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1515 if d.apiFile.String() == "" {
1516 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1517 }
1518
1519 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
1520 *implicitOutputs = append(*implicitOutputs, d.apiXmlFile)
1521
1522 flags = " --api-xml " + d.apiXmlFile.String()
1523
1524 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1525 ctx.PropertyErrorf("check_api.last_released.api_file",
1526 "has to be non-empty if jdiff was enabled!")
1527 }
1528 lastReleasedApi := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1529 "check_api.last_released.api_file")
1530 *implicits = append(*implicits, lastReleasedApi)
1531
1532 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
1533 *implicitOutputs = append(*implicitOutputs, d.lastReleasedApiXmlFile)
1534
1535 flags += " --convert-to-jdiff " + lastReleasedApi.String() + " " +
1536 d.lastReleasedApiXmlFile.String()
1537 }
1538
1539 return flags
1540}
1541
Nan Zhang1598a9e2018-09-04 17:14:32 -07001542func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
1543 implicitOutputs android.WritablePaths, javaVersion,
1544 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001545
Nan Zhang86d2d552018-08-09 15:33:27 -07001546 ctx.Build(pctx, android.BuildParams{
1547 Rule: metalava,
1548 Description: "Metalava",
1549 Output: d.Javadoc.stubsSrcJar,
1550 Inputs: d.Javadoc.srcFiles,
1551 Implicits: implicits,
1552 ImplicitOutputs: implicitOutputs,
1553 Args: map[string]string{
Nan Zhang86d2d552018-08-09 15:33:27 -07001554 "outDir": android.PathForModuleOut(ctx, "out").String(),
1555 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1556 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1557 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001558 "javaVersion": javaVersion,
Nan Zhang86d2d552018-08-09 15:33:27 -07001559 "bootclasspathArgs": bootclasspathArgs,
1560 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001561 "sourcepathArgs": sourcepathArgs,
1562 "opts": opts,
Nan Zhang86d2d552018-08-09 15:33:27 -07001563 },
1564 })
1565}
1566
Nan Zhang1598a9e2018-09-04 17:14:32 -07001567func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
Adrian Roos4937c4a2019-08-12 17:54:09 +02001568 apiFile, removedApiFile android.Path, baselineFile android.OptionalPath, updatedBaselineOut android.WritablePath, implicits android.Paths,
Colin Cross39c16792019-01-24 16:32:44 -08001569 javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001570 output android.WritablePath) {
Adrian Roos4937c4a2019-08-12 17:54:09 +02001571
1572 implicits = append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile}, implicits...)
1573 var implicitOutputs android.WritablePaths
1574
1575 if baselineFile.Valid() {
1576 implicits = append(implicits, baselineFile.Path())
1577 implicitOutputs = append(implicitOutputs, updatedBaselineOut)
1578 }
1579
Nan Zhang2760dfc2018-08-24 17:32:54 +00001580 ctx.Build(pctx, android.BuildParams{
Adrian Roos4937c4a2019-08-12 17:54:09 +02001581 Rule: metalavaApiCheck,
1582 Description: "Metalava Check API",
1583 Output: output,
1584 Inputs: d.Javadoc.srcFiles,
1585 Implicits: implicits,
1586 ImplicitOutputs: implicitOutputs,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001587 Args: map[string]string{
Colin Cross39c16792019-01-24 16:32:44 -08001588 "srcJarDir": android.PathForModuleOut(ctx, subdir, "srcjars").String(),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001589 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1590 "javaVersion": javaVersion,
1591 "bootclasspathArgs": bootclasspathArgs,
1592 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001593 "sourcepathArgs": sourcepathArgs,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001594 "opts": opts,
1595 "msg": msg,
1596 },
1597 })
1598}
1599
Nan Zhang71bbe632018-09-17 14:32:21 -07001600func (d *Droidstubs) transformJdiff(ctx android.ModuleContext, implicits android.Paths,
1601 implicitOutputs android.WritablePaths,
1602 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
1603 ctx.Build(pctx, android.BuildParams{
1604 Rule: javadoc,
1605 Description: "Jdiff",
1606 Output: d.jdiffStubsSrcJar,
1607 Inputs: d.Javadoc.srcFiles,
1608 Implicits: implicits,
1609 ImplicitOutputs: implicitOutputs,
1610 Args: map[string]string{
Nan Zhang23a1ba62018-09-19 11:19:39 -07001611 "outDir": android.PathForModuleOut(ctx, "jdiff-out").String(),
1612 "srcJarDir": android.PathForModuleOut(ctx, "jdiff-srcjars").String(),
1613 "stubsDir": android.PathForModuleOut(ctx, "jdiff-stubsDir").String(),
Nan Zhang71bbe632018-09-17 14:32:21 -07001614 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1615 "opts": opts,
1616 "bootclasspathArgs": bootclasspathArgs,
1617 "classpathArgs": classpathArgs,
1618 "sourcepathArgs": sourcepathArgs,
1619 "docZip": d.jdiffDocZip.String(),
1620 },
1621 })
1622}
1623
Nan Zhang1598a9e2018-09-04 17:14:32 -07001624func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001625 deps := d.Javadoc.collectDeps(ctx)
1626
1627 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001628
Nan Zhanga40da042018-08-01 12:48:00 -07001629 var implicits android.Paths
1630 implicits = append(implicits, d.Javadoc.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001631 implicits = append(implicits, d.Javadoc.argFiles...)
Nan Zhanga40da042018-08-01 12:48:00 -07001632
1633 var implicitOutputs android.WritablePaths
Nan Zhang1598a9e2018-09-04 17:14:32 -07001634 for _, o := range d.Javadoc.properties.Out {
Nan Zhanga40da042018-08-01 12:48:00 -07001635 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1636 }
1637
1638 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
Nan Zhang2760dfc2018-08-24 17:32:54 +00001639 metalavaCheckApiImplicits := implicits
Nan Zhang71bbe632018-09-17 14:32:21 -07001640 jdiffImplicits := implicits
1641
Nan Zhanga40da042018-08-01 12:48:00 -07001642 if err != nil {
1643 return
1644 }
1645
Nan Zhang1598a9e2018-09-04 17:14:32 -07001646 flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
Nan Zhangdee152b2018-12-26 16:06:37 -08001647 flags.metalavaAnnotationsFlags, flags.metalavaMergeAnnoDirFlags =
1648 d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001649 flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang9c69a122018-08-22 10:22:08 -07001650 flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang71bbe632018-09-17 14:32:21 -07001651 flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
1652
Nan Zhang1598a9e2018-09-04 17:14:32 -07001653 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1654 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1655 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1656 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1657 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001658 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001659 d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
1660 flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001661 flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
Nan Zhang71bbe632018-09-17 14:32:21 -07001662 flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
Nan Zhang61819ce2018-05-04 18:49:16 -07001663
Nan Zhang1598a9e2018-09-04 17:14:32 -07001664 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1665 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001666 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1667 "check_api.current.api_file")
1668 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1669 "check_api.current_removed_api_file")
Adrian Roos4937c4a2019-08-12 17:54:09 +02001670 baselineFile := ctx.ExpandOptionalSource(d.properties.Check_api.Current.Baseline_file,
1671 "check_api.current.baseline_file")
Nan Zhang61819ce2018-05-04 18:49:16 -07001672
Nan Zhang2760dfc2018-08-24 17:32:54 +00001673 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001674 opts := " " + d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
1675 " --check-compatibility:removed:current " + removedApiFile.String() +
Nan Zhangdee152b2018-12-26 16:06:37 -08001676 flags.metalavaInclusionAnnotationsFlags + flags.metalavaMergeAnnoDirFlags + " "
Adrian Roos4937c4a2019-08-12 17:54:09 +02001677 baselineOut := android.PathForModuleOut(ctx, "current_baseline.txt")
1678 if baselineFile.Valid() {
1679 opts = opts + "--baseline " + baselineFile.String() + " --update-baseline " + baselineOut.String() + " "
1680 }
Nan Zhang2760dfc2018-08-24 17:32:54 +00001681
Adrian Roos4937c4a2019-08-12 17:54:09 +02001682 d.transformCheckApi(ctx, apiFile, removedApiFile, baselineFile, baselineOut, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001683 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001684 fmt.Sprintf(`\n******************************\n`+
1685 `You have tried to change the API from what has been previously approved.\n\n`+
1686 `To make these errors go away, you have two choices:\n`+
1687 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1688 ` errors above.\n\n`+
1689 ` 2. You can update current.txt by executing the following command:\n`+
1690 ` make %s-update-current-api\n\n`+
1691 ` To submit the revised current.txt to the main Android repository,\n`+
1692 ` you will need approval.\n`+
1693 `******************************\n`, ctx.ModuleName()),
1694 d.checkCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001695
1696 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001697 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1698 d.updateCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001699 }
Nan Zhanga40da042018-08-01 12:48:00 -07001700
Nan Zhang1598a9e2018-09-04 17:14:32 -07001701 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1702 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001703 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1704 "check_api.last_released.api_file")
1705 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1706 "check_api.last_released.removed_api_file")
Adrian Roos4937c4a2019-08-12 17:54:09 +02001707 baselineFile := ctx.ExpandOptionalSource(d.properties.Check_api.Last_released.Baseline_file,
1708 "check_api.last_released.baseline_file")
Nan Zhang61819ce2018-05-04 18:49:16 -07001709
Nan Zhang2760dfc2018-08-24 17:32:54 +00001710 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001711 opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
1712 flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
Nan Zhangdee152b2018-12-26 16:06:37 -08001713 removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
Adrian Roos4937c4a2019-08-12 17:54:09 +02001714 baselineOut := android.PathForModuleOut(ctx, "last_released_baseline.txt")
1715 if baselineFile.Valid() {
1716 opts = opts + "--baseline " + baselineFile.String() + " --update-baseline " + baselineOut.String() + " "
1717 }
Nan Zhang2760dfc2018-08-24 17:32:54 +00001718
Adrian Roos4937c4a2019-08-12 17:54:09 +02001719 d.transformCheckApi(ctx, apiFile, removedApiFile, baselineFile, baselineOut, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001720 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001721 `\n******************************\n`+
1722 `You have tried to change the API from what has been previously released in\n`+
1723 `an SDK. Please fix the errors listed above.\n`+
1724 `******************************\n`,
1725 d.checkLastReleasedApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001726 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001727
Pete Gillin581d6082018-10-22 15:55:04 +01001728 if String(d.properties.Check_nullability_warnings) != "" {
1729 if d.nullabilityWarningsFile == nil {
1730 ctx.PropertyErrorf("check_nullability_warnings",
1731 "Cannot specify check_nullability_warnings unless validating nullability")
1732 }
1733 checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
1734 "check_nullability_warnings")
1735 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
1736 msg := fmt.Sprintf(`\n******************************\n`+
1737 `The warnings encountered during nullability annotation validation did\n`+
1738 `not match the checked in file of expected warnings. The diffs are shown\n`+
1739 `above. You have two options:\n`+
1740 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1741 ` 2. Update the file of expected warnings by running:\n`+
1742 ` cp %s %s\n`+
1743 ` and submitting the updated file as part of your change.`,
1744 d.nullabilityWarningsFile, checkNullabilityWarnings)
1745 ctx.Build(pctx, android.BuildParams{
1746 Rule: nullabilityWarningsCheck,
1747 Description: "Nullability Warnings Check",
1748 Output: d.checkNullabilityWarningsTimestamp,
1749 Implicits: android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
1750 Args: map[string]string{
1751 "expected": checkNullabilityWarnings.String(),
1752 "actual": d.nullabilityWarningsFile.String(),
1753 "msg": msg,
1754 },
1755 })
1756 }
1757
Nan Zhang71bbe632018-09-17 14:32:21 -07001758 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1759
Nan Zhang86b06202018-09-21 17:09:21 -07001760 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1761 // since there's cron job downstream that fetch this .zip file periodically.
1762 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001763 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1764 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1765
1766 var jdiffImplicitOutputs android.WritablePaths
1767 jdiffImplicitOutputs = append(jdiffImplicitOutputs, d.jdiffDocZip)
1768
1769 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
1770 jdiffImplicits = append(jdiffImplicits, android.Paths{jdiff, d.apiXmlFile, d.lastReleasedApiXmlFile}...)
1771
1772 opts := " -encoding UTF-8 -source 1.8 -J-Xmx1600m -XDignore.symbol.file " +
1773 "-doclet jdiff.JDiff -docletpath " + jdiff.String() + " -quiet " +
1774 "-newapi " + strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext()) +
1775 " -newapidir " + filepath.Dir(d.apiXmlFile.String()) +
1776 " -oldapi " + strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext()) +
1777 " -oldapidir " + filepath.Dir(d.lastReleasedApiXmlFile.String())
1778
1779 d.transformJdiff(ctx, jdiffImplicits, jdiffImplicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1780 flags.sourcepathArgs, opts)
1781 }
Nan Zhang581fd212018-01-10 16:06:12 -08001782}
Dan Willemsencc090972018-02-26 14:33:31 -08001783
Nan Zhanga40da042018-08-01 12:48:00 -07001784//
Nan Zhangf4936b02018-08-01 15:00:28 -07001785// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001786//
Dan Willemsencc090972018-02-26 14:33:31 -08001787var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001788var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001789var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001790var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001791
Nan Zhangf4936b02018-08-01 15:00:28 -07001792type ExportedDroiddocDirProperties struct {
1793 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001794 Path *string
1795}
1796
Nan Zhangf4936b02018-08-01 15:00:28 -07001797type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001798 android.ModuleBase
1799
Nan Zhangf4936b02018-08-01 15:00:28 -07001800 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001801
1802 deps android.Paths
1803 dir android.Path
1804}
1805
Nan Zhangf4936b02018-08-01 15:00:28 -07001806func ExportedDroiddocDirFactory() android.Module {
1807 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001808 module.AddProperties(&module.properties)
1809 android.InitAndroidModule(module)
1810 return module
1811}
1812
Nan Zhangf4936b02018-08-01 15:00:28 -07001813func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001814
Nan Zhangf4936b02018-08-01 15:00:28 -07001815func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001816 path := String(d.properties.Path)
1817 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001818 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001819}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001820
1821//
1822// Defaults
1823//
1824type DocDefaults struct {
1825 android.ModuleBase
1826 android.DefaultsModuleBase
1827}
1828
1829func (*DocDefaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1830}
1831
Nan Zhangb2b33de2018-02-23 11:18:47 -08001832func DocDefaultsFactory() android.Module {
1833 module := &DocDefaults{}
1834
1835 module.AddProperties(
1836 &JavadocProperties{},
1837 &DroiddocProperties{},
1838 )
1839
1840 android.InitDefaultsModule(module)
1841
1842 return module
1843}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001844
1845func StubsDefaultsFactory() android.Module {
1846 module := &DocDefaults{}
1847
1848 module.AddProperties(
1849 &JavadocProperties{},
1850 &DroidstubsProperties{},
1851 )
1852
1853 android.InitDefaultsModule(module)
1854
1855 return module
1856}