• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 
17 package com.android.tools.lint.detector.api;
18 
19 import com.android.annotations.NonNull;
20 import com.android.annotations.Nullable;
21 import com.android.tools.lint.client.api.Configuration;
22 import com.google.common.annotations.Beta;
23 
24 import java.util.EnumSet;
25 
26 
27 /**
28  * An issue is a potential bug in an Android application. An issue is discovered
29  * by a {@link Detector}, and has an associated {@link Severity}.
30  * <p>
31  * Issues and detectors are separate classes because a detector can discover
32  * multiple different issues as it's analyzing code, and we want to be able to
33  * different severities for different issues, the ability to suppress one but
34  * not other issues from the same detector, and so on.
35  * <p/>
36  * <b>NOTE: This is not a public or final API; if you rely on this be prepared
37  * to adjust your code for the next tools release.</b>
38  */
39 @Beta
40 public final class Issue implements Comparable<Issue> {
41     private final String mId;
42     private final String mDescription;
43     private final String mExplanation;
44     private final Category mCategory;
45     private final int mPriority;
46     private final Severity mSeverity;
47     private String mMoreInfoUrl;
48     private boolean mEnabledByDefault = true;
49     private final EnumSet<Scope> mScope;
50     private final Class<? extends Detector> mClass;
51 
52     // Use factory methods
Issue( @onNull String id, @NonNull String description, @NonNull String explanation, @NonNull Category category, int priority, @NonNull Severity severity, @NonNull Class<? extends Detector> detectorClass, @NonNull EnumSet<Scope> scope)53     private Issue(
54             @NonNull String id,
55             @NonNull String description,
56             @NonNull String explanation,
57             @NonNull Category category,
58             int priority,
59             @NonNull Severity severity,
60             @NonNull Class<? extends Detector> detectorClass,
61             @NonNull EnumSet<Scope> scope) {
62         super();
63         mId = id;
64         mDescription = description;
65         mExplanation = explanation;
66         mCategory = category;
67         mPriority = priority;
68         mSeverity = severity;
69         mClass = detectorClass;
70         mScope = scope;
71     }
72 
73     /**
74      * Creates a new issue
75      *
76      * @param id the fixed id of the issue
77      * @param description the quick summary of the issue (one line)
78      * @param explanation a full explanation of the issue, with suggestions for
79      *            how to fix it
80      * @param category the associated category, if any
81      * @param priority the priority, a number from 1 to 10 with 10 being most
82      *            important/severe
83      * @param severity the default severity of the issue
84      * @param detectorClass the class of the detector to find this issue
85      * @param scope the scope of files required to analyze this issue
86      * @return a new {@link Issue}
87      */
88     @NonNull
create( @onNull String id, @NonNull String description, @NonNull String explanation, @NonNull Category category, int priority, @NonNull Severity severity, @NonNull Class<? extends Detector> detectorClass, @NonNull EnumSet<Scope> scope)89     public static Issue create(
90             @NonNull String id,
91             @NonNull String description,
92             @NonNull String explanation,
93             @NonNull Category category,
94             int priority,
95             @NonNull Severity severity,
96             @NonNull Class<? extends Detector> detectorClass,
97             @NonNull EnumSet<Scope> scope) {
98         return new Issue(id, description, explanation, category, priority, severity,
99                 detectorClass, scope);
100     }
101 
102     /**
103      * Returns the unique id of this issue. These should not change over time
104      * since they are used to persist the names of issues suppressed by the user
105      * etc. It is typically a single camel-cased word.
106      *
107      * @return the associated fixed id, never null and always unique
108      */
109     @NonNull
getId()110     public String getId() {
111         return mId;
112     }
113 
114     /**
115      * Briefly (one line) describes the kinds of checks performed by this rule
116      *
117      * @return a quick summary of the issue, never null
118      */
119     @NonNull
getDescription()120     public String getDescription() {
121         return mDescription;
122     }
123 
124     /**
125      * Describes the error found by this rule, e.g.
126      * "Buttons must define contentDescriptions". Preferably the explanation
127      * should also contain a description of how the problem should be solved.
128      * Additional info can be provided via {@link #getMoreInfo()}.
129      *
130      * @return an explanation of the issue, never null.
131      */
132     @NonNull
getExplanation()133     public String getExplanation() {
134         return mExplanation;
135     }
136 
137     /**
138      * The primary category of the issue
139      *
140      * @return the primary category of the issue, never null
141      */
142     @NonNull
getCategory()143     public Category getCategory() {
144         return mCategory;
145     }
146 
147     /**
148      * Returns a priority, in the range 1-10, with 10 being the most severe and
149      * 1 the least
150      *
151      * @return a priority from 1 to 10
152      */
getPriority()153     public int getPriority() {
154         return mPriority;
155     }
156 
157     /**
158      * Returns the default severity of the issues found by this detector (some
159      * tools may allow the user to specify custom severities for detectors).
160      * <p>
161      * Note that even though the normal way for an issue to be disabled is for
162      * the {@link Configuration} to return {@link Severity#IGNORE}, there is a
163      * {@link #isEnabledByDefault()} method which can be used to turn off issues
164      * by default. This is done rather than just having the severity as the only
165      * attribute on the issue such that an issue can be configured with an
166      * appropriate severity (such as {@link Severity#ERROR}) even when issues
167      * are disabled by default for example because they are experimental or not
168      * yet stable.
169      *
170      * @return the severity of the issues found by this detector
171      */
172     @NonNull
getDefaultSeverity()173     public Severity getDefaultSeverity() {
174         return mSeverity;
175     }
176 
177     /**
178      * Returns a link (a URL string) to more information, or null
179      *
180      * @return a link to more information, or null
181      */
182     @Nullable
getMoreInfo()183     public String getMoreInfo() {
184         return mMoreInfoUrl;
185     }
186 
187     /**
188      * Returns whether this issue should be enabled by default, unless the user
189      * has explicitly disabled it.
190      *
191      * @return true if this issue should be enabled by default
192      */
isEnabledByDefault()193     public boolean isEnabledByDefault() {
194         return mEnabledByDefault;
195     }
196 
197     /**
198      * Returns the scope required to analyze the code to detect this issue.
199      * This is determined by the detectors which reports the issue.
200      *
201      * @return the required scope
202      */
203     @NonNull
getScope()204     public EnumSet<Scope> getScope() {
205         return mScope;
206     }
207 
208     /**
209      * Sorts the detectors alphabetically by id. This is intended to make it
210      * convenient to store settings for detectors in a fixed order. It is not
211      * intended as the order to be shown to the user; for that, a tool embedding
212      * lint might consider the priorities, categories, severities etc of the
213      * various detectors.
214      *
215      * @param other the {@link Issue} to compare this issue to
216      */
217     @Override
compareTo(@onNull Issue other)218     public int compareTo(@NonNull Issue other) {
219         return getId().compareTo(other.getId());
220     }
221 
222     /**
223      * Sets a more info URL string
224      *
225      * @param moreInfoUrl url string
226      * @return this, for constructor chaining
227      */
228     @NonNull
setMoreInfo(@onNull String moreInfoUrl)229     public Issue setMoreInfo(@NonNull String moreInfoUrl) {
230         mMoreInfoUrl = moreInfoUrl;
231         return this;
232     }
233 
234     /**
235      * Sets whether this issue is enabled by default.
236      *
237      * @param enabledByDefault whether the issue should be enabled by default
238      * @return this, for constructor chaining
239      */
240     @NonNull
setEnabledByDefault(boolean enabledByDefault)241     public Issue setEnabledByDefault(boolean enabledByDefault) {
242         mEnabledByDefault = enabledByDefault;
243         return this;
244     }
245 
246     /**
247      * Returns the class of the detector to use to find this issue
248      *
249      * @return the class of the detector to use to find this issue
250      */
251     @NonNull
getDetectorClass()252     public Class<? extends Detector> getDetectorClass() {
253         return mClass;
254     }
255 
256     @Override
toString()257     public String toString() {
258         return mId;
259     }
260 }
261