19290dcdb94493c736d11121758504f062d893574Alan Viverette/*
217a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets * Copyright 2017 The Android Open Source Project
39290dcdb94493c736d11121758504f062d893574Alan Viverette *
49290dcdb94493c736d11121758504f062d893574Alan Viverette * Licensed under the Apache License, Version 2.0 (the "License");
59290dcdb94493c736d11121758504f062d893574Alan Viverette * you may not use this file except in compliance with the License.
69290dcdb94493c736d11121758504f062d893574Alan Viverette * You may obtain a copy of the License at
79290dcdb94493c736d11121758504f062d893574Alan Viverette *
89290dcdb94493c736d11121758504f062d893574Alan Viverette *      http://www.apache.org/licenses/LICENSE-2.0
99290dcdb94493c736d11121758504f062d893574Alan Viverette *
109290dcdb94493c736d11121758504f062d893574Alan Viverette * Unless required by applicable law or agreed to in writing, software
119290dcdb94493c736d11121758504f062d893574Alan Viverette * distributed under the License is distributed on an "AS IS" BASIS,
129290dcdb94493c736d11121758504f062d893574Alan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139290dcdb94493c736d11121758504f062d893574Alan Viverette * See the License for the specific language governing permissions and
149290dcdb94493c736d11121758504f062d893574Alan Viverette * limitations under the License.
159290dcdb94493c736d11121758504f062d893574Alan Viverette */
169290dcdb94493c736d11121758504f062d893574Alan Viverette
17526389b5eb93f99eaf4dba0b0c75b0b7df9a0f65Aurimas Liutikaspackage androidx.build.doclava
18cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
19cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viveretteimport org.gradle.api.tasks.Input
20cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viveretteimport org.gradle.api.tasks.InputFiles
21cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viveretteimport org.gradle.api.tasks.Optional
22cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viveretteimport org.gradle.api.tasks.OutputDirectory
23cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viveretteimport org.gradle.api.tasks.OutputFile
2417a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinetsimport org.gradle.api.tasks.javadoc.Javadoc
2517a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinetsimport org.gradle.external.javadoc.CoreJavadocOptions
2617a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinetsimport java.io.File
2717a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets
2817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets// external/doclava/src/com/google/doclava/Errors.java
29a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinetsval DEFAULT_DOCLAVA_CONFIG = ChecksConfig(
30a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        errors = listOf(
31a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets                101,  // unresolved link
32a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets                103,  // unknown tag
33a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets                104   // unknown param name
34a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        ),
35a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        warnings = listOf(121 /* hidden type param */),
36a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        hidden = listOf(
37a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets                111,  // hidden super class
38a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets                113   // @deprecation mismatch
39a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        )
4017a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets)
4117a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets
4217a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinetsprivate fun <E> CoreJavadocOptions.addMultilineMultiValueOption(
43a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets    name: String,
44a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets    values: Collection<E>
45a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets) {
46a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets    addMultilineMultiValueOption(name).value = values.map { listOf(it.toString()) }
4717a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets}
48cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
4917a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinetsopen class DoclavaTask : Javadoc() {
50cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
51cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    // All lowercase name to match MinimalJavadocOptions#docletpath
5217a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    private var docletpath: List<File> = emptyList()
53cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
54cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Input
55a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets    var checksConfig: ChecksConfig = DEFAULT_DOCLAVA_CONFIG
56cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
57cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
58cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If non-null, the list of packages that will be treated as if they were
59cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * marked with {@literal @hide}.<br>
60cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * Packages names will be matched exactly; sub-packages are not automatically recognized.
61cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
62cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Optional
63cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Input
6417a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    var hiddenPackages: Collection<String>? = null
65cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
66cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
67cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If non-null and not-empty, the whitelist of packages that will be present in the generated
68cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * stubs; if null or empty, then all packages have stubs generated.<br>
69cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * Wildcards are accepted.
70cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
71cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Optional
72cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Input
7317a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    var stubPackages: Set<String>? = null
74cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
75cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Input
7617a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    var generateDocs = true
77cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
78cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
79cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If non-null, the location of where to place the generated api file.
80cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If this is non-null, then {@link #removedApiFile} must be non-null as well.
81cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
82cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Optional
83cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @OutputFile
8417a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    var apiFile: File? = null
85cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
86cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
87cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If non-null, the location of where to place the generated removed api file.
88cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If this is non-null, then {@link #apiFile} must be non-null as well.
89cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
90cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Optional
91cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @OutputFile
9217a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    var removedApiFile: File? = null
93cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
94cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
95cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If non-null, the location of the generated keep list.
96cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
97cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Optional
98cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @OutputFile
9917a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    var keepListFile: File? = null
100cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
101cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
102cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * If non-null, the location to put the generated stub sources.
103cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
104cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @Optional
105cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @OutputDirectory
10617a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    var stubsDir: File? = null
107cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
10817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    init {
10917a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        setFailOnError(true)
110cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        options.doclet = "com.google.doclava.Doclava"
111cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        options.encoding("UTF-8")
112cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        options.quiet()
113cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        // doclava doesn't understand '-doctitle'
114cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        title = null
115cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        maxMemory = "1280m"
1167b68068be70799a3527a0dec00873690443b800fAlan Viverette        // If none of generateDocs, apiFile, keepListFile, or stubJarsDir are true, then there is
1177b68068be70799a3527a0dec00873690443b800fAlan Viverette        // no work to do.
11817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        onlyIf({ generateDocs || apiFile != null || keepListFile != null || stubsDir != null })
119cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    }
120cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
121cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
122cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * The doclet path which has the {@code com.gogole.doclava.Doclava} class.
123db838b10d0df476c8e2319461a79c910b260cd81Aurimas Liutikas     * This option will override any doclet path set in this instance's
124db838b10d0df476c8e2319461a79c910b260cd81Aurimas Liutikas     * {@link #options JavadocOptions}.
125cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * @see MinimalJavadocOptions#getDocletpath()
126cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
127cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    @InputFiles
12817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    fun getDocletpath(): List<File> {
12917a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        return docletpath
130cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    }
131cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
132cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
133cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * Sets the doclet path which has the {@code com.gogole.doclava.Doclava} class.
134db838b10d0df476c8e2319461a79c910b260cd81Aurimas Liutikas     * This option will override any doclet path set in this instance's
135db838b10d0df476c8e2319461a79c910b260cd81Aurimas Liutikas     * {@link #options JavadocOptions}.
136cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * @see MinimalJavadocOptions#setDocletpath(java.util.List)
137cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
13817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    fun setDocletpath(docletpath: Collection<File>) {
13917a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        this.docletpath = docletpath.toList()
140cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        // Go ahead and keep the docletpath in our JavadocOptions object in sync.
14117a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        options.docletpath = docletpath.toList()
142cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    }
143cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
144cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    /**
145cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * "Configures" this DoclavaTask with parameters that might not be at their final values
146cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     * until this task is run.
147cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette     */
14817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    private fun configureDoclava() = (options as CoreJavadocOptions).apply {
149a192828d56310f78603b46440c95abd0c4bd76ccAurimas Liutikas
15017a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        docletpath = this@DoclavaTask.docletpath
151a192828d56310f78603b46440c95abd0c4bd76ccAurimas Liutikas
15217a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        // configure doclava error/warning/hide levels
153a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        addMultilineMultiValueOption("hide", checksConfig.hidden)
154a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        addMultilineMultiValueOption("warning", checksConfig.warnings)
155a14b834943469c91933a93da68c81f0ebc0a5719Sergey Vasilinets        addMultilineMultiValueOption("error", checksConfig.errors)
156cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
15717a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        if (hiddenPackages != null) {
15817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets            addMultilineMultiValueOption("hidePackage", hiddenPackages!!)
159cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        }
160cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
16117a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        if (!generateDocs) {
162db838b10d0df476c8e2319461a79c910b260cd81Aurimas Liutikas            addBooleanOption("nodocs", true)
163cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        }
1647b68068be70799a3527a0dec00873690443b800fAlan Viverette
1657b68068be70799a3527a0dec00873690443b800fAlan Viverette        // If requested, generate the API files.
1667b68068be70799a3527a0dec00873690443b800fAlan Viverette        if (apiFile != null) {
16717a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets            addFileOption("api", apiFile)
16817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets            addFileOption("removedApi", removedApiFile)
169cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        }
1707b68068be70799a3527a0dec00873690443b800fAlan Viverette
171cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        // If requested, generate the keep list.
17217a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets        addFileOption("proguard", keepListFile)
17317a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets
174cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        // If requested, generate stubs.
175cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        if (stubsDir != null) {
17617a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets            addFileOption("stubs", stubsDir)
17717a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets            val stubs = stubPackages
17817a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets            if (stubs != null) {
17917a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets                addStringOption("stubpackages", stubs.joinToString(":"))
180cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette            }
181cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette        }
182f354ae55994777773b771d0f4a929f9771410332Alan Viverette        // Always treat this as an Android docs task.
183db838b10d0df476c8e2319461a79c910b260cd81Aurimas Liutikas        addBooleanOption("android", true)
184cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    }
185cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette
18622b62144c356a00c27edec095c244c7a1c88f694Sergey Vasilinets    fun coreJavadocOptions(configure: CoreJavadocOptions.() -> Unit) =
18722b62144c356a00c27edec095c244c7a1c88f694Sergey Vasilinets            (options as CoreJavadocOptions).configure()
18822b62144c356a00c27edec095c244c7a1c88f694Sergey Vasilinets
18917a1890938be2900196bf3095e2f91db8b62413fSergey Vasilinets    override fun generate() {
1907b68068be70799a3527a0dec00873690443b800fAlan Viverette        configureDoclava()
1917b68068be70799a3527a0dec00873690443b800fAlan Viverette        super.generate()
192cc5197e1c75195409a5c3289df31b3025d3fb364Alan Viverette    }
1937b68068be70799a3527a0dec00873690443b800fAlan Viverette}
194