• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.support.doclava;
18
19import org.gradle.api.InvalidUserDataException
20import org.gradle.api.Nullable
21import org.gradle.api.tasks.Input
22import org.gradle.api.tasks.InputFiles
23import org.gradle.api.tasks.javadoc.Javadoc
24import org.gradle.api.tasks.Optional
25import org.gradle.api.tasks.OutputDirectory
26import org.gradle.api.tasks.OutputFile
27import org.gradle.api.tasks.ParallelizableTask
28
29@ParallelizableTask
30public class DoclavaTask extends Javadoc {
31
32    // external/doclava/src/com/google/doclava/Errors.java
33    public static final def DEFAULT_DOCLAVA_ERRORS = Collections.unmodifiableSet([
34            101,    // unresolved link
35            103,    // unknown tag
36            104,    // unknown param name
37    ] as Set)
38
39    public static final def DEFAULT_DOCLAVA_WARNINGS = Collections.unmodifiableSet([
40            121,    // hidden type param
41    ] as Set)
42
43
44    public static final def DEFAULT_DOCLAVA_HIDDEN = Collections.unmodifiableSet([
45            111,    // hidden super class
46            113,    // @deprecation mismatch
47    ] as Set)
48
49
50    // All lowercase name to match MinimalJavadocOptions#docletpath
51    private Collection<File> mDocletpath
52
53    // doclava error types which will cause the build to fail
54    @Input
55    Collection doclavaErrors = DEFAULT_DOCLAVA_ERRORS
56    @Input
57    Collection doclavaWarnings = DEFAULT_DOCLAVA_WARNINGS
58    // spammy doclava warnings which we want to hide
59    @Input
60    Collection doclavaHidden = DEFAULT_DOCLAVA_HIDDEN
61
62    /**
63     * If non-null, the list of packages that will be treated as if they were
64     * marked with {@literal @hide}.<br>
65     * Packages names will be matched exactly; sub-packages are not automatically recognized.
66     */
67    @Optional
68    @Nullable
69    @Input
70    Collection hiddenPackages = null
71
72    /**
73     * If non-null and not-empty, the whitelist of packages that will be present in the generated
74     * stubs; if null or empty, then all packages have stubs generated.<br>
75     * Wildcards are accepted.
76     */
77    @Optional
78    @Nullable
79    @Input
80    Set<String> stubPackages = null
81
82    @Input
83    boolean generateDocs = true
84
85    /**
86     * If non-null, the location of where to place the generated api file.
87     * If this is non-null, then {@link #removedApiFile} must be non-null as well.
88     */
89    @Optional
90    @Nullable
91    @OutputFile
92    File apiFile = null
93
94    /**
95     * If non-null, the location of where to place the generated removed api file.
96     * If this is non-null, then {@link #apiFile} must be non-null as well.
97     */
98    @Optional
99    @Nullable
100    @OutputFile
101    File removedApiFile = null
102
103    /**
104     * If non-null, the location of the generated keep list.
105     */
106    @Optional
107    @Nullable
108    @OutputFile
109    File keepListFile = null
110
111    /**
112     * If non-null, the location to put the generated stub sources.
113     */
114    @Optional
115    @Nullable
116    @OutputDirectory
117    File stubsDir = null
118
119    public DoclavaTask() {
120        failOnError = true
121        options.doclet = "com.google.doclava.Doclava"
122        options.encoding("UTF-8")
123        options.quiet()
124        // doclava doesn't understand '-doctitle'
125        title = null
126        maxMemory = "1280m"
127        // TODO(csyoung) Some way to override this?
128        // If none of generateDocs, apiFile, keepListFile, or stubJarsDir are true, then there is no work to do.
129        onlyIf( { getGenerateDocs() ||
130                (getApiFile() != null && getRemovedApiFile() != null) ||
131                getKeepListFile() != null ||
132                getStubsDir() != null } )
133    }
134
135    /**
136     * The doclet path which has the {@code com.gogole.doclava.Doclava} class.
137     * This option will override any doclet path set in this instance's {@link #options JavadocOptions}.
138     * @see MinimalJavadocOptions#getDocletpath()
139     */
140    @InputFiles
141    public Collection<File> getDocletpath() {
142        return mDocletpath
143    }
144
145    /**
146     * Sets the doclet path which has the {@code com.gogole.doclava.Doclava} class.
147     * This option will override any doclet path set in this instance's {@link #options JavadocOptions}.
148     * @see MinimalJavadocOptions#setDocletpath(java.util.List)
149     */
150    public void setDocletpath(Collection<File> docletpath) {
151        mDocletpath = docletpath
152        // Go ahead and keep the docletpath in our JavadocOptions object in sync.
153        options.docletpath = docletpath as List
154    }
155
156    public void setDoclavaErrors(Collection errors) {
157        // Make it serializable.
158        doclavaErrors = errors as int[]
159    }
160
161    public void setDoclavaWarnings(Collection warnings) {
162        // Make it serializable.
163        doclavaWarnings = warnings as int[]
164    }
165
166    public void setDoclavaHidden(Collection hidden) {
167        // Make it serializable.
168        doclavaHidden = hidden as int[]
169    }
170
171    private static boolean verifyAndGetGenerateApiFiles(File apiFile, File removedApiFile) {
172        if (apiFile == null) {
173            if (removedApiFile == null) {
174                return false
175            } else {
176                throw new InvalidUserDataException('removedApiFile specified but not apiFile')
177            }
178        } else {
179            return true
180        }
181    }
182
183    /**
184     * "Configures" this DoclavaTask with parameters that might not be at their final values
185     * until this task is run.
186     */
187    private configureDoclava() {
188        options.docletpath = getDocletpath() as List
189        // configure doclava error/warning/hide levels
190        options.addOption(new DoclavaMultilineJavadocOptionFileOption('hide'))
191                .setValue(getDoclavaHidden().collect({[it.toString()]}))
192        options.addOption(new DoclavaMultilineJavadocOptionFileOption('warning'))
193                .setValue(getDoclavaWarnings().collect({[it.toString()]}))
194        options.addOption(new DoclavaMultilineJavadocOptionFileOption('error'))
195                .setValue(getDoclavaErrors().collect({[it.toString()]}))
196
197        Collection hiddenPackages = getHiddenPackages()
198        if (hiddenPackages) {
199            options.addOption(new DoclavaMultilineJavadocOptionFileOption('hidePackage'))
200                    .setValue(hiddenPackages.collect({[it.toString()]}))
201        }
202
203        if (!getGenerateDocs()) {
204            options.addOption(new DoclavaJavadocOptionFileOption('nodocs'))
205        }
206        // If requested, generate the api files.
207        File apiFile = getApiFile()
208        File removedApiFile = getRemovedApiFile()
209        if (verifyAndGetGenerateApiFiles(apiFile, removedApiFile)) {
210            options.addStringOption('api', apiFile.absolutePath)
211            options.addStringOption('removedApi', removedApiFile.absolutePath)
212        }
213        // If requested, generate the keep list.
214        File keepListFile = getKeepListFile()
215        if (keepListFile != null) {
216            options.addStringOption('proguard', keepListFile.absolutePath)
217        }
218        // If requested, generate stubs.
219        File stubsDir = getStubsDir()
220        if (stubsDir != null) {
221            options.addStringOption('stubs', stubsDir.absolutePath)
222            Set<String> stubPackages = getStubPackages()
223            if (stubPackages) {
224                options.addStringOption('stubpackages', stubPackages.join(':'))
225            }
226        }
227        // Always treat this as an Android docs task.
228        options.addOption(new DoclavaJavadocOptionFileOption('android'))
229    }
230
231    @Override
232    public void generate() {
233        configureDoclava();
234        super.generate();
235    }
236}