blob: e1476a27ff62c6f54767a5e780fbd2f949ecd489 [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 && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -070076 `${config.JavaCmd} ${config.JavaVmFlags} -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 && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -070098 `${config.JavaCmd} ${config.JavaVmFlags} -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 && ` +
Sasha Smundak26c6d9e2019-06-11 13:30:13 -0700123 `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.DokkaJar} $srcJarDir ` +
Nan Zhang1598a9e2018-09-04 17:14:32 -0700124 `$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>
Colin Crosse4a05842019-05-28 10:17:14 -0700214 // $$: a literal $
Nan Zhang1598a9e2018-09-04 17:14:32 -0700215 Args *string
216
217 // names of the output files used in args that will be generated
218 Out []string
Nan Zhang581fd212018-01-10 16:06:12 -0800219}
220
Nan Zhang61819ce2018-05-04 18:49:16 -0700221type ApiToCheck struct {
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900222 // path to the API txt file that the new API extracted from source code is checked
223 // against. The path can be local to the module or from other module (via :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800224 Api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700225
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900226 // path to the API txt file that the new @removed API extractd from source code is
227 // checked against. The path can be local to the module or from other module (via
228 // :module syntax).
Colin Cross27b922f2019-03-04 22:35:41 -0800229 Removed_api_file *string `android:"path"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700230
Jiyong Parkeeb8a642018-05-12 22:21:20 +0900231 // Arguments to the apicheck tool.
Nan Zhang61819ce2018-05-04 18:49:16 -0700232 Args *string
233}
234
Nan Zhang581fd212018-01-10 16:06:12 -0800235type DroiddocProperties struct {
236 // directory relative to top of the source tree that contains doc templates files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800237 Custom_template *string
Nan Zhang581fd212018-01-10 16:06:12 -0800238
Nan Zhanga40da042018-08-01 12:48:00 -0700239 // directories under current module source which contains html/jd files.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800240 Html_dirs []string
Nan Zhang581fd212018-01-10 16:06:12 -0800241
242 // set a value in the Clearsilver hdf namespace.
Nan Zhangb2b33de2018-02-23 11:18:47 -0800243 Hdf []string
Nan Zhang581fd212018-01-10 16:06:12 -0800244
245 // proofread file contains all of the text content of the javadocs concatenated into one file,
246 // suitable for spell-checking and other goodness.
Colin Cross27b922f2019-03-04 22:35:41 -0800247 Proofread_file *string `android:"path"`
Nan Zhang581fd212018-01-10 16:06:12 -0800248
249 // a todo file lists the program elements that are missing documentation.
250 // At some point, this might be improved to show more warnings.
Colin Cross27b922f2019-03-04 22:35:41 -0800251 Todo_file *string `android:"path"`
Nan Zhangb2b33de2018-02-23 11:18:47 -0800252
253 // directory under current module source that provide additional resources (images).
254 Resourcesdir *string
255
256 // resources output directory under out/soong/.intermediates.
257 Resourcesoutdir *string
Nan Zhang581fd212018-01-10 16:06:12 -0800258
Nan Zhange2ba5d42018-07-11 15:16:55 -0700259 // if set to true, collect the values used by the Dev tools and
260 // write them in files packaged with the SDK. Defaults to false.
261 Write_sdk_values *bool
262
263 // index.html under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800264 Static_doc_index_redirect *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700265
266 // source.properties under current module will be copied to docs out dir, if not null.
Colin Cross27b922f2019-03-04 22:35:41 -0800267 Static_doc_properties *string `android:"path"`
Nan Zhange2ba5d42018-07-11 15:16:55 -0700268
Nan Zhang581fd212018-01-10 16:06:12 -0800269 // a list of files under current module source dir which contains known tags in Java sources.
270 // filegroup or genrule can be included within this property.
Colin Cross27b922f2019-03-04 22:35:41 -0800271 Knowntags []string `android:"path"`
Nan Zhang28c68b92018-03-13 16:17:01 -0700272
273 // the tag name used to distinguish if the API files belong to public/system/test.
274 Api_tag_name *string
275
276 // the generated public API filename by Doclava.
277 Api_filename *string
278
David Brazdilfbe4cc32018-05-31 13:56:46 +0100279 // the generated public Dex API filename by Doclava.
280 Dex_api_filename *string
281
Nan Zhang28c68b92018-03-13 16:17:01 -0700282 // the generated private API filename by Doclava.
283 Private_api_filename *string
284
285 // the generated private Dex API filename by Doclava.
286 Private_dex_api_filename *string
287
288 // the generated removed API filename by Doclava.
289 Removed_api_filename *string
290
David Brazdilaac0c3c2018-04-24 16:23:29 +0100291 // the generated removed Dex API filename by Doclava.
292 Removed_dex_api_filename *string
293
Mathew Inwood76c3de12018-06-22 15:28:11 +0100294 // mapping of dex signatures to source file and line number. This is a temporary property and
295 // will be deleted; you probably shouldn't be using it.
296 Dex_mapping_filename *string
297
Nan Zhang28c68b92018-03-13 16:17:01 -0700298 // the generated exact API filename by Doclava.
299 Exact_api_filename *string
Nan Zhang853f4202018-04-12 16:55:56 -0700300
Nan Zhang66dc2362018-08-14 20:41:04 -0700301 // the generated proguard filename by Doclava.
302 Proguard_filename *string
303
Nan Zhang853f4202018-04-12 16:55:56 -0700304 // if set to false, don't allow droiddoc to generate stubs source files. Defaults to true.
305 Create_stubs *bool
Nan Zhang61819ce2018-05-04 18:49:16 -0700306
307 Check_api struct {
308 Last_released ApiToCheck
309
310 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900311
312 // do not perform API check against Last_released, in the case that both two specified API
313 // files by Last_released are modules which don't exist.
314 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang61819ce2018-05-04 18:49:16 -0700315 }
Nan Zhang79614d12018-04-19 18:03:39 -0700316
Nan Zhang1598a9e2018-09-04 17:14:32 -0700317 // if set to true, generate docs through Dokka instead of Doclava.
318 Dokka_enabled *bool
319}
320
321type DroidstubsProperties struct {
322 // the tag name used to distinguish if the API files belong to public/system/test.
323 Api_tag_name *string
324
Nan Zhang199645c2018-09-19 12:40:06 -0700325 // the generated public API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700326 Api_filename *string
327
Nan Zhang199645c2018-09-19 12:40:06 -0700328 // the generated public Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700329 Dex_api_filename *string
330
Nan Zhang199645c2018-09-19 12:40:06 -0700331 // the generated private API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700332 Private_api_filename *string
333
Nan Zhang199645c2018-09-19 12:40:06 -0700334 // the generated private Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700335 Private_dex_api_filename *string
336
Nan Zhang199645c2018-09-19 12:40:06 -0700337 // the generated removed API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700338 Removed_api_filename *string
339
Nan Zhang199645c2018-09-19 12:40:06 -0700340 // the generated removed Dex API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700341 Removed_dex_api_filename *string
342
Nan Zhang9c69a122018-08-22 10:22:08 -0700343 // mapping of dex signatures to source file and line number. This is a temporary property and
344 // will be deleted; you probably shouldn't be using it.
345 Dex_mapping_filename *string
346
Nan Zhang199645c2018-09-19 12:40:06 -0700347 // the generated exact API filename by Metalava.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700348 Exact_api_filename *string
349
Nan Zhang199645c2018-09-19 12:40:06 -0700350 // the generated proguard filename by Metalava.
351 Proguard_filename *string
352
Nan Zhang1598a9e2018-09-04 17:14:32 -0700353 Check_api struct {
354 Last_released ApiToCheck
355
356 Current ApiToCheck
Inseob Kim38449af2019-02-28 14:24:05 +0900357
358 // do not perform API check against Last_released, in the case that both two specified API
359 // files by Last_released are modules which don't exist.
360 Ignore_missing_latest_api *bool `blueprint:"mutated"`
Nan Zhang1598a9e2018-09-04 17:14:32 -0700361 }
Nan Zhang79614d12018-04-19 18:03:39 -0700362
363 // user can specify the version of previous released API file in order to do compatibility check.
Colin Cross27b922f2019-03-04 22:35:41 -0800364 Previous_api *string `android:"path"`
Nan Zhang79614d12018-04-19 18:03:39 -0700365
366 // is set to true, Metalava will allow framework SDK to contain annotations.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700367 Annotations_enabled *bool
Nan Zhang79614d12018-04-19 18:03:39 -0700368
Pete Gillin77167902018-09-19 18:16:26 +0100369 // 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 -0700370 Merge_annotations_dirs []string
Nan Zhang86d2d552018-08-09 15:33:27 -0700371
Pete Gillin77167902018-09-19 18:16:26 +0100372 // a list of top-level directories containing Java stub files to merge show/hide annotations from.
373 Merge_inclusion_annotations_dirs []string
374
Pete Gillinc382a562018-11-14 18:45:46 +0000375 // a file containing a list of classes to do nullability validation for.
376 Validate_nullability_from_list *string
377
Pete Gillin581d6082018-10-22 15:55:04 +0100378 // a file containing expected warnings produced by validation of nullability annotations.
379 Check_nullability_warnings *string
380
Nan Zhang1598a9e2018-09-04 17:14:32 -0700381 // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
382 Create_doc_stubs *bool
Nan Zhang9c69a122018-08-22 10:22:08 -0700383
384 // is set to true, Metalava will allow framework SDK to contain API levels annotations.
385 Api_levels_annotations_enabled *bool
386
387 // the dirs which Metalava extracts API levels annotations from.
388 Api_levels_annotations_dirs []string
389
390 // if set to true, collect the values used by the Dev tools and
391 // write them in files packaged with the SDK. Defaults to false.
392 Write_sdk_values *bool
Nan Zhang71bbe632018-09-17 14:32:21 -0700393
394 // If set to true, .xml based public API file will be also generated, and
395 // JDiff tool will be invoked to genreate javadoc files. Defaults to false.
396 Jdiff_enabled *bool
Nan Zhang581fd212018-01-10 16:06:12 -0800397}
398
Nan Zhanga40da042018-08-01 12:48:00 -0700399//
400// Common flags passed down to build rule
401//
402type droiddocBuilderFlags struct {
Nan Zhang86d2d552018-08-09 15:33:27 -0700403 bootClasspathArgs string
404 classpathArgs string
Nan Zhang1598a9e2018-09-04 17:14:32 -0700405 sourcepathArgs string
Nan Zhang86d2d552018-08-09 15:33:27 -0700406 dokkaClasspathArgs string
407 aidlFlags string
Colin Cross3047fa22019-04-18 10:56:44 -0700408 aidlDeps android.Paths
Nan Zhanga40da042018-08-01 12:48:00 -0700409
Nan Zhanga40da042018-08-01 12:48:00 -0700410 doclavaStubsFlags string
Nan Zhang86d2d552018-08-09 15:33:27 -0700411 doclavaDocsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700412 postDoclavaCmds string
413
Nan Zhang9c69a122018-08-22 10:22:08 -0700414 metalavaStubsFlags string
415 metalavaAnnotationsFlags string
Nan Zhangdee152b2018-12-26 16:06:37 -0800416 metalavaMergeAnnoDirFlags string
Neil Fullerb2f14ec2018-10-21 22:13:19 +0100417 metalavaInclusionAnnotationsFlags string
Nan Zhang9c69a122018-08-22 10:22:08 -0700418 metalavaApiLevelsAnnotationsFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700419
Nan Zhang71bbe632018-09-17 14:32:21 -0700420 metalavaApiToXmlFlags string
Nan Zhanga40da042018-08-01 12:48:00 -0700421}
422
423func InitDroiddocModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
424 android.InitAndroidArchModule(module, hod, android.MultilibCommon)
425 android.InitDefaultableModule(module)
426}
427
Nan Zhang1598a9e2018-09-04 17:14:32 -0700428func apiCheckEnabled(apiToCheck ApiToCheck, apiVersionTag string) bool {
429 if String(apiToCheck.Api_file) != "" && String(apiToCheck.Removed_api_file) != "" {
430 return true
431 } else if String(apiToCheck.Api_file) != "" {
432 panic("for " + apiVersionTag + " removed_api_file has to be non-empty!")
433 } else if String(apiToCheck.Removed_api_file) != "" {
434 panic("for " + apiVersionTag + " api_file has to be non-empty!")
435 }
436
437 return false
438}
439
Inseob Kim38449af2019-02-28 14:24:05 +0900440func ignoreMissingModules(ctx android.BottomUpMutatorContext, apiToCheck *ApiToCheck) {
441 api_file := String(apiToCheck.Api_file)
442 removed_api_file := String(apiToCheck.Removed_api_file)
443
444 api_module := android.SrcIsModule(api_file)
445 removed_api_module := android.SrcIsModule(removed_api_file)
446
447 if api_module == "" || removed_api_module == "" {
448 return
449 }
450
451 if ctx.OtherModuleExists(api_module) || ctx.OtherModuleExists(removed_api_module) {
452 return
453 }
454
455 apiToCheck.Api_file = nil
456 apiToCheck.Removed_api_file = nil
457}
458
Nan Zhang1598a9e2018-09-04 17:14:32 -0700459type ApiFilePath interface {
460 ApiFilePath() android.Path
461}
462
463func transformUpdateApi(ctx android.ModuleContext, destApiFile, destRemovedApiFile,
464 srcApiFile, srcRemovedApiFile android.Path, output android.WritablePath) {
465 ctx.Build(pctx, android.BuildParams{
466 Rule: updateApi,
467 Description: "Update API",
468 Output: output,
469 Implicits: append(android.Paths{}, srcApiFile, srcRemovedApiFile,
470 destApiFile, destRemovedApiFile),
471 Args: map[string]string{
472 "destApiFile": destApiFile.String(),
473 "srcApiFile": srcApiFile.String(),
474 "destRemovedApiFile": destRemovedApiFile.String(),
475 "srcRemovedApiFile": srcRemovedApiFile.String(),
476 },
477 })
478}
479
Nan Zhanga40da042018-08-01 12:48:00 -0700480//
481// Javadoc
482//
Nan Zhang581fd212018-01-10 16:06:12 -0800483type Javadoc struct {
484 android.ModuleBase
485 android.DefaultableModuleBase
486
487 properties JavadocProperties
488
489 srcJars android.Paths
490 srcFiles android.Paths
491 sourcepaths android.Paths
Nan Zhang1598a9e2018-09-04 17:14:32 -0700492 argFiles android.Paths
493
494 args string
Nan Zhang581fd212018-01-10 16:06:12 -0800495
Nan Zhangccff0f72018-03-08 17:26:16 -0800496 docZip android.WritablePath
497 stubsSrcJar android.WritablePath
Nan Zhang581fd212018-01-10 16:06:12 -0800498}
499
Colin Cross41955e82019-05-29 14:40:35 -0700500func (j *Javadoc) OutputFiles(tag string) (android.Paths, error) {
501 switch tag {
502 case "":
503 return android.Paths{j.stubsSrcJar}, nil
504 default:
505 return nil, fmt.Errorf("unsupported module reference tag %q", tag)
506 }
Nan Zhangb2b33de2018-02-23 11:18:47 -0800507}
508
Nan Zhang581fd212018-01-10 16:06:12 -0800509func JavadocFactory() android.Module {
510 module := &Javadoc{}
511
512 module.AddProperties(&module.properties)
513
514 InitDroiddocModule(module, android.HostAndDeviceSupported)
515 return module
516}
517
518func JavadocHostFactory() android.Module {
519 module := &Javadoc{}
520
521 module.AddProperties(&module.properties)
522
523 InitDroiddocModule(module, android.HostSupported)
524 return module
525}
526
Colin Cross41955e82019-05-29 14:40:35 -0700527var _ android.OutputFileProducer = (*Javadoc)(nil)
Nan Zhang581fd212018-01-10 16:06:12 -0800528
Colin Cross83bb3162018-06-25 15:48:06 -0700529func (j *Javadoc) sdkVersion() string {
530 return String(j.properties.Sdk_version)
531}
532
533func (j *Javadoc) minSdkVersion() string {
534 return j.sdkVersion()
535}
536
Dan Willemsen419290a2018-10-31 15:28:47 -0700537func (j *Javadoc) targetSdkVersion() string {
538 return j.sdkVersion()
539}
540
Paul Duffin250e6192019-06-07 10:44:37 +0100541func (j *Javadoc) noFrameworkLibs() bool {
542 return Bool(j.properties.No_framework_libs)
543}
544
545func (j *Javadoc) noStandardLibs() bool {
546 return Bool(j.properties.No_standard_libs)
547}
548
Nan Zhang581fd212018-01-10 16:06:12 -0800549func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
550 if ctx.Device() {
Paul Duffin250e6192019-06-07 10:44:37 +0100551 sdkDep := decodeSdkDep(ctx, sdkContext(j))
552 if sdkDep.hasStandardLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700553 if sdkDep.useDefaultLibs {
554 ctx.AddVariationDependencies(nil, bootClasspathTag, config.DefaultBootclasspathLibraries...)
555 if ctx.Config().TargetOpenJDK9() {
556 ctx.AddVariationDependencies(nil, systemModulesTag, config.DefaultSystemModules)
557 }
Paul Duffin250e6192019-06-07 10:44:37 +0100558 if sdkDep.hasFrameworkLibs() {
Nan Zhang5994b622018-09-21 16:39:51 -0700559 ctx.AddVariationDependencies(nil, libTag, config.DefaultLibraries...)
560 }
561 } else if sdkDep.useModule {
562 if ctx.Config().TargetOpenJDK9() {
563 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules)
564 }
565 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.modules...)
Nan Zhang357466b2018-04-17 17:38:36 -0700566 }
Nan Zhang581fd212018-01-10 16:06:12 -0800567 }
568 }
569
Colin Cross42d48b72018-08-29 14:10:52 -0700570 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700571 if j.properties.Srcs_lib != nil {
Colin Cross42d48b72018-08-29 14:10:52 -0700572 ctx.AddVariationDependencies(nil, srcsLibTag, *j.properties.Srcs_lib)
Colin Crossa1ce2a02018-06-20 15:19:39 -0700573 }
Nan Zhang581fd212018-01-10 16:06:12 -0800574}
575
Nan Zhangb2b33de2018-02-23 11:18:47 -0800576func (j *Javadoc) genWhitelistPathPrefixes(whitelistPathPrefixes map[string]bool) {
577 for _, dir := range j.properties.Srcs_lib_whitelist_dirs {
578 for _, pkg := range j.properties.Srcs_lib_whitelist_pkgs {
Jiyong Park82484c02018-04-23 21:41:26 +0900579 // convert foo.bar.baz to foo/bar/baz
580 pkgAsPath := filepath.Join(strings.Split(pkg, ".")...)
581 prefix := filepath.Join(dir, pkgAsPath)
Nan Zhangb2b33de2018-02-23 11:18:47 -0800582 if _, found := whitelistPathPrefixes[prefix]; !found {
583 whitelistPathPrefixes[prefix] = true
584 }
585 }
586 }
587}
588
Nan Zhanga40da042018-08-01 12:48:00 -0700589func (j *Javadoc) collectAidlFlags(ctx android.ModuleContext, deps deps) droiddocBuilderFlags {
590 var flags droiddocBuilderFlags
Jiyong Park1e440682018-05-23 18:42:04 +0900591
Colin Cross3047fa22019-04-18 10:56:44 -0700592 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs)
Jiyong Park1e440682018-05-23 18:42:04 +0900593
594 return flags
595}
596
597func (j *Javadoc) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath,
Colin Cross3047fa22019-04-18 10:56:44 -0700598 aidlIncludeDirs android.Paths) (string, android.Paths) {
Jiyong Park1e440682018-05-23 18:42:04 +0900599
600 aidlIncludes := android.PathsForModuleSrc(ctx, j.properties.Aidl.Local_include_dirs)
601 aidlIncludes = append(aidlIncludes, android.PathsForSource(ctx, j.properties.Aidl.Include_dirs)...)
602
603 var flags []string
Colin Cross3047fa22019-04-18 10:56:44 -0700604 var deps android.Paths
605
Jiyong Park1e440682018-05-23 18:42:04 +0900606 if aidlPreprocess.Valid() {
607 flags = append(flags, "-p"+aidlPreprocess.String())
Colin Cross3047fa22019-04-18 10:56:44 -0700608 deps = append(deps, aidlPreprocess.Path())
Jiyong Park1e440682018-05-23 18:42:04 +0900609 } else {
610 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I"))
611 }
612
613 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I"))
614 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String())
615 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() {
616 flags = append(flags, "-I"+src.String())
617 }
618
Colin Cross3047fa22019-04-18 10:56:44 -0700619 return strings.Join(flags, " "), deps
Jiyong Park1e440682018-05-23 18:42:04 +0900620}
621
622func (j *Javadoc) genSources(ctx android.ModuleContext, srcFiles android.Paths,
Nan Zhanga40da042018-08-01 12:48:00 -0700623 flags droiddocBuilderFlags) android.Paths {
Jiyong Park1e440682018-05-23 18:42:04 +0900624
625 outSrcFiles := make(android.Paths, 0, len(srcFiles))
626
627 for _, srcFile := range srcFiles {
628 switch srcFile.Ext() {
629 case ".aidl":
Colin Cross3047fa22019-04-18 10:56:44 -0700630 javaFile := genAidl(ctx, srcFile, flags.aidlFlags, flags.aidlDeps)
Jiyong Park1e440682018-05-23 18:42:04 +0900631 outSrcFiles = append(outSrcFiles, javaFile)
Inseob Kimc0907f12019-02-08 21:00:45 +0900632 case ".sysprop":
633 javaFile := genSysprop(ctx, srcFile)
634 outSrcFiles = append(outSrcFiles, javaFile)
Jiyong Park1e440682018-05-23 18:42:04 +0900635 default:
636 outSrcFiles = append(outSrcFiles, srcFile)
637 }
638 }
639
640 return outSrcFiles
641}
642
Nan Zhang581fd212018-01-10 16:06:12 -0800643func (j *Javadoc) collectDeps(ctx android.ModuleContext) deps {
644 var deps deps
645
Colin Cross83bb3162018-06-25 15:48:06 -0700646 sdkDep := decodeSdkDep(ctx, sdkContext(j))
Nan Zhang581fd212018-01-10 16:06:12 -0800647 if sdkDep.invalidVersion {
Colin Cross86a60ae2018-05-29 14:44:55 -0700648 ctx.AddMissingDependencies(sdkDep.modules)
Nan Zhang581fd212018-01-10 16:06:12 -0800649 } else if sdkDep.useFiles {
Colin Cross86a60ae2018-05-29 14:44:55 -0700650 deps.bootClasspath = append(deps.bootClasspath, sdkDep.jars...)
Nan Zhang581fd212018-01-10 16:06:12 -0800651 }
652
653 ctx.VisitDirectDeps(func(module android.Module) {
654 otherName := ctx.OtherModuleName(module)
655 tag := ctx.OtherModuleDependencyTag(module)
656
Colin Cross2d24c1b2018-05-23 10:59:18 -0700657 switch tag {
658 case bootClasspathTag:
659 if dep, ok := module.(Dependency); ok {
Nan Zhang581fd212018-01-10 16:06:12 -0800660 deps.bootClasspath = append(deps.bootClasspath, dep.ImplementationJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700661 } else {
662 panic(fmt.Errorf("unknown dependency %q for %q", otherName, ctx.ModuleName()))
663 }
664 case libTag:
665 switch dep := module.(type) {
Colin Cross897d2ed2019-02-11 14:03:51 -0800666 case SdkLibraryDependency:
667 deps.classpath = append(deps.classpath, dep.SdkImplementationJars(ctx, j.sdkVersion())...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700668 case Dependency:
Sundong Ahnba493602018-11-20 17:36:35 +0900669 deps.classpath = append(deps.classpath, dep.HeaderJars()...)
Colin Cross2d24c1b2018-05-23 10:59:18 -0700670 case android.SourceFileProducer:
Nan Zhang581fd212018-01-10 16:06:12 -0800671 checkProducesJars(ctx, dep)
672 deps.classpath = append(deps.classpath, dep.Srcs()...)
Nan Zhang581fd212018-01-10 16:06:12 -0800673 default:
674 ctx.ModuleErrorf("depends on non-java module %q", otherName)
675 }
Colin Crossa1ce2a02018-06-20 15:19:39 -0700676 case srcsLibTag:
677 switch dep := module.(type) {
678 case Dependency:
679 srcs := dep.(SrcDependency).CompiledSrcs()
680 whitelistPathPrefixes := make(map[string]bool)
681 j.genWhitelistPathPrefixes(whitelistPathPrefixes)
682 for _, src := range srcs {
683 if _, ok := src.(android.WritablePath); ok { // generated sources
684 deps.srcs = append(deps.srcs, src)
685 } else { // select source path for documentation based on whitelist path prefixs.
Nan Zhang1598a9e2018-09-04 17:14:32 -0700686 for k := range whitelistPathPrefixes {
Colin Crossa1ce2a02018-06-20 15:19:39 -0700687 if strings.HasPrefix(src.Rel(), k) {
688 deps.srcs = append(deps.srcs, src)
689 break
690 }
691 }
692 }
693 }
694 deps.srcJars = append(deps.srcJars, dep.(SrcDependency).CompiledSrcJars()...)
695 default:
696 ctx.ModuleErrorf("depends on non-java module %q", otherName)
697 }
Nan Zhang357466b2018-04-17 17:38:36 -0700698 case systemModulesTag:
699 if deps.systemModules != nil {
700 panic("Found two system module dependencies")
701 }
702 sm := module.(*SystemModules)
703 if sm.outputFile == nil {
704 panic("Missing directory for system module dependency")
705 }
706 deps.systemModules = sm.outputFile
Nan Zhang581fd212018-01-10 16:06:12 -0800707 }
708 })
709 // do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
710 // may contain filegroup or genrule.
Colin Cross8a497952019-03-05 22:25:09 -0800711 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
Nan Zhanga40da042018-08-01 12:48:00 -0700712 flags := j.collectAidlFlags(ctx, deps)
Jiyong Park1e440682018-05-23 18:42:04 +0900713 srcFiles = j.genSources(ctx, srcFiles, flags)
Nan Zhang581fd212018-01-10 16:06:12 -0800714
715 // srcs may depend on some genrule output.
716 j.srcJars = srcFiles.FilterByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800717 j.srcJars = append(j.srcJars, deps.srcJars...)
718
Nan Zhang581fd212018-01-10 16:06:12 -0800719 j.srcFiles = srcFiles.FilterOutByExt(".srcjar")
Nan Zhangb2b33de2018-02-23 11:18:47 -0800720 j.srcFiles = append(j.srcFiles, deps.srcs...)
Nan Zhang581fd212018-01-10 16:06:12 -0800721
722 j.docZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"docs.zip")
Nan Zhangccff0f72018-03-08 17:26:16 -0800723 j.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
Nan Zhang581fd212018-01-10 16:06:12 -0800724
Nan Zhang9c69a122018-08-22 10:22:08 -0700725 if j.properties.Local_sourcepaths == nil && len(j.srcFiles) > 0 {
Nan Zhang581fd212018-01-10 16:06:12 -0800726 j.properties.Local_sourcepaths = append(j.properties.Local_sourcepaths, ".")
727 }
728 j.sourcepaths = android.PathsForModuleSrc(ctx, j.properties.Local_sourcepaths)
Nan Zhang581fd212018-01-10 16:06:12 -0800729
Colin Cross8a497952019-03-05 22:25:09 -0800730 j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
Paul Duffin99e4a502019-02-11 15:38:42 +0000731 argFilesMap := map[string]string{}
732 argFileLabels := []string{}
Nan Zhang1598a9e2018-09-04 17:14:32 -0700733
Paul Duffin99e4a502019-02-11 15:38:42 +0000734 for _, label := range j.properties.Arg_files {
Colin Cross8a497952019-03-05 22:25:09 -0800735 var paths = android.PathsForModuleSrc(ctx, []string{label})
Paul Duffin99e4a502019-02-11 15:38:42 +0000736 if _, exists := argFilesMap[label]; !exists {
737 argFilesMap[label] = strings.Join(paths.Strings(), " ")
738 argFileLabels = append(argFileLabels, label)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700739 } else {
740 ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
Paul Duffin99e4a502019-02-11 15:38:42 +0000741 label, argFilesMap[label], paths)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700742 }
743 }
744
745 var err error
746 j.args, err = android.Expand(String(j.properties.Args), func(name string) (string, error) {
747 if strings.HasPrefix(name, "location ") {
748 label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
Paul Duffin99e4a502019-02-11 15:38:42 +0000749 if paths, ok := argFilesMap[label]; ok {
750 return paths, nil
Nan Zhang1598a9e2018-09-04 17:14:32 -0700751 } else {
Paul Duffin99e4a502019-02-11 15:38:42 +0000752 return "", fmt.Errorf("unknown location label %q, expecting one of %q",
753 label, strings.Join(argFileLabels, ", "))
Nan Zhang1598a9e2018-09-04 17:14:32 -0700754 }
755 } else if name == "genDir" {
756 return android.PathForModuleGen(ctx).String(), nil
757 }
758 return "", fmt.Errorf("unknown variable '$(%s)'", name)
759 })
760
761 if err != nil {
762 ctx.PropertyErrorf("args", "%s", err.Error())
763 }
764
Nan Zhang581fd212018-01-10 16:06:12 -0800765 return deps
766}
767
768func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
769 j.addDeps(ctx)
770}
771
772func (j *Javadoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
773 deps := j.collectDeps(ctx)
774
775 var implicits android.Paths
776 implicits = append(implicits, deps.bootClasspath...)
777 implicits = append(implicits, deps.classpath...)
778
Nan Zhang1598a9e2018-09-04 17:14:32 -0700779 var bootClasspathArgs, classpathArgs, sourcepathArgs string
Nan Zhang357466b2018-04-17 17:38:36 -0700780
Colin Cross83bb3162018-06-25 15:48:06 -0700781 javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
Colin Cross997262f2018-06-19 22:49:39 -0700782 if len(deps.bootClasspath) > 0 {
783 var systemModules classpath
784 if deps.systemModules != nil {
785 systemModules = append(systemModules, deps.systemModules)
Nan Zhang581fd212018-01-10 16:06:12 -0800786 }
Colin Cross997262f2018-06-19 22:49:39 -0700787 bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
788 bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
Nan Zhang581fd212018-01-10 16:06:12 -0800789 }
790 if len(deps.classpath.Strings()) > 0 {
791 classpathArgs = "-classpath " + strings.Join(deps.classpath.Strings(), ":")
792 }
793
794 implicits = append(implicits, j.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -0700795 implicits = append(implicits, j.argFiles...)
Nan Zhang581fd212018-01-10 16:06:12 -0800796
Nan Zhangaf322cc2018-06-19 15:15:38 -0700797 opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
Nan Zhang581fd212018-01-10 16:06:12 -0800798
Nan Zhang1598a9e2018-09-04 17:14:32 -0700799 sourcepathArgs = "-sourcepath " + strings.Join(j.sourcepaths.Strings(), ":")
800
Nan Zhang581fd212018-01-10 16:06:12 -0800801 ctx.Build(pctx, android.BuildParams{
802 Rule: javadoc,
803 Description: "Javadoc",
Nan Zhangccff0f72018-03-08 17:26:16 -0800804 Output: j.stubsSrcJar,
Nan Zhang581fd212018-01-10 16:06:12 -0800805 ImplicitOutput: j.docZip,
806 Inputs: j.srcFiles,
807 Implicits: implicits,
808 Args: map[string]string{
Nan Zhangde860a42018-08-08 16:32:21 -0700809 "outDir": android.PathForModuleOut(ctx, "out").String(),
810 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
811 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
Nan Zhang581fd212018-01-10 16:06:12 -0800812 "srcJars": strings.Join(j.srcJars.Strings(), " "),
813 "opts": opts,
Nan Zhang853f4202018-04-12 16:55:56 -0700814 "bootclasspathArgs": bootClasspathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800815 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -0700816 "sourcepathArgs": sourcepathArgs,
Nan Zhang581fd212018-01-10 16:06:12 -0800817 "docZip": j.docZip.String(),
818 },
819 })
820}
821
Nan Zhanga40da042018-08-01 12:48:00 -0700822//
823// Droiddoc
824//
825type Droiddoc struct {
826 Javadoc
827
828 properties DroiddocProperties
829 apiFile android.WritablePath
830 dexApiFile android.WritablePath
831 privateApiFile android.WritablePath
832 privateDexApiFile android.WritablePath
833 removedApiFile android.WritablePath
834 removedDexApiFile android.WritablePath
835 exactApiFile android.WritablePath
836 apiMappingFile android.WritablePath
Nan Zhang66dc2362018-08-14 20:41:04 -0700837 proguardFile android.WritablePath
Nan Zhanga40da042018-08-01 12:48:00 -0700838
839 checkCurrentApiTimestamp android.WritablePath
840 updateCurrentApiTimestamp android.WritablePath
841 checkLastReleasedApiTimestamp android.WritablePath
842
Nan Zhanga40da042018-08-01 12:48:00 -0700843 apiFilePath android.Path
844}
845
Nan Zhanga40da042018-08-01 12:48:00 -0700846func DroiddocFactory() android.Module {
847 module := &Droiddoc{}
848
849 module.AddProperties(&module.properties,
850 &module.Javadoc.properties)
851
852 InitDroiddocModule(module, android.HostAndDeviceSupported)
853 return module
854}
855
856func DroiddocHostFactory() android.Module {
857 module := &Droiddoc{}
858
859 module.AddProperties(&module.properties,
860 &module.Javadoc.properties)
861
862 InitDroiddocModule(module, android.HostSupported)
863 return module
864}
865
866func (d *Droiddoc) ApiFilePath() android.Path {
867 return d.apiFilePath
868}
869
Nan Zhang581fd212018-01-10 16:06:12 -0800870func (d *Droiddoc) DepsMutator(ctx android.BottomUpMutatorContext) {
871 d.Javadoc.addDeps(ctx)
872
Inseob Kim38449af2019-02-28 14:24:05 +0900873 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
874 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
875 }
876
Nan Zhang79614d12018-04-19 18:03:39 -0700877 if String(d.properties.Custom_template) != "" {
Dan Willemsencc090972018-02-26 14:33:31 -0800878 ctx.AddDependency(ctx.Module(), droiddocTemplateTag, String(d.properties.Custom_template))
879 }
Nan Zhang581fd212018-01-10 16:06:12 -0800880}
881
Nan Zhang66dc2362018-08-14 20:41:04 -0700882func (d *Droiddoc) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
883 deps deps) (droiddocBuilderFlags, error) {
Nan Zhanga40da042018-08-01 12:48:00 -0700884 var flags droiddocBuilderFlags
Nan Zhang581fd212018-01-10 16:06:12 -0800885
Nan Zhanga40da042018-08-01 12:48:00 -0700886 *implicits = append(*implicits, deps.bootClasspath...)
887 *implicits = append(*implicits, deps.classpath...)
Nan Zhang581fd212018-01-10 16:06:12 -0800888
Nan Zhangc94f9d82018-06-26 10:02:26 -0700889 if len(deps.bootClasspath.Strings()) > 0 {
890 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
Nan Zhanga40da042018-08-01 12:48:00 -0700891 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
Nan Zhang357466b2018-04-17 17:38:36 -0700892 }
Nan Zhanga40da042018-08-01 12:48:00 -0700893 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
Nan Zhang1598a9e2018-09-04 17:14:32 -0700894 // Dokka doesn't support bootClasspath, so combine these two classpath vars for Dokka.
Nan Zhang86d2d552018-08-09 15:33:27 -0700895 dokkaClasspath := classpath{}
896 dokkaClasspath = append(dokkaClasspath, deps.bootClasspath...)
897 dokkaClasspath = append(dokkaClasspath, deps.classpath...)
898 flags.dokkaClasspathArgs = dokkaClasspath.FormJavaClassPath("-classpath")
Nan Zhang79614d12018-04-19 18:03:39 -0700899
Nan Zhang9c69a122018-08-22 10:22:08 -0700900 // TODO(nanzhang): Remove this if- statement once we finish migration for all Doclava
901 // based stubs generation.
902 // In the future, all the docs generation depends on Metalava stubs (droidstubs) srcjar
903 // dir. We need add the srcjar dir to -sourcepath arg, so that Javadoc can figure out
904 // the correct package name base path.
905 if len(d.Javadoc.properties.Local_sourcepaths) > 0 {
906 flags.sourcepathArgs = "-sourcepath " + strings.Join(d.Javadoc.sourcepaths.Strings(), ":")
907 } else {
908 flags.sourcepathArgs = "-sourcepath " + android.PathForModuleOut(ctx, "srcjars").String()
909 }
Nan Zhang581fd212018-01-10 16:06:12 -0800910
Nan Zhanga40da042018-08-01 12:48:00 -0700911 return flags, nil
912}
Nan Zhang581fd212018-01-10 16:06:12 -0800913
Nan Zhanga40da042018-08-01 12:48:00 -0700914func (d *Droiddoc) collectDoclavaDocsFlags(ctx android.ModuleContext, implicits *android.Paths,
Nan Zhang443fa522018-08-20 20:58:28 -0700915 jsilver, doclava android.Path) string {
Nan Zhang581fd212018-01-10 16:06:12 -0800916
Nan Zhanga40da042018-08-01 12:48:00 -0700917 *implicits = append(*implicits, jsilver)
918 *implicits = append(*implicits, doclava)
Nan Zhang30963742018-04-23 09:59:14 -0700919
Nan Zhang46130972018-06-04 11:28:01 -0700920 var date string
921 if runtime.GOOS == "darwin" {
922 date = `date -r`
923 } else {
924 date = `date -d`
925 }
926
Nan Zhang443fa522018-08-20 20:58:28 -0700927 // Droiddoc always gets "-source 1.8" because it doesn't support 1.9 sources. For modules with 1.9
928 // sources, droiddoc will get sources produced by metalava which will have already stripped out the
929 // 1.9 language features.
930 args := " -source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
Nan Zhang30963742018-04-23 09:59:14 -0700931 "-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
Nan Zhang581fd212018-01-10 16:06:12 -0800932 "-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
Nan Zhang79614d12018-04-19 18:03:39 -0700933 `-hdf page.now "$$(` + date + ` @$$(cat ` + ctx.Config().Getenv("BUILD_DATETIME_FILE") + `) "+%d %b %Y %k:%M")" `
Nan Zhang46130972018-06-04 11:28:01 -0700934
Nan Zhanga40da042018-08-01 12:48:00 -0700935 if String(d.properties.Custom_template) == "" {
936 // TODO: This is almost always droiddoc-templates-sdk
937 ctx.PropertyErrorf("custom_template", "must specify a template")
938 }
939
940 ctx.VisitDirectDepsWithTag(droiddocTemplateTag, func(m android.Module) {
Nan Zhangf4936b02018-08-01 15:00:28 -0700941 if t, ok := m.(*ExportedDroiddocDir); ok {
Nan Zhanga40da042018-08-01 12:48:00 -0700942 *implicits = append(*implicits, t.deps...)
943 args = args + " -templatedir " + t.dir.String()
944 } else {
945 ctx.PropertyErrorf("custom_template", "module %q is not a droiddoc_template", ctx.OtherModuleName(m))
946 }
947 })
948
949 if len(d.properties.Html_dirs) > 0 {
Colin Cross07e51612019-03-05 12:46:40 -0800950 htmlDir := d.properties.Html_dirs[0]
Colin Cross8a497952019-03-05 22:25:09 -0800951 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(d.properties.Html_dirs[0], "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800952 args = args + " -htmldir " + htmlDir
Nan Zhanga40da042018-08-01 12:48:00 -0700953 }
954
955 if len(d.properties.Html_dirs) > 1 {
Colin Cross07e51612019-03-05 12:46:40 -0800956 htmlDir2 := d.properties.Html_dirs[1]
Colin Cross8a497952019-03-05 22:25:09 -0800957 *implicits = append(*implicits, android.PathsForModuleSrc(ctx, []string{filepath.Join(htmlDir2, "**/*")})...)
Colin Cross07e51612019-03-05 12:46:40 -0800958 args = args + " -htmldir2 " + htmlDir2
Nan Zhanga40da042018-08-01 12:48:00 -0700959 }
960
961 if len(d.properties.Html_dirs) > 2 {
962 ctx.PropertyErrorf("html_dirs", "Droiddoc only supports up to 2 html dirs")
963 }
964
Colin Cross8a497952019-03-05 22:25:09 -0800965 knownTags := android.PathsForModuleSrc(ctx, d.properties.Knowntags)
Nan Zhanga40da042018-08-01 12:48:00 -0700966 *implicits = append(*implicits, knownTags...)
967
968 for _, kt := range knownTags {
969 args = args + " -knowntags " + kt.String()
970 }
971
972 for _, hdf := range d.properties.Hdf {
973 args = args + " -hdf " + hdf
974 }
975
976 if String(d.properties.Proofread_file) != "" {
977 proofreadFile := android.PathForModuleOut(ctx, String(d.properties.Proofread_file))
978 args = args + " -proofread " + proofreadFile.String()
979 }
980
981 if String(d.properties.Todo_file) != "" {
982 // tricky part:
983 // we should not compute full path for todo_file through PathForModuleOut().
984 // the non-standard doclet will get the full path relative to "-o".
985 args = args + " -todo " + String(d.properties.Todo_file)
986 }
987
988 if String(d.properties.Resourcesdir) != "" {
989 // TODO: should we add files under resourcesDir to the implicits? It seems that
990 // resourcesDir is one sub dir of htmlDir
991 resourcesDir := android.PathForModuleSrc(ctx, String(d.properties.Resourcesdir))
992 args = args + " -resourcesdir " + resourcesDir.String()
993 }
994
995 if String(d.properties.Resourcesoutdir) != "" {
996 // TODO: it seems -resourceoutdir reference/android/images/ didn't get generated anywhere.
997 args = args + " -resourcesoutdir " + String(d.properties.Resourcesoutdir)
998 }
999 return args
1000}
1001
Nan Zhang1598a9e2018-09-04 17:14:32 -07001002func (d *Droiddoc) collectStubsFlags(ctx android.ModuleContext,
1003 implicitOutputs *android.WritablePaths) string {
1004 var doclavaFlags string
1005 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1006 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1007 String(d.properties.Api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001008 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1009 doclavaFlags += " -api " + d.apiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001010 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1011 d.apiFilePath = d.apiFile
1012 }
1013
Nan Zhang1598a9e2018-09-04 17:14:32 -07001014 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1015 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1016 String(d.properties.Removed_api_filename) != "" {
Nan Zhanga40da042018-08-01 12:48:00 -07001017 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1018 doclavaFlags += " -removedApi " + d.removedApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001019 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1020 }
1021
1022 if String(d.properties.Private_api_filename) != "" {
1023 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1024 doclavaFlags += " -privateApi " + d.privateApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001025 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1026 }
1027
1028 if String(d.properties.Dex_api_filename) != "" {
1029 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1030 doclavaFlags += " -dexApi " + d.dexApiFile.String()
1031 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1032 }
1033
1034 if String(d.properties.Private_dex_api_filename) != "" {
1035 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1036 doclavaFlags += " -privateDexApi " + d.privateDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001037 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1038 }
1039
1040 if String(d.properties.Removed_dex_api_filename) != "" {
1041 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1042 doclavaFlags += " -removedDexApi " + d.removedDexApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001043 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1044 }
1045
1046 if String(d.properties.Exact_api_filename) != "" {
1047 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1048 doclavaFlags += " -exactApi " + d.exactApiFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001049 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1050 }
1051
1052 if String(d.properties.Dex_mapping_filename) != "" {
1053 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1054 doclavaFlags += " -apiMapping " + d.apiMappingFile.String()
Nan Zhanga40da042018-08-01 12:48:00 -07001055 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1056 }
1057
Nan Zhang66dc2362018-08-14 20:41:04 -07001058 if String(d.properties.Proguard_filename) != "" {
1059 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1060 doclavaFlags += " -proguard " + d.proguardFile.String()
Nan Zhang66dc2362018-08-14 20:41:04 -07001061 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1062 }
1063
Nan Zhanga40da042018-08-01 12:48:00 -07001064 if BoolDefault(d.properties.Create_stubs, true) {
Nan Zhangde860a42018-08-08 16:32:21 -07001065 doclavaFlags += " -stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001066 }
1067
1068 if Bool(d.properties.Write_sdk_values) {
Nan Zhangde860a42018-08-08 16:32:21 -07001069 doclavaFlags += " -sdkvalues " + android.PathForModuleOut(ctx, "out").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001070 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001071
1072 return doclavaFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001073}
1074
1075func (d *Droiddoc) getPostDoclavaCmds(ctx android.ModuleContext, implicits *android.Paths) string {
1076 var cmds string
1077 if String(d.properties.Static_doc_index_redirect) != "" {
1078 static_doc_index_redirect := ctx.ExpandSource(String(d.properties.Static_doc_index_redirect),
1079 "static_doc_index_redirect")
1080 *implicits = append(*implicits, static_doc_index_redirect)
1081 cmds = cmds + " && cp " + static_doc_index_redirect.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001082 android.PathForModuleOut(ctx, "out", "index.html").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001083 }
1084
1085 if String(d.properties.Static_doc_properties) != "" {
1086 static_doc_properties := ctx.ExpandSource(String(d.properties.Static_doc_properties),
1087 "static_doc_properties")
1088 *implicits = append(*implicits, static_doc_properties)
1089 cmds = cmds + " && cp " + static_doc_properties.String() + " " +
Nan Zhangde860a42018-08-08 16:32:21 -07001090 android.PathForModuleOut(ctx, "out", "source.properties").String()
Nan Zhanga40da042018-08-01 12:48:00 -07001091 }
1092 return cmds
1093}
1094
Nan Zhang1598a9e2018-09-04 17:14:32 -07001095func (d *Droiddoc) transformDoclava(ctx android.ModuleContext, implicits android.Paths,
1096 implicitOutputs android.WritablePaths,
1097 bootclasspathArgs, classpathArgs, sourcepathArgs, opts, postDoclavaCmds string) {
1098 ctx.Build(pctx, android.BuildParams{
1099 Rule: javadoc,
1100 Description: "Doclava",
1101 Output: d.Javadoc.stubsSrcJar,
1102 Inputs: d.Javadoc.srcFiles,
1103 Implicits: implicits,
1104 ImplicitOutputs: implicitOutputs,
1105 Args: map[string]string{
1106 "outDir": android.PathForModuleOut(ctx, "out").String(),
1107 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1108 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1109 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1110 "opts": opts,
1111 "bootclasspathArgs": bootclasspathArgs,
1112 "classpathArgs": classpathArgs,
1113 "sourcepathArgs": sourcepathArgs,
1114 "docZip": d.Javadoc.docZip.String(),
1115 "postDoclavaCmds": postDoclavaCmds,
1116 },
1117 })
1118}
1119
1120func (d *Droiddoc) transformCheckApi(ctx android.ModuleContext, apiFile, removedApiFile android.Path,
1121 checkApiClasspath classpath, msg, opts string, output android.WritablePath) {
1122 ctx.Build(pctx, android.BuildParams{
1123 Rule: apiCheck,
1124 Description: "Doclava Check API",
1125 Output: output,
1126 Inputs: nil,
1127 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1128 checkApiClasspath...),
1129 Args: map[string]string{
1130 "msg": msg,
1131 "classpath": checkApiClasspath.FormJavaClassPath(""),
1132 "opts": opts,
1133 "apiFile": apiFile.String(),
1134 "apiFileToCheck": d.apiFile.String(),
1135 "removedApiFile": removedApiFile.String(),
1136 "removedApiFileToCheck": d.removedApiFile.String(),
1137 },
1138 })
1139}
1140
1141func (d *Droiddoc) transformDokka(ctx android.ModuleContext, implicits android.Paths,
1142 classpathArgs, opts string) {
1143 ctx.Build(pctx, android.BuildParams{
1144 Rule: dokka,
1145 Description: "Dokka",
1146 Output: d.Javadoc.stubsSrcJar,
1147 Inputs: d.Javadoc.srcFiles,
1148 Implicits: implicits,
1149 Args: map[string]string{
Nan Zhang3ffc3522018-11-29 10:42:47 -08001150 "outDir": android.PathForModuleOut(ctx, "dokka-out").String(),
1151 "srcJarDir": android.PathForModuleOut(ctx, "dokka-srcjars").String(),
1152 "stubsDir": android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001153 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1154 "classpathArgs": classpathArgs,
1155 "opts": opts,
1156 "docZip": d.Javadoc.docZip.String(),
1157 },
1158 })
1159}
1160
1161func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
1162 deps := d.Javadoc.collectDeps(ctx)
1163
1164 jsilver := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jsilver.jar")
1165 doclava := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "doclava.jar")
1166 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME")
1167 checkApiClasspath := classpath{jsilver, doclava, android.PathForSource(ctx, java8Home, "lib/tools.jar")}
1168
1169 var implicits android.Paths
1170 implicits = append(implicits, d.Javadoc.srcJars...)
1171 implicits = append(implicits, d.Javadoc.argFiles...)
1172
1173 var implicitOutputs android.WritablePaths
1174 implicitOutputs = append(implicitOutputs, d.Javadoc.docZip)
1175 for _, o := range d.Javadoc.properties.Out {
1176 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1177 }
1178
1179 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
1180 if err != nil {
1181 return
1182 }
1183
1184 flags.doclavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
1185 if Bool(d.properties.Dokka_enabled) {
1186 d.transformDokka(ctx, implicits, flags.classpathArgs, d.Javadoc.args)
1187 } else {
1188 flags.doclavaDocsFlags = d.collectDoclavaDocsFlags(ctx, &implicits, jsilver, doclava)
1189 flags.postDoclavaCmds = d.getPostDoclavaCmds(ctx, &implicits)
1190 d.transformDoclava(ctx, implicits, implicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1191 flags.sourcepathArgs, flags.doclavaDocsFlags+flags.doclavaStubsFlags+" "+d.Javadoc.args,
1192 flags.postDoclavaCmds)
1193 }
1194
1195 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1196 !ctx.Config().IsPdkBuild() {
1197 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1198 "check_api.current.api_file")
1199 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1200 "check_api.current_removed_api_file")
1201
1202 d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
1203 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1204 fmt.Sprintf(`\n******************************\n`+
1205 `You have tried to change the API from what has been previously approved.\n\n`+
1206 `To make these errors go away, you have two choices:\n`+
1207 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1208 ` errors above.\n\n`+
1209 ` 2. You can update current.txt by executing the following command:\n`+
1210 ` make %s-update-current-api\n\n`+
1211 ` To submit the revised current.txt to the main Android repository,\n`+
1212 ` you will need approval.\n`+
1213 `******************************\n`, ctx.ModuleName()), String(d.properties.Check_api.Current.Args),
1214 d.checkCurrentApiTimestamp)
1215
1216 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
1217 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1218 d.updateCurrentApiTimestamp)
1219 }
1220
1221 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1222 !ctx.Config().IsPdkBuild() {
1223 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1224 "check_api.last_released.api_file")
1225 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1226 "check_api.last_released.removed_api_file")
1227
1228 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
1229 d.transformCheckApi(ctx, apiFile, removedApiFile, checkApiClasspath,
1230 `\n******************************\n`+
1231 `You have tried to change the API from what has been previously released in\n`+
1232 `an SDK. Please fix the errors listed above.\n`+
1233 `******************************\n`, String(d.properties.Check_api.Last_released.Args),
1234 d.checkLastReleasedApiTimestamp)
1235 }
1236}
1237
1238//
1239// Droidstubs
1240//
1241type Droidstubs struct {
1242 Javadoc
1243
Pete Gillin581d6082018-10-22 15:55:04 +01001244 properties DroidstubsProperties
1245 apiFile android.WritablePath
1246 apiXmlFile android.WritablePath
1247 lastReleasedApiXmlFile android.WritablePath
1248 dexApiFile android.WritablePath
1249 privateApiFile android.WritablePath
1250 privateDexApiFile android.WritablePath
1251 removedApiFile android.WritablePath
1252 removedDexApiFile android.WritablePath
1253 apiMappingFile android.WritablePath
1254 exactApiFile android.WritablePath
1255 proguardFile android.WritablePath
1256 nullabilityWarningsFile android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001257
1258 checkCurrentApiTimestamp android.WritablePath
1259 updateCurrentApiTimestamp android.WritablePath
1260 checkLastReleasedApiTimestamp android.WritablePath
1261
Pete Gillin581d6082018-10-22 15:55:04 +01001262 checkNullabilityWarningsTimestamp android.WritablePath
1263
Nan Zhang1598a9e2018-09-04 17:14:32 -07001264 annotationsZip android.WritablePath
Nan Zhang9c69a122018-08-22 10:22:08 -07001265 apiVersionsXml android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001266
1267 apiFilePath android.Path
Nan Zhang71bbe632018-09-17 14:32:21 -07001268
1269 jdiffDocZip android.WritablePath
1270 jdiffStubsSrcJar android.WritablePath
Nan Zhang1598a9e2018-09-04 17:14:32 -07001271}
1272
1273func DroidstubsFactory() android.Module {
1274 module := &Droidstubs{}
1275
1276 module.AddProperties(&module.properties,
1277 &module.Javadoc.properties)
1278
1279 InitDroiddocModule(module, android.HostAndDeviceSupported)
1280 return module
1281}
1282
1283func DroidstubsHostFactory() android.Module {
1284 module := &Droidstubs{}
1285
1286 module.AddProperties(&module.properties,
1287 &module.Javadoc.properties)
1288
1289 InitDroiddocModule(module, android.HostSupported)
1290 return module
1291}
1292
1293func (d *Droidstubs) ApiFilePath() android.Path {
1294 return d.apiFilePath
1295}
1296
1297func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
1298 d.Javadoc.addDeps(ctx)
1299
Inseob Kim38449af2019-02-28 14:24:05 +09001300 if Bool(d.properties.Check_api.Ignore_missing_latest_api) {
1301 ignoreMissingModules(ctx, &d.properties.Check_api.Last_released)
1302 }
1303
Nan Zhang1598a9e2018-09-04 17:14:32 -07001304 if len(d.properties.Merge_annotations_dirs) != 0 {
1305 for _, mergeAnnotationsDir := range d.properties.Merge_annotations_dirs {
1306 ctx.AddDependency(ctx.Module(), metalavaMergeAnnotationsDirTag, mergeAnnotationsDir)
1307 }
1308 }
Nan Zhang9c69a122018-08-22 10:22:08 -07001309
Pete Gillin77167902018-09-19 18:16:26 +01001310 if len(d.properties.Merge_inclusion_annotations_dirs) != 0 {
1311 for _, mergeInclusionAnnotationsDir := range d.properties.Merge_inclusion_annotations_dirs {
1312 ctx.AddDependency(ctx.Module(), metalavaMergeInclusionAnnotationsDirTag, mergeInclusionAnnotationsDir)
1313 }
1314 }
1315
Nan Zhang9c69a122018-08-22 10:22:08 -07001316 if len(d.properties.Api_levels_annotations_dirs) != 0 {
1317 for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
1318 ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
1319 }
1320 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001321}
1322
1323func (d *Droidstubs) initBuilderFlags(ctx android.ModuleContext, implicits *android.Paths,
1324 deps deps) (droiddocBuilderFlags, error) {
1325 var flags droiddocBuilderFlags
1326
1327 *implicits = append(*implicits, deps.bootClasspath...)
1328 *implicits = append(*implicits, deps.classpath...)
1329
1330 // continue to use -bootclasspath even if Metalava under -source 1.9 is enabled
1331 // since it doesn't support system modules yet.
1332 if len(deps.bootClasspath.Strings()) > 0 {
1333 // For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
1334 flags.bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
1335 }
1336 flags.classpathArgs = deps.classpath.FormJavaClassPath("-classpath")
1337
Sundong Ahn56dce442018-10-05 18:41:09 +09001338 flags.sourcepathArgs = "-sourcepath \"" + strings.Join(d.Javadoc.sourcepaths.Strings(), ":") + "\""
Nan Zhang1598a9e2018-09-04 17:14:32 -07001339 return flags, nil
1340}
1341
1342func (d *Droidstubs) collectStubsFlags(ctx android.ModuleContext,
1343 implicitOutputs *android.WritablePaths) string {
1344 var metalavaFlags string
1345 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1346 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1347 String(d.properties.Api_filename) != "" {
1348 d.apiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.txt")
1349 metalavaFlags = metalavaFlags + " --api " + d.apiFile.String()
1350 *implicitOutputs = append(*implicitOutputs, d.apiFile)
1351 d.apiFilePath = d.apiFile
1352 }
1353
1354 if apiCheckEnabled(d.properties.Check_api.Current, "current") ||
1355 apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") ||
1356 String(d.properties.Removed_api_filename) != "" {
1357 d.removedApiFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_removed.txt")
1358 metalavaFlags = metalavaFlags + " --removed-api " + d.removedApiFile.String()
1359 *implicitOutputs = append(*implicitOutputs, d.removedApiFile)
1360 }
1361
1362 if String(d.properties.Private_api_filename) != "" {
1363 d.privateApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_api_filename))
1364 metalavaFlags = metalavaFlags + " --private-api " + d.privateApiFile.String()
1365 *implicitOutputs = append(*implicitOutputs, d.privateApiFile)
1366 }
1367
1368 if String(d.properties.Dex_api_filename) != "" {
1369 d.dexApiFile = android.PathForModuleOut(ctx, String(d.properties.Dex_api_filename))
1370 metalavaFlags += " --dex-api " + d.dexApiFile.String()
1371 *implicitOutputs = append(*implicitOutputs, d.dexApiFile)
1372 }
1373
1374 if String(d.properties.Private_dex_api_filename) != "" {
1375 d.privateDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Private_dex_api_filename))
1376 metalavaFlags = metalavaFlags + " --private-dex-api " + d.privateDexApiFile.String()
1377 *implicitOutputs = append(*implicitOutputs, d.privateDexApiFile)
1378 }
1379
1380 if String(d.properties.Removed_dex_api_filename) != "" {
1381 d.removedDexApiFile = android.PathForModuleOut(ctx, String(d.properties.Removed_dex_api_filename))
1382 metalavaFlags = metalavaFlags + " --removed-dex-api " + d.removedDexApiFile.String()
1383 *implicitOutputs = append(*implicitOutputs, d.removedDexApiFile)
1384 }
1385
1386 if String(d.properties.Exact_api_filename) != "" {
1387 d.exactApiFile = android.PathForModuleOut(ctx, String(d.properties.Exact_api_filename))
1388 metalavaFlags = metalavaFlags + " --exact-api " + d.exactApiFile.String()
1389 *implicitOutputs = append(*implicitOutputs, d.exactApiFile)
1390 }
1391
Nan Zhang9c69a122018-08-22 10:22:08 -07001392 if String(d.properties.Dex_mapping_filename) != "" {
1393 d.apiMappingFile = android.PathForModuleOut(ctx, String(d.properties.Dex_mapping_filename))
1394 metalavaFlags = metalavaFlags + " --dex-api-mapping " + d.apiMappingFile.String()
1395 *implicitOutputs = append(*implicitOutputs, d.apiMappingFile)
1396 }
1397
Nan Zhang199645c2018-09-19 12:40:06 -07001398 if String(d.properties.Proguard_filename) != "" {
1399 d.proguardFile = android.PathForModuleOut(ctx, String(d.properties.Proguard_filename))
1400 metalavaFlags += " --proguard " + d.proguardFile.String()
1401 *implicitOutputs = append(*implicitOutputs, d.proguardFile)
1402 }
1403
Nan Zhang9c69a122018-08-22 10:22:08 -07001404 if Bool(d.properties.Write_sdk_values) {
1405 metalavaFlags = metalavaFlags + " --sdk-values " + android.PathForModuleOut(ctx, "out").String()
1406 }
1407
Nan Zhang1598a9e2018-09-04 17:14:32 -07001408 if Bool(d.properties.Create_doc_stubs) {
1409 metalavaFlags += " --doc-stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1410 } else {
1411 metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
1412 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001413 return metalavaFlags
1414}
1415
1416func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
Nan Zhangdee152b2018-12-26 16:06:37 -08001417 implicits *android.Paths, implicitOutputs *android.WritablePaths) (string, string) {
1418 var flags, mergeAnnoDirFlags string
Nan Zhang1598a9e2018-09-04 17:14:32 -07001419 if Bool(d.properties.Annotations_enabled) {
Pete Gillina262c052018-09-14 14:25:48 +01001420 flags += " --include-annotations"
Pete Gillinc382a562018-11-14 18:45:46 +00001421 validatingNullability :=
1422 strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
1423 String(d.properties.Validate_nullability_from_list) != ""
Pete Gillina262c052018-09-14 14:25:48 +01001424 migratingNullability := String(d.properties.Previous_api) != ""
1425 if !(migratingNullability || validatingNullability) {
1426 ctx.PropertyErrorf("previous_api",
1427 "has to be non-empty if annotations was enabled (unless validating nullability)")
Nan Zhanga40da042018-08-01 12:48:00 -07001428 }
Pete Gillina262c052018-09-14 14:25:48 +01001429 if migratingNullability {
Colin Cross8a497952019-03-05 22:25:09 -08001430 previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
Pete Gillina262c052018-09-14 14:25:48 +01001431 *implicits = append(*implicits, previousApi)
1432 flags += " --migrate-nullness " + previousApi.String()
1433 }
Pete Gillinc382a562018-11-14 18:45:46 +00001434 if s := String(d.properties.Validate_nullability_from_list); s != "" {
Colin Cross8a497952019-03-05 22:25:09 -08001435 flags += " --validate-nullability-from-list " + android.PathForModuleSrc(ctx, s).String()
Pete Gillinc382a562018-11-14 18:45:46 +00001436 }
Pete Gillina262c052018-09-14 14:25:48 +01001437 if validatingNullability {
Pete Gillin581d6082018-10-22 15:55:04 +01001438 d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
1439 *implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
1440 flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
Pete Gillina262c052018-09-14 14:25:48 +01001441 }
Nan Zhanga40da042018-08-01 12:48:00 -07001442
1443 d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
1444 *implicitOutputs = append(*implicitOutputs, d.annotationsZip)
1445
Nan Zhangf4936b02018-08-01 15:00:28 -07001446 flags += " --extract-annotations " + d.annotationsZip.String()
1447
Nan Zhang1598a9e2018-09-04 17:14:32 -07001448 if len(d.properties.Merge_annotations_dirs) == 0 {
Nan Zhang9c69a122018-08-22 10:22:08 -07001449 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhanga40da042018-08-01 12:48:00 -07001450 "has to be non-empty if annotations was enabled!")
1451 }
Nan Zhangf4936b02018-08-01 15:00:28 -07001452 ctx.VisitDirectDepsWithTag(metalavaMergeAnnotationsDirTag, func(m android.Module) {
1453 if t, ok := m.(*ExportedDroiddocDir); ok {
1454 *implicits = append(*implicits, t.deps...)
Nan Zhangdee152b2018-12-26 16:06:37 -08001455 mergeAnnoDirFlags += " --merge-qualifier-annotations " + t.dir.String()
Nan Zhangf4936b02018-08-01 15:00:28 -07001456 } else {
Nan Zhang9c69a122018-08-22 10:22:08 -07001457 ctx.PropertyErrorf("merge_annotations_dirs",
Nan Zhangf4936b02018-08-01 15:00:28 -07001458 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1459 }
1460 })
Nan Zhangdee152b2018-12-26 16:06:37 -08001461 flags += mergeAnnoDirFlags
Nan Zhanga40da042018-08-01 12:48:00 -07001462 // TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001463 flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
Nan Zhanga40da042018-08-01 12:48:00 -07001464 }
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001465
Nan Zhangdee152b2018-12-26 16:06:37 -08001466 return flags, mergeAnnoDirFlags
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001467}
1468
1469func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
1470 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1471 var flags string
Pete Gillin77167902018-09-19 18:16:26 +01001472 ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
1473 if t, ok := m.(*ExportedDroiddocDir); ok {
1474 *implicits = append(*implicits, t.deps...)
1475 flags += " --merge-inclusion-annotations " + t.dir.String()
1476 } else {
1477 ctx.PropertyErrorf("merge_inclusion_annotations_dirs",
1478 "module %q is not a metalava merge-annotations dir", ctx.OtherModuleName(m))
1479 }
1480 })
Nan Zhanga40da042018-08-01 12:48:00 -07001481
1482 return flags
1483}
1484
Nan Zhang9c69a122018-08-22 10:22:08 -07001485func (d *Droidstubs) collectAPILevelsAnnotationsFlags(ctx android.ModuleContext,
1486 implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
1487 var flags string
1488 if Bool(d.properties.Api_levels_annotations_enabled) {
1489 d.apiVersionsXml = android.PathForModuleOut(ctx, "api-versions.xml")
1490 *implicitOutputs = append(*implicitOutputs, d.apiVersionsXml)
1491
1492 if len(d.properties.Api_levels_annotations_dirs) == 0 {
1493 ctx.PropertyErrorf("api_levels_annotations_dirs",
1494 "has to be non-empty if api levels annotations was enabled!")
1495 }
1496
1497 flags = " --generate-api-levels " + d.apiVersionsXml.String() + " --apply-api-levels " +
1498 d.apiVersionsXml.String() + " --current-version " + ctx.Config().PlatformSdkVersion() +
1499 " --current-codename " + ctx.Config().PlatformSdkCodename() + " "
1500
1501 ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
1502 if t, ok := m.(*ExportedDroiddocDir); ok {
1503 var androidJars android.Paths
1504 for _, dep := range t.deps {
1505 if strings.HasSuffix(dep.String(), "android.jar") {
1506 androidJars = append(androidJars, dep)
1507 }
1508 }
1509 *implicits = append(*implicits, androidJars...)
Tor Norbyeebcdfed2019-01-24 11:05:46 -08001510 flags += " --android-jar-pattern " + t.dir.String() + "/%/public/android.jar "
Nan Zhang9c69a122018-08-22 10:22:08 -07001511 } else {
1512 ctx.PropertyErrorf("api_levels_annotations_dirs",
1513 "module %q is not a metalava api-levels-annotations dir", ctx.OtherModuleName(m))
1514 }
1515 })
1516
1517 }
1518
1519 return flags
1520}
1521
Nan Zhang71bbe632018-09-17 14:32:21 -07001522func (d *Droidstubs) collectApiToXmlFlags(ctx android.ModuleContext, implicits *android.Paths,
1523 implicitOutputs *android.WritablePaths) string {
1524 var flags string
1525 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1526 if d.apiFile.String() == "" {
1527 ctx.ModuleErrorf("API signature file has to be specified in Metalava when jdiff is enabled.")
1528 }
1529
1530 d.apiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_api.xml")
1531 *implicitOutputs = append(*implicitOutputs, d.apiXmlFile)
1532
1533 flags = " --api-xml " + d.apiXmlFile.String()
1534
1535 if String(d.properties.Check_api.Last_released.Api_file) == "" {
1536 ctx.PropertyErrorf("check_api.last_released.api_file",
1537 "has to be non-empty if jdiff was enabled!")
1538 }
1539 lastReleasedApi := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1540 "check_api.last_released.api_file")
1541 *implicits = append(*implicits, lastReleasedApi)
1542
1543 d.lastReleasedApiXmlFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_last_released_api.xml")
1544 *implicitOutputs = append(*implicitOutputs, d.lastReleasedApiXmlFile)
1545
1546 flags += " --convert-to-jdiff " + lastReleasedApi.String() + " " +
1547 d.lastReleasedApiXmlFile.String()
1548 }
1549
1550 return flags
1551}
1552
Nan Zhang1598a9e2018-09-04 17:14:32 -07001553func (d *Droidstubs) transformMetalava(ctx android.ModuleContext, implicits android.Paths,
1554 implicitOutputs android.WritablePaths, javaVersion,
1555 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
Nan Zhang9c69a122018-08-22 10:22:08 -07001556
Nan Zhang86d2d552018-08-09 15:33:27 -07001557 ctx.Build(pctx, android.BuildParams{
1558 Rule: metalava,
1559 Description: "Metalava",
1560 Output: d.Javadoc.stubsSrcJar,
1561 Inputs: d.Javadoc.srcFiles,
1562 Implicits: implicits,
1563 ImplicitOutputs: implicitOutputs,
1564 Args: map[string]string{
Nan Zhang86d2d552018-08-09 15:33:27 -07001565 "outDir": android.PathForModuleOut(ctx, "out").String(),
1566 "srcJarDir": android.PathForModuleOut(ctx, "srcjars").String(),
1567 "stubsDir": android.PathForModuleOut(ctx, "stubsDir").String(),
1568 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
Nan Zhang1598a9e2018-09-04 17:14:32 -07001569 "javaVersion": javaVersion,
Nan Zhang86d2d552018-08-09 15:33:27 -07001570 "bootclasspathArgs": bootclasspathArgs,
1571 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001572 "sourcepathArgs": sourcepathArgs,
1573 "opts": opts,
Nan Zhang86d2d552018-08-09 15:33:27 -07001574 },
1575 })
1576}
1577
Nan Zhang1598a9e2018-09-04 17:14:32 -07001578func (d *Droidstubs) transformCheckApi(ctx android.ModuleContext,
1579 apiFile, removedApiFile android.Path, implicits android.Paths,
Colin Cross39c16792019-01-24 16:32:44 -08001580 javaVersion, bootclasspathArgs, classpathArgs, sourcepathArgs, opts, subdir, msg string,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001581 output android.WritablePath) {
1582 ctx.Build(pctx, android.BuildParams{
1583 Rule: metalavaApiCheck,
1584 Description: "Metalava Check API",
1585 Output: output,
1586 Inputs: d.Javadoc.srcFiles,
1587 Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
1588 implicits...),
1589 Args: map[string]string{
Colin Cross39c16792019-01-24 16:32:44 -08001590 "srcJarDir": android.PathForModuleOut(ctx, subdir, "srcjars").String(),
Nan Zhang2760dfc2018-08-24 17:32:54 +00001591 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1592 "javaVersion": javaVersion,
1593 "bootclasspathArgs": bootclasspathArgs,
1594 "classpathArgs": classpathArgs,
Nan Zhang1598a9e2018-09-04 17:14:32 -07001595 "sourcepathArgs": sourcepathArgs,
Nan Zhang2760dfc2018-08-24 17:32:54 +00001596 "opts": opts,
1597 "msg": msg,
1598 },
1599 })
1600}
1601
Nan Zhang71bbe632018-09-17 14:32:21 -07001602func (d *Droidstubs) transformJdiff(ctx android.ModuleContext, implicits android.Paths,
1603 implicitOutputs android.WritablePaths,
1604 bootclasspathArgs, classpathArgs, sourcepathArgs, opts string) {
1605 ctx.Build(pctx, android.BuildParams{
1606 Rule: javadoc,
1607 Description: "Jdiff",
1608 Output: d.jdiffStubsSrcJar,
1609 Inputs: d.Javadoc.srcFiles,
1610 Implicits: implicits,
1611 ImplicitOutputs: implicitOutputs,
1612 Args: map[string]string{
Nan Zhang23a1ba62018-09-19 11:19:39 -07001613 "outDir": android.PathForModuleOut(ctx, "jdiff-out").String(),
1614 "srcJarDir": android.PathForModuleOut(ctx, "jdiff-srcjars").String(),
1615 "stubsDir": android.PathForModuleOut(ctx, "jdiff-stubsDir").String(),
Nan Zhang71bbe632018-09-17 14:32:21 -07001616 "srcJars": strings.Join(d.Javadoc.srcJars.Strings(), " "),
1617 "opts": opts,
1618 "bootclasspathArgs": bootclasspathArgs,
1619 "classpathArgs": classpathArgs,
1620 "sourcepathArgs": sourcepathArgs,
1621 "docZip": d.jdiffDocZip.String(),
1622 },
1623 })
1624}
1625
Nan Zhang1598a9e2018-09-04 17:14:32 -07001626func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Nan Zhanga40da042018-08-01 12:48:00 -07001627 deps := d.Javadoc.collectDeps(ctx)
1628
1629 javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), sdkContext(d))
Nan Zhang581fd212018-01-10 16:06:12 -08001630
Nan Zhanga40da042018-08-01 12:48:00 -07001631 var implicits android.Paths
1632 implicits = append(implicits, d.Javadoc.srcJars...)
Nan Zhang1598a9e2018-09-04 17:14:32 -07001633 implicits = append(implicits, d.Javadoc.argFiles...)
Nan Zhanga40da042018-08-01 12:48:00 -07001634
1635 var implicitOutputs android.WritablePaths
Nan Zhang1598a9e2018-09-04 17:14:32 -07001636 for _, o := range d.Javadoc.properties.Out {
Nan Zhanga40da042018-08-01 12:48:00 -07001637 implicitOutputs = append(implicitOutputs, android.PathForModuleGen(ctx, o))
1638 }
1639
1640 flags, err := d.initBuilderFlags(ctx, &implicits, deps)
Nan Zhang2760dfc2018-08-24 17:32:54 +00001641 metalavaCheckApiImplicits := implicits
Nan Zhang71bbe632018-09-17 14:32:21 -07001642 jdiffImplicits := implicits
1643
Nan Zhanga40da042018-08-01 12:48:00 -07001644 if err != nil {
1645 return
1646 }
1647
Nan Zhang1598a9e2018-09-04 17:14:32 -07001648 flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
Nan Zhangdee152b2018-12-26 16:06:37 -08001649 flags.metalavaAnnotationsFlags, flags.metalavaMergeAnnoDirFlags =
1650 d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001651 flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang9c69a122018-08-22 10:22:08 -07001652 flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
Nan Zhang71bbe632018-09-17 14:32:21 -07001653 flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
1654
Nan Zhang1598a9e2018-09-04 17:14:32 -07001655 if strings.Contains(d.Javadoc.args, "--generate-documentation") {
1656 // Currently Metalava have the ability to invoke Javadoc in a seperate process.
1657 // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
1658 // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
1659 d.Javadoc.args = d.Javadoc.args + " -nodocs "
Nan Zhang79614d12018-04-19 18:03:39 -07001660 }
Nan Zhang1598a9e2018-09-04 17:14:32 -07001661 d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
1662 flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001663 flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
Nan Zhang71bbe632018-09-17 14:32:21 -07001664 flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
Nan Zhang61819ce2018-05-04 18:49:16 -07001665
Nan Zhang1598a9e2018-09-04 17:14:32 -07001666 if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
1667 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001668 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Api_file),
1669 "check_api.current.api_file")
1670 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Current.Removed_api_file),
1671 "check_api.current_removed_api_file")
1672
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 + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001677
Nan Zhang1598a9e2018-09-04 17:14:32 -07001678 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001679 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "current-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001680 fmt.Sprintf(`\n******************************\n`+
1681 `You have tried to change the API from what has been previously approved.\n\n`+
1682 `To make these errors go away, you have two choices:\n`+
1683 ` 1. You can add '@hide' javadoc comments to the methods, etc. listed in the\n`+
1684 ` errors above.\n\n`+
1685 ` 2. You can update current.txt by executing the following command:\n`+
1686 ` make %s-update-current-api\n\n`+
1687 ` To submit the revised current.txt to the main Android repository,\n`+
1688 ` you will need approval.\n`+
1689 `******************************\n`, ctx.ModuleName()),
1690 d.checkCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001691
1692 d.updateCurrentApiTimestamp = android.PathForModuleOut(ctx, "update_current_api.timestamp")
Nan Zhang1598a9e2018-09-04 17:14:32 -07001693 transformUpdateApi(ctx, apiFile, removedApiFile, d.apiFile, d.removedApiFile,
1694 d.updateCurrentApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001695 }
Nan Zhanga40da042018-08-01 12:48:00 -07001696
Nan Zhang1598a9e2018-09-04 17:14:32 -07001697 if apiCheckEnabled(d.properties.Check_api.Last_released, "last_released") &&
1698 !ctx.Config().IsPdkBuild() {
Nan Zhang61819ce2018-05-04 18:49:16 -07001699 apiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Api_file),
1700 "check_api.last_released.api_file")
1701 removedApiFile := ctx.ExpandSource(String(d.properties.Check_api.Last_released.Removed_api_file),
1702 "check_api.last_released.removed_api_file")
1703
Nan Zhang2760dfc2018-08-24 17:32:54 +00001704 d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
Neil Fullerb2f14ec2018-10-21 22:13:19 +01001705 opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
1706 flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
Nan Zhangdee152b2018-12-26 16:06:37 -08001707 removedApiFile.String() + flags.metalavaMergeAnnoDirFlags + " "
Nan Zhang2760dfc2018-08-24 17:32:54 +00001708
Nan Zhang1598a9e2018-09-04 17:14:32 -07001709 d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
Colin Cross39c16792019-01-24 16:32:44 -08001710 javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts, "last-apicheck",
Nan Zhang1598a9e2018-09-04 17:14:32 -07001711 `\n******************************\n`+
1712 `You have tried to change the API from what has been previously released in\n`+
1713 `an SDK. Please fix the errors listed above.\n`+
1714 `******************************\n`,
1715 d.checkLastReleasedApiTimestamp)
Nan Zhang61819ce2018-05-04 18:49:16 -07001716 }
Nan Zhang71bbe632018-09-17 14:32:21 -07001717
Pete Gillin581d6082018-10-22 15:55:04 +01001718 if String(d.properties.Check_nullability_warnings) != "" {
1719 if d.nullabilityWarningsFile == nil {
1720 ctx.PropertyErrorf("check_nullability_warnings",
1721 "Cannot specify check_nullability_warnings unless validating nullability")
1722 }
1723 checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
1724 "check_nullability_warnings")
1725 d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
1726 msg := fmt.Sprintf(`\n******************************\n`+
1727 `The warnings encountered during nullability annotation validation did\n`+
1728 `not match the checked in file of expected warnings. The diffs are shown\n`+
1729 `above. You have two options:\n`+
1730 ` 1. Resolve the differences by editing the nullability annotations.\n`+
1731 ` 2. Update the file of expected warnings by running:\n`+
1732 ` cp %s %s\n`+
1733 ` and submitting the updated file as part of your change.`,
1734 d.nullabilityWarningsFile, checkNullabilityWarnings)
1735 ctx.Build(pctx, android.BuildParams{
1736 Rule: nullabilityWarningsCheck,
1737 Description: "Nullability Warnings Check",
1738 Output: d.checkNullabilityWarningsTimestamp,
1739 Implicits: android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
1740 Args: map[string]string{
1741 "expected": checkNullabilityWarnings.String(),
1742 "actual": d.nullabilityWarningsFile.String(),
1743 "msg": msg,
1744 },
1745 })
1746 }
1747
Nan Zhang71bbe632018-09-17 14:32:21 -07001748 if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
1749
Nan Zhang86b06202018-09-21 17:09:21 -07001750 // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below
1751 // since there's cron job downstream that fetch this .zip file periodically.
1752 // See b/116221385 for reference.
Nan Zhang71bbe632018-09-17 14:32:21 -07001753 d.jdiffDocZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-docs.zip")
1754 d.jdiffStubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"jdiff-stubs.srcjar")
1755
1756 var jdiffImplicitOutputs android.WritablePaths
1757 jdiffImplicitOutputs = append(jdiffImplicitOutputs, d.jdiffDocZip)
1758
1759 jdiff := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "jdiff.jar")
1760 jdiffImplicits = append(jdiffImplicits, android.Paths{jdiff, d.apiXmlFile, d.lastReleasedApiXmlFile}...)
1761
Pete Gillin2b1ea2e2019-06-10 14:20:11 +01001762 opts := " -source 1.8 -J-Xmx1600m -XDignore.symbol.file " +
Nan Zhang71bbe632018-09-17 14:32:21 -07001763 "-doclet jdiff.JDiff -docletpath " + jdiff.String() + " -quiet " +
1764 "-newapi " + strings.TrimSuffix(d.apiXmlFile.Base(), d.apiXmlFile.Ext()) +
1765 " -newapidir " + filepath.Dir(d.apiXmlFile.String()) +
1766 " -oldapi " + strings.TrimSuffix(d.lastReleasedApiXmlFile.Base(), d.lastReleasedApiXmlFile.Ext()) +
1767 " -oldapidir " + filepath.Dir(d.lastReleasedApiXmlFile.String())
1768
1769 d.transformJdiff(ctx, jdiffImplicits, jdiffImplicitOutputs, flags.bootClasspathArgs, flags.classpathArgs,
1770 flags.sourcepathArgs, opts)
1771 }
Nan Zhang581fd212018-01-10 16:06:12 -08001772}
Dan Willemsencc090972018-02-26 14:33:31 -08001773
Nan Zhanga40da042018-08-01 12:48:00 -07001774//
Nan Zhangf4936b02018-08-01 15:00:28 -07001775// Exported Droiddoc Directory
Nan Zhanga40da042018-08-01 12:48:00 -07001776//
Dan Willemsencc090972018-02-26 14:33:31 -08001777var droiddocTemplateTag = dependencyTag{name: "droiddoc-template"}
Nan Zhangf4936b02018-08-01 15:00:28 -07001778var metalavaMergeAnnotationsDirTag = dependencyTag{name: "metalava-merge-annotations-dir"}
Pete Gillin77167902018-09-19 18:16:26 +01001779var metalavaMergeInclusionAnnotationsDirTag = dependencyTag{name: "metalava-merge-inclusion-annotations-dir"}
Nan Zhang9c69a122018-08-22 10:22:08 -07001780var metalavaAPILevelsAnnotationsDirTag = dependencyTag{name: "metalava-api-levels-annotations-dir"}
Dan Willemsencc090972018-02-26 14:33:31 -08001781
Nan Zhangf4936b02018-08-01 15:00:28 -07001782type ExportedDroiddocDirProperties struct {
1783 // path to the directory containing Droiddoc related files.
Dan Willemsencc090972018-02-26 14:33:31 -08001784 Path *string
1785}
1786
Nan Zhangf4936b02018-08-01 15:00:28 -07001787type ExportedDroiddocDir struct {
Dan Willemsencc090972018-02-26 14:33:31 -08001788 android.ModuleBase
1789
Nan Zhangf4936b02018-08-01 15:00:28 -07001790 properties ExportedDroiddocDirProperties
Dan Willemsencc090972018-02-26 14:33:31 -08001791
1792 deps android.Paths
1793 dir android.Path
1794}
1795
Nan Zhangf4936b02018-08-01 15:00:28 -07001796func ExportedDroiddocDirFactory() android.Module {
1797 module := &ExportedDroiddocDir{}
Dan Willemsencc090972018-02-26 14:33:31 -08001798 module.AddProperties(&module.properties)
1799 android.InitAndroidModule(module)
1800 return module
1801}
1802
Nan Zhangf4936b02018-08-01 15:00:28 -07001803func (d *ExportedDroiddocDir) DepsMutator(android.BottomUpMutatorContext) {}
Dan Willemsencc090972018-02-26 14:33:31 -08001804
Nan Zhangf4936b02018-08-01 15:00:28 -07001805func (d *ExportedDroiddocDir) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Colin Cross07e51612019-03-05 12:46:40 -08001806 path := String(d.properties.Path)
1807 d.dir = android.PathForModuleSrc(ctx, path)
Colin Cross8a497952019-03-05 22:25:09 -08001808 d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
Dan Willemsencc090972018-02-26 14:33:31 -08001809}
Nan Zhangb2b33de2018-02-23 11:18:47 -08001810
1811//
1812// Defaults
1813//
1814type DocDefaults struct {
1815 android.ModuleBase
1816 android.DefaultsModuleBase
1817}
1818
Nan Zhangb2b33de2018-02-23 11:18:47 -08001819func DocDefaultsFactory() android.Module {
1820 module := &DocDefaults{}
1821
1822 module.AddProperties(
1823 &JavadocProperties{},
1824 &DroiddocProperties{},
1825 )
1826
1827 android.InitDefaultsModule(module)
1828
1829 return module
1830}
Nan Zhang1598a9e2018-09-04 17:14:32 -07001831
1832func StubsDefaultsFactory() android.Module {
1833 module := &DocDefaults{}
1834
1835 module.AddProperties(
1836 &JavadocProperties{},
1837 &DroidstubsProperties{},
1838 )
1839
1840 android.InitDefaultsModule(module)
1841
1842 return module
1843}