blob: c268e370766f4278f1cb0c64cebad9bd47ec3e95 [file] [log] [blame]
package org.jetbrains.android.inspections.lint;
import com.android.SdkConstants;
import com.android.ide.common.repository.GradleCoordinate;
import com.android.ide.common.resources.ResourceUrl;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.common.resources.configuration.VersionQualifier;
import com.android.resources.ResourceFolderType;
import com.android.sdklib.AndroidVersion;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkVersionInfo;
import com.android.tools.idea.actions.OverrideResourceAction;
import com.android.tools.idea.res.ResourceHelper;
import com.android.tools.idea.templates.RepositoryUrlManager;
import com.android.tools.idea.uibuilder.actions.UpgradeConstraintLayoutFix;
import com.android.tools.lint.checks.*;
import com.android.tools.lint.detector.api.Issue;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.refactoring.UnusedResourcesQuickFix;
import org.jetbrains.android.sdk.AndroidSdkData;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.android.SdkConstants.*;
import static com.android.tools.lint.checks.ApiDetector.REQUIRES_API_ANNOTATION;
import static com.android.tools.lint.checks.FragmentDetector.ISSUE;
import static com.android.tools.lint.checks.PluralsDetector.IMPLIED_QUANTITY;
import static com.android.tools.lint.detector.api.TextFormat.RAW;
import static com.android.xml.AndroidManifest.*;
/**
* Registrations for all the various Lint rules as local IDE inspections, along with quickfixes for many of them
*/
public class AndroidLintInspectionToolProvider {
public static class AndroidLintCustomErrorInspection extends AndroidLintInspectionBase {
public AndroidLintCustomErrorInspection() {
super("Error from Custom Lint Check", IntellijLintIssueRegistry.CUSTOM_ERROR);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return ShowCustomIssueExplanationFix.getFixes(startElement, message);
}
}
public static class AndroidLintCustomWarningInspection extends AndroidLintInspectionBase {
public AndroidLintCustomWarningInspection() {
super("Warning from Custom Lint Check", IntellijLintIssueRegistry.CUSTOM_WARNING);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return ShowCustomIssueExplanationFix.getFixes(startElement, message);
}
}
public static class AndroidLintAaptCrashInspection extends AndroidLintInspectionBase {
public AndroidLintAaptCrashInspection() {
super(AndroidBundle.message("android.lint.inspections.aapt.crash"), ResourceCycleDetector.CRASH);
}
}
public static class AndroidLintInconsistentArraysInspection extends AndroidLintInspectionBase {
public AndroidLintInconsistentArraysInspection() {
super(AndroidBundle.message("android.lint.inspections.inconsistent.arrays"), ArraySizeDetector.INCONSISTENT);
}
}
public static class AndroidLintInconsistentLayoutInspection extends AndroidLintInspectionBase {
public AndroidLintInconsistentLayoutInspection() {
super(AndroidBundle.message("android.lint.inspections.inconsistent.layout"), LayoutConsistencyDetector.INCONSISTENT_IDS);
}
}
public static class AndroidLintDuplicateIncludedIdsInspection extends AndroidLintInspectionBase {
public AndroidLintDuplicateIncludedIdsInspection() {
super(AndroidBundle.message("android.lint.inspections.duplicate.included.ids"), DuplicateIdDetector.CROSS_LAYOUT);
}
}
public static class AndroidLintIconExpectedSizeInspection extends AndroidLintInspectionBase {
public AndroidLintIconExpectedSizeInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.expected.size"), IconDetector.ICON_EXPECTED_SIZE);
}
}
public static class AndroidLintIconDipSizeInspection extends AndroidLintInspectionBase {
public AndroidLintIconDipSizeInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.dip.size"), IconDetector.ICON_DIP_SIZE);
}
}
public static class AndroidLintIconLocationInspection extends AndroidLintInspectionBase {
public AndroidLintIconLocationInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.location"), IconDetector.ICON_LOCATION);
}
}
public static class AndroidLintIconDensitiesInspection extends AndroidLintInspectionBase {
public AndroidLintIconDensitiesInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.densities"), IconDetector.ICON_DENSITIES);
}
}
public static class AndroidLintIconMissingDensityFolderInspection extends AndroidLintInspectionBase {
public AndroidLintIconMissingDensityFolderInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.missing.density.folder"), IconDetector.ICON_MISSING_FOLDER);
}
}
public static class AndroidLintIconMixedNinePatchInspection extends AndroidLintInspectionBase {
public AndroidLintIconMixedNinePatchInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.mixed.nine.patch"), IconDetector.ICON_MIX_9PNG);
}
}
public static class AndroidLintFloatMathInspection extends AndroidLintInspectionBase {
public AndroidLintFloatMathInspection() {
super(AndroidBundle.message("android.lint.inspections.float.math"), MathDetector.ISSUE);
}
}
public static class AndroidLintFullBackupContentInspection extends AndroidLintInspectionBase {
public AndroidLintFullBackupContentInspection() {
super(AndroidBundle.message("android.lint.inspections.full.backup.content"), FullBackupContentDetector.ISSUE);
}
}
public static class AndroidLintGetInstanceInspection extends AndroidLintInspectionBase {
public AndroidLintGetInstanceInspection() {
super(AndroidBundle.message("android.lint.inspections.get.instance"), CipherGetInstanceDetector.ISSUE);
}
}
public static class AndroidLintGifUsageInspection extends AndroidLintInspectionBase {
public AndroidLintGifUsageInspection() {
super(AndroidBundle.message("android.lint.inspections.gif.usage"), IconDetector.GIF_USAGE);
}
}
public static class AndroidLintIconDuplicatesInspection extends AndroidLintInspectionBase {
public AndroidLintIconDuplicatesInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.duplicates"), IconDetector.DUPLICATES_NAMES);
}
}
public static class AndroidLintIconDuplicatesConfigInspection extends AndroidLintInspectionBase {
public AndroidLintIconDuplicatesConfigInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.duplicates.config"), IconDetector.DUPLICATES_CONFIGURATIONS);
}
}
public static class AndroidLintIconNoDpiInspection extends AndroidLintInspectionBase {
public AndroidLintIconNoDpiInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.no.dpi"), IconDetector.ICON_NODPI);
}
}
public static class AndroidLintOverdrawInspection extends AndroidLintInspectionBase {
public AndroidLintOverdrawInspection() {
super(AndroidBundle.message("android.lint.inspections.overdraw"), OverdrawDetector.ISSUE);
}
}
public static class AndroidLintMissingSuperCallInspection extends AndroidLintInspectionBase {
public AndroidLintMissingSuperCallInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.super.call"), CallSuperDetector.ISSUE);
}
}
public static class AndroidLintMissingTranslationInspection extends AndroidLintInspectionBase {
public AndroidLintMissingTranslationInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.translation"), TranslationDetector.MISSING);
}
}
public static class AndroidLintExtraTranslationInspection extends AndroidLintInspectionBase {
public AndroidLintExtraTranslationInspection() {
super(AndroidBundle.message("android.lint.inspections.extra.translation"), TranslationDetector.EXTRA);
}
}
public static class AndroidLintUnusedResourcesInspection extends AndroidLintInspectionBase {
public AndroidLintUnusedResourcesInspection() {
super(AndroidBundle.message("android.lint.inspections.unused.resources"), UnusedResourceDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
String resource = UnusedResourceDetector.getUnusedResource(message, RAW);
if (resource != null) {
String resourceUrl = "@" + resource.substring(2).replace('.', '/');
return new AndroidLintQuickFix[]{
new UnusedResourcesQuickFix(null),
new UnusedResourcesQuickFix(resource),
new SetAttributeQuickFix("Add a tools:keep attribute to mark as implicitly used", ATTR_KEEP, TOOLS_URI, resourceUrl)};
} else {
return new AndroidLintQuickFix[] {new UnusedResourcesQuickFix(null) };
}
}
}
public static class AndroidLintUnprotectedSMSBroadcastReceiverInspection extends AndroidLintInspectionBase {
public AndroidLintUnprotectedSMSBroadcastReceiverInspection() {
super(AndroidBundle.message("android.lint.inspections.unprotected.smsbroadcast.receiver"), UnsafeBroadcastReceiverDetector.BROADCAST_SMS);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return new AndroidLintQuickFix[] {
new SetAttributeQuickFix("Set permission attribute", ATTR_PERMISSION, "android.permission.BROADCAST_SMS")
};
}
}
public static class AndroidLintUnusedAttributeInspection extends AndroidLintInspectionBase {
public AndroidLintUnusedAttributeInspection() {
super(AndroidBundle.message("android.lint.inspections.unused.attribute"), ApiDetector.UNUSED);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return getApiDetectorFixes(ApiDetector.INLINED, startElement, endElement, message);
}
}
public static class AndroidLintUnusedIdsInspection extends AndroidLintInspectionBase {
public AndroidLintUnusedIdsInspection() {
super(AndroidBundle.message("android.lint.inspections.unused.ids"), UnusedResourceDetector.ISSUE_IDS);
}
}
public static class AndroidLintAlwaysShowActionInspection extends AndroidLintInspectionBase {
public AndroidLintAlwaysShowActionInspection() {
super(AndroidBundle.message("android.lint.inspections.always.show.action"), AlwaysShowActionDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] { new ReplaceStringQuickFix("Replace with ifRoom", "(always)", "ifRoom") };
}
}
public static class AndroidLintAppCompatMethodInspection extends AndroidLintInspectionBase {
public AndroidLintAppCompatMethodInspection() {
super(AndroidBundle.message("android.lint.inspections.app.compat.method"), AppCompatCallDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String oldCall = AppCompatCallDetector.getOldCall(message, RAW);
String newCall = AppCompatCallDetector.getNewCall(message, RAW);
if (oldCall != null && newCall != null) {
return new AndroidLintQuickFix[]{ new ReplaceStringQuickFix("Replace with " + newCall + "()", oldCall, newCall) };
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintAppCompatResourceInspection extends AndroidLintInspectionBase {
public AndroidLintAppCompatResourceInspection() {
super(AndroidBundle.message("android.lint.inspections.app.compat.resource"), AppCompatResourceDetector.ISSUE);
}
}
private static AndroidLintQuickFix[] getAppIndexingQuickFix(PsiElement startElement, PsiElement endElement, String message) {
AppIndexingApiDetector.IssueType type = AppIndexingApiDetector.IssueType.parse(message);
switch (type) {
case SCHEME_MISSING:
case URL_MISSING:
return new AndroidLintQuickFix[]{ new SetAttributeQuickFix("Set scheme", SdkConstants.ATTR_SCHEME, "http")};
case HOST_MISSING:
return new AndroidLintQuickFix[]{ new SetAttributeQuickFix("Set host", SdkConstants.ATTR_HOST, null)};
case MISSING_SLASH:
PsiElement parent = startElement.getParent();
if (parent instanceof XmlAttribute) {
XmlAttribute attr = (XmlAttribute) parent;
String path = attr.getValue();
if (path != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Replace with /" + path, path, "/" + path)};
}
}
break;
default:
break;
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
public static class AndroidLintGoogleAppIndexingUrlErrorInspection extends AndroidLintInspectionBase {
public AndroidLintGoogleAppIndexingUrlErrorInspection() {
super(AndroidBundle.message("android.lint.inspections.google.app.indexing.url.error"), AppIndexingApiDetector.ISSUE_URL_ERROR);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return getAppIndexingQuickFix(startElement, endElement, message);
}
}
public static class AndroidLintGoogleAppIndexingWarningInspection extends AndroidLintInspectionBase {
public AndroidLintGoogleAppIndexingWarningInspection() {
super(AndroidBundle.message("android.lint.inspections.google.app.indexing.warning"), AppIndexingApiDetector.ISSUE_APP_INDEXING);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return getAppIndexingQuickFix(startElement, endElement, message);
}
}
public static class AndroidLintGoogleAppIndexingApiWarningInspection extends AndroidLintInspectionBase {
public AndroidLintGoogleAppIndexingApiWarningInspection() {
super(AndroidBundle.message("android.lint.inspections.google.app.indexing.api.warning"), AppIndexingApiDetector.ISSUE_APP_INDEXING_API);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return getAppIndexingQuickFix(startElement, endElement, message);
}
}
public static class AndroidLintAppLinksAutoVerifyErrorInspection extends AndroidLintInspectionBase {
public AndroidLintAppLinksAutoVerifyErrorInspection() {
super(AndroidBundle.message("android.lint.inspections.app.links.auto.verify.error"), AppLinksAutoVerifyDetector.ISSUE_ERROR);
}
}
public static class AndroidLintAppLinksAutoVerifyWarningInspection extends AndroidLintInspectionBase {
public AndroidLintAppLinksAutoVerifyWarningInspection() {
super(AndroidBundle.message("android.lint.inspections.app.links.auto.verify.warning"), AppLinksAutoVerifyDetector.ISSUE_WARNING);
}
}
public static class AndroidLintAssertInspection extends AndroidLintInspectionBase {
public AndroidLintAssertInspection() {
super(AndroidBundle.message("android.lint.inspections.assert"), AssertDetector.ISSUE);
}
}
public static class AndroidLintStringFormatCountInspection extends AndroidLintInspectionBase {
public AndroidLintStringFormatCountInspection() {
super(AndroidBundle.message("android.lint.inspections.string.format.count"), StringFormatDetector.ARG_COUNT);
}
}
public static class AndroidLintStringFormatMatchesInspection extends AndroidLintInspectionBase {
public AndroidLintStringFormatMatchesInspection() {
super(AndroidBundle.message("android.lint.inspections.string.format.matches"), StringFormatDetector.ARG_TYPES);
}
}
public static class AndroidLintStringFormatInvalidInspection extends AndroidLintInspectionBase {
public AndroidLintStringFormatInvalidInspection() {
super(AndroidBundle.message("android.lint.inspections.string.format.invalid"), StringFormatDetector.INVALID);
}
}
public static class AndroidLintWrongRegionInspection extends AndroidLintInspectionBase {
public AndroidLintWrongRegionInspection() {
super(AndroidBundle.message("android.lint.inspections.wrong.region"), LocaleFolderDetector.WRONG_REGION);
}
}
public static class AndroidLintWrongViewCastInspection extends AndroidLintInspectionBase {
public AndroidLintWrongViewCastInspection() {
super(AndroidBundle.message("android.lint.inspections.wrong.view.cast"), ViewTypeDetector.ISSUE);
}
}
public static class AndroidLintUnknownIdInspection extends AndroidLintInspectionBase {
public AndroidLintUnknownIdInspection() {
super(AndroidBundle.message("android.lint.inspections.unknown.id"), WrongIdDetector.UNKNOWN_ID);
}
}
public static class AndroidLintCommitTransactionInspection extends AndroidLintInspectionBase {
public AndroidLintCommitTransactionInspection() {
super(AndroidBundle.message("android.lint.inspections.commit.transaction"), CleanupDetector.COMMIT_FRAGMENT);
}
}
/**
* Local inspections processed by AndroidLintExternalAnnotator
*/
public static class AndroidLintContentDescriptionInspection extends AndroidLintInspectionBase {
public AndroidLintContentDescriptionInspection() {
super(AndroidBundle.message("android.lint.inspections.content.description"), AccessibilityDetector.ISSUE);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{
new SetAttributeQuickFix(AndroidBundle.message("android.lint.fix.add.content.description"),
SdkConstants.ATTR_CONTENT_DESCRIPTION, null)
};
}
}
public static class AndroidLintButtonOrderInspection extends AndroidLintInspectionBase {
public AndroidLintButtonOrderInspection() {
super(AndroidBundle.message("android.lint.inspections.button.order"), ButtonDetector.ORDER);
}
}
public static class AndroidLintBackButtonInspection extends AndroidLintInspectionBase {
public AndroidLintBackButtonInspection() {
super(AndroidBundle.message("android.lint.inspections.back.button"), ButtonDetector.BACK_BUTTON);
}
}
public static class AndroidLintBadHostnameVerifierInspection extends AndroidLintInspectionBase {
public AndroidLintBadHostnameVerifierInspection() {
super(AndroidBundle.message("android.lint.inspections.bad.hostname.verifier"), BadHostnameVerifierDetector.ISSUE);
}
}
public static class AndroidLintBatteryLifeInspection extends AndroidLintInspectionBase {
public AndroidLintBatteryLifeInspection() {
super(AndroidBundle.message("android.lint.inspections.battery.life"), BatteryDetector.ISSUE);
}
}
public static class AndroidLintButtonCaseInspection extends AndroidLintInspectionBase {
public AndroidLintButtonCaseInspection() {
super(AndroidBundle.message("android.lint.inspections.button.case"), ButtonDetector.CASE);
}
}
public static class AndroidLintExtraTextInspection extends AndroidLintInspectionBase {
public AndroidLintExtraTextInspection() {
super(AndroidBundle.message("android.lint.inspections.extra.text"), ExtraTextDetector.ISSUE);
}
}
public static class AndroidLintHandlerLeakInspection extends AndroidLintInspectionBase {
public AndroidLintHandlerLeakInspection() {
super(AndroidBundle.message("android.lint.inspections.handler.leak"), HandlerDetector.ISSUE);
}
}
public static class AndroidLintHardcodedDebugModeInspection extends AndroidLintInspectionBase {
public AndroidLintHardcodedDebugModeInspection() {
super(AndroidBundle.message("android.lint.inspections.hardcoded.debug.mode"), HardcodedDebugModeDetector.ISSUE);
}
}
public static class AndroidLintHardwareIdsInspection extends AndroidLintInspectionBase {
public AndroidLintHardwareIdsInspection() {
super(AndroidBundle.message("android.lint.inspections.hardware.ids"), HardwareIdDetector.ISSUE);
}
}
public static class AndroidLintDrawAllocationInspection extends AndroidLintInspectionBase {
public AndroidLintDrawAllocationInspection() {
super(AndroidBundle.message("android.lint.inspections.draw.allocation"), JavaPerformanceDetector.PAINT_ALLOC);
}
}
public static class AndroidLintUseSparseArraysInspection extends AndroidLintInspectionBase {
public AndroidLintUseSparseArraysInspection() {
super(AndroidBundle.message("android.lint.inspections.use.sparse.arrays"), JavaPerformanceDetector.USE_SPARSE_ARRAY);
}
}
public static class AndroidLintUseValueOfInspection extends AndroidLintInspectionBase {
public AndroidLintUseValueOfInspection() {
super(AndroidBundle.message("android.lint.inspections.use.value.of"), JavaPerformanceDetector.USE_VALUE_OF);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String replacedType = JavaPerformanceDetector.getReplacedType(message, RAW);
if (replacedType != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Replace with valueOf()", "(new\\s+" + replacedType + ")",
replacedType + ".valueOf")};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintLibraryCustomViewInspection extends AndroidLintInspectionBase {
public AndroidLintLibraryCustomViewInspection() {
// TODO: Quickfix
super(AndroidBundle.message("android.lint.inspections.library.custom.view"), NamespaceDetector.CUSTOM_VIEW);
}
}
public static class AndroidLintPackageManagerGetSignaturesInspection extends AndroidLintInspectionBase {
public AndroidLintPackageManagerGetSignaturesInspection() {
super(AndroidBundle.message("android.lint.inspections.package.manager.get.signatures"), GetSignaturesDetector.ISSUE);
}
}
public static class AndroidLintParcelClassLoaderInspection extends AndroidLintInspectionBase {
public AndroidLintParcelClassLoaderInspection() {
super(AndroidBundle.message("android.lint.inspections.parcel.class.loader"), ReadParcelableDetector.ISSUE);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull final PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
String replace = "null)";
if (endElement.getPrevSibling() instanceof PsiJavaToken
&& ((PsiJavaToken)endElement.getPrevSibling()).getTokenType() == JavaTokenType.LPARENTH) {
replace = ")";
}
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Use getClass().getClassLoader()", replace, "getClass().getClassLoader())")};
}
}
public static class AndroidLintParcelCreatorInspection extends AndroidLintInspectionBase {
public AndroidLintParcelCreatorInspection() {
super(AndroidBundle.message("android.lint.inspections.parcel.creator"), ParcelDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{
new ParcelableQuickFix(AndroidBundle.message("implement.parcelable.intention.text"), ParcelableQuickFix.Operation.IMPLEMENT),
};
}
}
public static class AndroidLintPluralsCandidateInspection extends AndroidLintInspectionBase {
public AndroidLintPluralsCandidateInspection() {
super(AndroidBundle.message("android.lint.inspections.plurals.candidate"), StringFormatDetector.POTENTIAL_PLURAL);
}
}
public static class AndroidLintPrivateResourceInspection extends AndroidLintInspectionBase {
public AndroidLintPrivateResourceInspection() {
super(AndroidBundle.message("android.lint.inspections.private.resource"), PrivateResourceDetector.ISSUE);
}
}
public static class AndroidLintSdCardPathInspection extends AndroidLintInspectionBase {
public AndroidLintSdCardPathInspection() {
super(AndroidBundle.message("android.lint.inspections.sd.card.path"), SdCardDetector.ISSUE);
}
}
public static class AndroidLintTextViewEditsInspection extends AndroidLintInspectionBase {
public AndroidLintTextViewEditsInspection() {
super(AndroidBundle.message("android.lint.inspections.text.view.edits"), TextViewDetector.ISSUE);
}
}
public static class AndroidLintEnforceUTF8Inspection extends AndroidLintInspectionBase {
public AndroidLintEnforceUTF8Inspection() {
super(AndroidBundle.message("android.lint.inspections.enforce.utf8"), Utf8Detector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, null, "utf-8") };
}
}
public static class AndroidLintUnknownIdInLayoutInspection extends AndroidLintInspectionBase {
public AndroidLintUnknownIdInLayoutInspection() {
super(AndroidBundle.message("android.lint.inspections.unknown.id.in.layout"), WrongIdDetector.UNKNOWN_ID_LAYOUT);
}
}
public static class AndroidLintSuspiciousImportInspection extends AndroidLintInspectionBase {
public AndroidLintSuspiciousImportInspection() {
super(AndroidBundle.message("android.lint.inspections.suspicious.import"), WrongImportDetector.ISSUE);
}
}
public static class AndroidLintAccidentalOctalInspection extends AndroidLintInspectionBase {
public AndroidLintAccidentalOctalInspection() {
super(AndroidBundle.message("android.lint.inspections.accidental.octal"), GradleDetector.ACCIDENTAL_OCTAL);
}
}
public static class AndroidLintAdapterViewChildrenInspection extends AndroidLintInspectionBase {
public AndroidLintAdapterViewChildrenInspection() {
super(AndroidBundle.message("android.lint.inspections.adapter.view.children"), ChildCountDetector.ADAPTER_VIEW_ISSUE);
}
}
public static class AndroidLintSQLiteStringInspection extends AndroidLintInspectionBase {
public AndroidLintSQLiteStringInspection() {
super(AndroidBundle.message("android.lint.inspections.sqlite.string"), SQLiteDetector.ISSUE);
}
}
public static class AndroidLintScrollViewCountInspection extends AndroidLintInspectionBase {
public AndroidLintScrollViewCountInspection() {
super(AndroidBundle.message("android.lint.inspections.scroll.view.count"), ChildCountDetector.SCROLLVIEW_ISSUE);
}
}
public static class AndroidLintMissingPrefixInspection extends AndroidLintInspectionBase {
public AndroidLintMissingPrefixInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.prefix"), DetectMissingPrefix.MISSING_NAMESPACE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new AddMissingPrefixQuickFix()};
}
}
public static class AndroidLintMissingQuantityInspection extends AndroidLintInspectionBase {
public AndroidLintMissingQuantityInspection() {
// TODO: Add fixes
super(AndroidBundle.message("android.lint.inspections.missing.quantity"), PluralsDetector.MISSING);
}
}
public static class AndroidLintUnusedQuantityInspection extends AndroidLintInspectionBase {
public AndroidLintUnusedQuantityInspection() {
// TODO: Add fixes
super(AndroidBundle.message("android.lint.inspections.unused.quantity"), PluralsDetector.EXTRA);
}
}
public static class AndroidLintDuplicateIdsInspection extends AndroidLintInspectionBase {
public AndroidLintDuplicateIdsInspection() {
super(AndroidBundle.message("android.lint.inspections.duplicate.ids"), DuplicateIdDetector.WITHIN_LAYOUT);
}
}
public static class AndroidLintGridLayoutInspection extends AndroidLintInspectionBase {
public AndroidLintGridLayoutInspection() {
super(AndroidBundle.message("android.lint.inspections.grid.layout"), GridLayoutDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull final PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
String obsolete = GridLayoutDetector.getOldValue(message, RAW);
String available = GridLayoutDetector.getNewValue(message, RAW);
if (obsolete != null && available != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Update to " + available, obsolete, available) {
@Override
protected void editBefore(@NotNull Document document) {
Project project = startElement.getProject();
final XmlFile file = PsiTreeUtil.getParentOfType(startElement, XmlFile.class);
if (file != null) {
AndroidResourceUtil.ensureNamespaceImported(file, AUTO_URI, null);
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
}
}
}};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintHardcodedTextInspection extends AndroidLintInspectionBase {
public AndroidLintHardcodedTextInspection() {
super(AndroidBundle.message("android.lint.inspections.hardcoded.text"), HardcodedValuesDetector.ISSUE);
}
@NotNull
@Override
public IntentionAction[] getIntentions(@NotNull final PsiElement startElement, @NotNull PsiElement endElement) {
return new IntentionAction[]{new AndroidAddStringResourceQuickFix(startElement)};
}
}
public static class AndroidLintInefficientWeightInspection extends AndroidLintInspectionBase {
public AndroidLintInefficientWeightInspection() {
super(AndroidBundle.message("android.lint.inspections.inefficient.weight"), InefficientWeightDetector.INEFFICIENT_WEIGHT);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{
new InefficientWeightQuickFix()
};
}
}
public static class AndroidLintNestedWeightsInspection extends AndroidLintInspectionBase {
public AndroidLintNestedWeightsInspection() {
super(AndroidBundle.message("android.lint.inspections.nested.weights"), InefficientWeightDetector.NESTED_WEIGHTS);
}
}
public static class AndroidLintDefaultLocaleInspection extends AndroidLintInspectionBase {
public AndroidLintDefaultLocaleInspection() {
super(AndroidBundle.message("android.lint.inspections.default.locale"), LocaleDetector.STRING_LOCALE);
}
}
public static class AndroidLintDeprecatedInspection extends AndroidLintInspectionBase {
public AndroidLintDeprecatedInspection() {
super(AndroidBundle.message("android.lint.inspections.deprecated"), DeprecationDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return new AndroidLintQuickFix[]{
new SingleLineTrueQuickFix(),
new RemoveAttributeQuickFix()
};
}
}
public static class AndroidLintDeviceAdminInspection extends AndroidLintInspectionBase {
public AndroidLintDeviceAdminInspection() {
// TODO: Add quickfix
super(AndroidBundle.message("android.lint.inspections.device.admin"), ManifestDetector.DEVICE_ADMIN);
}
}
public static class AndroidLintDisableBaselineAlignmentInspection extends AndroidLintInspectionBase {
public AndroidLintDisableBaselineAlignmentInspection() {
super(AndroidBundle.message("android.lint.inspections.disable.baseline.alignment"), InefficientWeightDetector.BASELINE_WEIGHTS);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{
new SetAttributeQuickFix(AndroidBundle.message("android.lint.fix.set.baseline.attribute"),
SdkConstants.ATTR_BASELINE_ALIGNED, VALUE_FALSE)
};
}
}
public static class AndroidLintManifestOrderInspection extends AndroidLintInspectionBase {
public AndroidLintManifestOrderInspection() {
super(AndroidBundle.message("android.lint.inspections.manifest.order"), ManifestDetector.ORDER);
}
}
public static class AndroidLintMockLocationInspection extends AndroidLintInspectionBase {
public AndroidLintMockLocationInspection() {
super(AndroidBundle.message("android.lint.inspections.mock.location"), ManifestDetector.MOCK_LOCATION);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new MoveToDebugManifestQuickFix()};
}
}
public static class AndroidLintMultipleUsesSdkInspection extends AndroidLintInspectionBase {
public AndroidLintMultipleUsesSdkInspection() {
super(AndroidBundle.message("android.lint.inspections.multiple.uses.sdk"), ManifestDetector.MULTIPLE_USES_SDK);
}
}
public static class AndroidLintUsesMinSdkAttributesInspection extends AndroidLintInspectionBase {
public AndroidLintUsesMinSdkAttributesInspection() {
super(AndroidBundle.message("android.lint.inspections.uses.min.sdk.attributes"), ManifestDetector.USES_SDK);
}
}
public static class AndroidLintUsingHttpInspection extends AndroidLintInspectionBase {
public AndroidLintUsingHttpInspection() {
super(AndroidBundle.message("android.lint.inspections.using.http"), PropertyFileDetector.HTTP);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String escaped = PropertyFileDetector.getSuggestedEscape(message, RAW);
if (escaped != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, null, escaped)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintValidFragmentInspection extends AndroidLintInspectionBase {
public AndroidLintValidFragmentInspection() {
super(AndroidBundle.message("android.lint.inspections.valid.fragment"), ISSUE);
}
}
public static class AndroidLintValidRestrictionsInspection extends AndroidLintInspectionBase {
public AndroidLintValidRestrictionsInspection() {
super(AndroidBundle.message("android.lint.inspections.valid.restrictions"), RestrictionsDetector.ISSUE);
}
}
public static class AndroidLintVectorDrawableCompatInspection extends AndroidLintInspectionBase {
public AndroidLintVectorDrawableCompatInspection() {
super(AndroidBundle.message("android.lint.inspections.vector.drawable.compat"), VectorDrawableCompatDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
XmlAttribute attribute = PsiTreeUtil.getParentOfType(startElement, XmlAttribute.class, false);
if (attribute != null && ATTR_SRC.equals(attribute.getLocalName())) {
return new AndroidLintQuickFix[] {new RenameAttributeQuickFix(AUTO_URI, ATTR_SRC_COMPAT)};
} else {
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
}
public static class AndroidLintVectorRasterInspection extends AndroidLintInspectionBase {
public AndroidLintVectorRasterInspection() {
super(AndroidBundle.message("android.lint.inspections.vector.raster"), VectorDetector.ISSUE);
}
}
public static class AndroidLintViewConstructorInspection extends AndroidLintInspectionBase {
public AndroidLintViewConstructorInspection() {
super(AndroidBundle.message("android.lint.inspections.view.constructor"), ViewConstructorDetector.ISSUE);
}
}
public static class AndroidLintViewHolderInspection extends AndroidLintInspectionBase {
public AndroidLintViewHolderInspection() {
super(AndroidBundle.message("android.lint.inspections.view.holder"), ViewHolderDetector.ISSUE);
}
}
public static class AndroidLintViewTagInspection extends AndroidLintInspectionBase {
public AndroidLintViewTagInspection() {
super(AndroidBundle.message("android.lint.inspections.view.tag"), ViewTagDetector.ISSUE);
}
}
public static class AndroidLintWebViewLayoutInspection extends AndroidLintInspectionBase {
public AndroidLintWebViewLayoutInspection() {
super(AndroidBundle.message("android.lint.inspections.web.view.layout"), WebViewDetector.ISSUE);
}
}
public static class AndroidLintWearableBindListenerInspection extends AndroidLintInspectionBase {
public AndroidLintWearableBindListenerInspection() {
super(AndroidBundle.message("android.lint.inspections.wearable.bind.listener"), ManifestDetector.WEARABLE_BIND_LISTENER);
}
}
public static class AndroidLintMergeRootFrameInspection extends AndroidLintInspectionBase {
public AndroidLintMergeRootFrameInspection() {
super(AndroidBundle.message("android.lint.inspections.merge.root.frame"), MergeRootFrameLayoutDetector.ISSUE);
}
}
public static class AndroidLintNegativeMarginInspection extends AndroidLintInspectionBase {
public AndroidLintNegativeMarginInspection() {
super(AndroidBundle.message("android.lint.inspections.negative.margin"), NegativeMarginDetector.ISSUE);
}
}
public static class AndroidLintNestedScrollingInspection extends AndroidLintInspectionBase {
public AndroidLintNestedScrollingInspection() {
super(AndroidBundle.message("android.lint.inspections.nested.scrolling"), NestedScrollingWidgetDetector.ISSUE);
}
}
public static class AndroidLintNewerVersionAvailableInspection extends AndroidLintInspectionBase {
public AndroidLintNewerVersionAvailableInspection() {
super(AndroidBundle.message("android.lint.inspections.newer.version.available"), GradleDetector.REMOTE_VERSION);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String obsolete = GradleDetector.getOldValue(GradleDetector.DEPENDENCY, message, RAW);
String available = GradleDetector.getNewValue(GradleDetector.DEPENDENCY, message, RAW);
if (obsolete != null && available != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Update to " + available, obsolete, available)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintNfcTechWhitespaceInspection extends AndroidLintInspectionBase {
public AndroidLintNfcTechWhitespaceInspection() {
super(AndroidBundle.message("android.lint.inspections.nfc.tech.whitespace"), NfcTechListDetector.ISSUE);
}
}
public static class AndroidLintNotInterpolatedInspection extends AndroidLintInspectionBase {
public AndroidLintNotInterpolatedInspection() {
super(AndroidBundle.message("android.lint.inspections.not.interpolated"), GradleDetector.NOT_INTERPOLATED);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
String s = endElement.getText();
if (s.startsWith("'") && s.endsWith("'") && s.length() > 2) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Replace single quotes with double quotes", s,
"\"" + s.substring(1, s.length() - 1) + "\"")};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintNotSiblingInspection extends AndroidLintInspectionBase {
public AndroidLintNotSiblingInspection() {
super(AndroidBundle.message("android.lint.inspections.not.sibling"), WrongIdDetector.NOT_SIBLING);
}
}
public static class AndroidLintObsoleteLayoutParamInspection extends AndroidLintInspectionBase {
public AndroidLintObsoleteLayoutParamInspection() {
super(AndroidBundle.message("android.lint.inspections.obsolete.layout.param"), ObsoleteLayoutParamsDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new RemoveAttributeQuickFix()};
}
}
public static class AndroidLintProguardInspection extends AndroidLintInspectionBase {
public AndroidLintProguardInspection() {
super(AndroidBundle.message("android.lint.inspections.proguard"), ProguardDetector.WRONG_KEEP);
}
}
public static class AndroidLintProguardSplitInspection extends AndroidLintInspectionBase {
public AndroidLintProguardSplitInspection() {
super(AndroidBundle.message("android.lint.inspections.proguard.split"), ProguardDetector.SPLIT_CONFIG);
}
}
public static class AndroidLintPxUsageInspection extends AndroidLintInspectionBase {
public AndroidLintPxUsageInspection() {
super(AndroidBundle.message("android.lint.inspections.px.usage"), PxUsageDetector.PX_ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new ConvertToDpQuickFix()};
}
}
public static class AndroidLintScrollViewSizeInspection extends AndroidLintInspectionBase {
public AndroidLintScrollViewSizeInspection() {
super(AndroidBundle.message("android.lint.inspections.scroll.view.size"), ScrollViewChildDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new SetScrollViewSizeQuickFix()};
}
}
public static class AndroidLintExportedServiceInspection extends AndroidLintInspectionBase {
public AndroidLintExportedServiceInspection() {
super(AndroidBundle.message("android.lint.inspections.exported.service"), SecurityDetector.EXPORTED_SERVICE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{
new SetAttributeQuickFix(AndroidBundle.message("android.lint.fix.add.permission.attribute"),
SdkConstants.ATTR_PERMISSION, null)
};
}
}
public static class AndroidLintGradleCompatibleInspection extends AndroidLintInspectionBase {
public AndroidLintGradleCompatibleInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.compatible"), GradleDetector.COMPATIBILITY);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String before = GradleDetector.getOldValue(GradleDetector.COMPATIBILITY, message, RAW);
String after = GradleDetector.getNewValue(GradleDetector.COMPATIBILITY, message, RAW);
if (before != null && after != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Change to " + after, before, after)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintGradleDependencyInspection extends AndroidLintInspectionBase {
public AndroidLintGradleDependencyInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.dependency"), GradleDetector.DEPENDENCY);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String before = GradleDetector.getOldValue(GradleDetector.DEPENDENCY, message, RAW);
String after = GradleDetector.getNewValue(GradleDetector.DEPENDENCY, message, RAW);
if (before != null && after != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Change to " + after, before, after)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintGradleDeprecatedInspection extends AndroidLintInspectionBase {
public AndroidLintGradleDeprecatedInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.deprecated"), GradleDetector.DEPRECATED);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull final String message) {
String before = GradleDetector.getOldValue(GradleDetector.DEPRECATED, message, RAW);
String after = GradleDetector.getNewValue(GradleDetector.DEPRECATED, message, RAW);
if (before != null && after != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, before, after)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintGradleDynamicVersionInspection extends AndroidLintInspectionBase {
public AndroidLintGradleDynamicVersionInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.dynamic.version"), GradleDetector.PLUS);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull final PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
String before = GradleDetector.getOldValue(GradleDetector.PLUS, message, RAW);
if (before != null && before.contains("+")) {
final GradleCoordinate plus = GradleCoordinate.parseCoordinateString(before);
if (plus != null && plus.getArtifactId() != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Replace with specific version", plus.getRevision(), "specific version") {
@Nullable
@Override
protected String getNewValue() {
return RepositoryUrlManager.get().resolveDynamicCoordinateVersion(plus, startElement.getProject());
}
}};
}
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintGradleGetterInspection extends AndroidLintInspectionBase {
public AndroidLintGradleGetterInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.getter"), GradleDetector.GRADLE_GETTER);
}
}
public static class AndroidLintGradleIdeErrorInspection extends AndroidLintInspectionBase {
public AndroidLintGradleIdeErrorInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.ide.error"), GradleDetector.IDE_SUPPORT);
}
}
public static class AndroidLintGradleOverridesInspection extends AndroidLintInspectionBase {
public AndroidLintGradleOverridesInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.overrides"), ManifestDetector.GRADLE_OVERRIDES);
}
}
public static class AndroidLintGradlePathInspection extends AndroidLintInspectionBase {
public AndroidLintGradlePathInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.path"), GradleDetector.PATH);
}
}
public static class AndroidLintGradlePluginVersionInspection extends AndroidLintInspectionBase {
public AndroidLintGradlePluginVersionInspection() {
super(AndroidBundle.message("android.lint.inspections.gradle.plugin.version"), GradleDetector.GRADLE_PLUGIN_COMPATIBILITY);
}
}
public static class AndroidLintGrantAllUrisInspection extends AndroidLintInspectionBase {
public AndroidLintGrantAllUrisInspection() {
super(AndroidBundle.message("android.lint.inspections.grant.all.uris"), SecurityDetector.OPEN_PROVIDER);
}
}
public static class AndroidLintWorldWriteableFilesInspection extends AndroidLintInspectionBase {
public AndroidLintWorldWriteableFilesInspection() {
super(AndroidBundle.message("android.lint.inspections.world.writeable.files"), SecurityDetector.WORLD_WRITEABLE);
}
}
public static class AndroidLintSSLCertificateSocketFactoryCreateSocketInspection extends AndroidLintInspectionBase {
public AndroidLintSSLCertificateSocketFactoryCreateSocketInspection() {
super(AndroidBundle.message("android.lint.inspections.sslcertificate.socket.factory.create.socket"), SslCertificateSocketFactoryDetector.CREATE_SOCKET);
}
}
public static class AndroidLintSSLCertificateSocketFactoryGetInsecureInspection extends AndroidLintInspectionBase {
public AndroidLintSSLCertificateSocketFactoryGetInsecureInspection() {
super(AndroidBundle.message("android.lint.inspections.sslcertificate.socket.factory.get.insecure"), SslCertificateSocketFactoryDetector.GET_INSECURE);
}
}
public static class AndroidLintStateListReachableInspection extends AndroidLintInspectionBase {
public AndroidLintStateListReachableInspection() {
super(AndroidBundle.message("android.lint.inspections.state.list.reachable"), StateListDetector.ISSUE);
}
}
public static class AndroidLintSwitchIntDefInspection extends AndroidLintInspectionBase {
public AndroidLintSwitchIntDefInspection() {
super(AndroidBundle.message("android.lint.inspections.switch.int.def"), AnnotationDetector.SWITCH_TYPE_DEF);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
final List<String> missingCases = AnnotationDetector.getMissingCases(message, RAW);
if (missingCases != null && !missingCases.isEmpty()) {
return new AndroidLintQuickFix[]{new AndroidLintQuickFix() {
@Override
public void apply(@NotNull PsiElement startElement,
@NotNull PsiElement endElement,
@NotNull AndroidQuickfixContexts.Context context) {
if (startElement.getParent() instanceof PsiSwitchStatement) {
PsiSwitchStatement switchStatement = (PsiSwitchStatement)startElement.getParent();
Project project = switchStatement.getProject();
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
PsiCodeBlock body = switchStatement.getBody();
if (body == null) {
return;
}
PsiElement anchor = body.getLastChild();
for (String constant : missingCases) {
PsiElement parent = anchor.getParent();
PsiStatement caseStatement = factory.createStatementFromText("case " + constant + ":", anchor);
parent.addBefore(caseStatement, anchor);
PsiStatement breakStatement = factory.createStatementFromText("break;", anchor);
parent.addBefore(breakStatement, anchor);
}
CodeStyleManager.getInstance(project).reformat(switchStatement);
}
}
@Override
public boolean isApplicable(@NotNull PsiElement startElement,
@NotNull PsiElement endElement,
@NotNull AndroidQuickfixContexts.ContextType contextType) {
return startElement.isValid();
}
@NotNull
@Override
public String getName() {
return "Add Missing @IntDef Constants";
}
}};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintTextFieldsInspection extends AndroidLintInspectionBase {
public AndroidLintTextFieldsInspection() {
super(AndroidBundle.message("android.lint.inspections.text.fields"), TextFieldDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{
new SetAttributeQuickFix(AndroidBundle.message("android.lint.fix.add.input.type.attribute"),
SdkConstants.ATTR_INPUT_TYPE, null)
};
}
}
public static class AndroidLintTooManyViewsInspection extends AndroidLintInspectionBase {
public AndroidLintTooManyViewsInspection() {
super(AndroidBundle.message("android.lint.inspections.too.many.views"), TooManyViewsDetector.TOO_MANY);
}
}
public static class AndroidLintTooDeepLayoutInspection extends AndroidLintInspectionBase {
public AndroidLintTooDeepLayoutInspection() {
super(AndroidBundle.message("android.lint.inspections.too.deep.layout"), TooManyViewsDetector.TOO_DEEP);
}
}
public static class AndroidLintTrustAllX509TrustManagerInspection extends AndroidLintInspectionBase {
public AndroidLintTrustAllX509TrustManagerInspection() {
super(AndroidBundle.message("android.lint.inspections.trust.all.x509.trust.manager"), TrustAllX509TrustManagerDetector.ISSUE);
}
}
public static class AndroidLintTypographyDashesInspection extends AndroidLintTypographyInspectionBase {
public AndroidLintTypographyDashesInspection() {
super(AndroidBundle.message("android.lint.inspections.typography.dashes"), TypographyDetector.DASHES);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {new TypographyQuickFix(myIssue, message)};
}
}
public static class AndroidLintTypographyQuotesInspection extends AndroidLintTypographyInspectionBase {
public AndroidLintTypographyQuotesInspection() {
super(AndroidBundle.message("android.lint.inspections.typography.quotes"), TypographyDetector.QUOTES);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {new TypographyQuickFix(myIssue, message)};
}
}
public static class AndroidLintTypographyFractionsInspection extends AndroidLintTypographyInspectionBase {
public AndroidLintTypographyFractionsInspection() {
super(AndroidBundle.message("android.lint.inspections.typography.fractions"), TypographyDetector.FRACTIONS);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {new TypographyQuickFix(myIssue, message)};
}
}
public static class AndroidLintTypographyEllipsisInspection extends AndroidLintTypographyInspectionBase {
public AndroidLintTypographyEllipsisInspection() {
super(AndroidBundle.message("android.lint.inspections.typography.ellipsis"), TypographyDetector.ELLIPSIS);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {new TypographyQuickFix(myIssue, message)};
}
}
public static class AndroidLintTypographyOtherInspection extends AndroidLintTypographyInspectionBase {
public AndroidLintTypographyOtherInspection() {
super(AndroidBundle.message("android.lint.inspections.typography.other"), TypographyDetector.OTHER);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {new TypographyQuickFix(myIssue, message)};
}
}
public static class AndroidLintUseAlpha2Inspection extends AndroidLintInspectionBase {
public AndroidLintUseAlpha2Inspection() {
super(AndroidBundle.message("android.lint.inspections.use.alpha2"), LocaleFolderDetector.USE_ALPHA_2);
}
}
public static class AndroidLintUseCompoundDrawablesInspection extends AndroidLintInspectionBase {
public AndroidLintUseCompoundDrawablesInspection() {
super(AndroidBundle.message("android.lint.inspections.use.compound.drawables"), UseCompoundDrawableDetector.ISSUE);
}
// TODO: implement quickfix
}
public static class AndroidLintUselessParentInspection extends AndroidLintInspectionBase {
public AndroidLintUselessParentInspection() {
super(AndroidBundle.message("android.lint.inspections.useless.parent"), UselessViewDetector.USELESS_PARENT);
}
// TODO: implement quickfix
}
public static class AndroidLintUselessLeafInspection extends AndroidLintInspectionBase {
public AndroidLintUselessLeafInspection() {
super(AndroidBundle.message("android.lint.inspections.useless.leaf"), UselessViewDetector.USELESS_LEAF);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new RemoveUselessViewQuickFix(myIssue)};
}
}
private abstract static class AndroidLintTypographyInspectionBase extends AndroidLintInspectionBase {
public AndroidLintTypographyInspectionBase(String displayName, Issue issue) {
super(displayName, issue);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {new TypographyQuickFix(myIssue, message)};
}
}
public static class AndroidLintNewApiInspection extends AndroidLintInspectionBase {
public AndroidLintNewApiInspection() {
super(AndroidBundle.message("android.lint.inspections.new.api"), ApiDetector.UNSUPPORTED);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return getApiDetectorFixes(ApiDetector.UNSUPPORTED, startElement, endElement, message);
}
}
public static class AndroidLintInlinedApiInspection extends AndroidLintInspectionBase {
public AndroidLintInlinedApiInspection() {
super(AndroidBundle.message("android.lint.inspections.inlined.api"), ApiDetector.INLINED);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return getApiDetectorFixes(ApiDetector.INLINED, startElement, endElement, message);
}
}
private static AndroidLintQuickFix[] getApiDetectorFixes(@NotNull Issue issue,
@NotNull PsiElement startElement,
@SuppressWarnings("UnusedParameters") @NotNull PsiElement endElement,
@NotNull String message) {
// TODO: Return one for each parent context (declaration, method, class, outer class(es)
int api = ApiDetector.getRequiredVersion(issue, message, RAW);
if (api != -1) {
List<AndroidLintQuickFix> list = Lists.newArrayList();
PsiFile file = startElement.getContainingFile();
boolean isXml = false;
if (file instanceof XmlFile) {
isXml = true;
ResourceFolderType folderType = ResourceHelper.getFolderType(file);
if (folderType != null) {
FolderConfiguration config = ResourceHelper.getFolderConfiguration(file);
if (config != null) {
config.setVersionQualifier(new VersionQualifier(api));
String folder = config.getFolderName(folderType);
list.add(OverrideResourceAction.createFix(folder));
}
}
}
list.add(new AddTargetVersionCheckQuickFix(api));
list.add(new AddTargetApiQuickFix(api, false, startElement));
ApplicationManager.getApplication().assertReadAccessAllowed();
if (!isXml && JavaPsiFacade.getInstance(startElement.getProject()).findClass(REQUIRES_API_ANNOTATION,
GlobalSearchScope.allScope(startElement.getProject())) != null) {
list.add(new AddTargetApiQuickFix(api, true, startElement));
}
return list.toArray(new AndroidLintQuickFix[list.size()]);
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
public static class AndroidLintOverrideInspection extends AndroidLintInspectionBase {
public AndroidLintOverrideInspection() {
super(AndroidBundle.message("android.lint.inspections.override"), ApiDetector.OVERRIDE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return getApiDetectorFixes(ApiDetector.INLINED, startElement, endElement, message);
}
}
public static class AndroidLintDuplicateUsesFeatureInspection extends AndroidLintInspectionBase {
public AndroidLintDuplicateUsesFeatureInspection() {
super(AndroidBundle.message("android.lint.inspections.duplicate.uses.feature"), ManifestDetector.DUPLICATE_USES_FEATURE);
}
}
public static class AndroidLintMipmapIconsInspection extends AndroidLintInspectionBase {
public AndroidLintMipmapIconsInspection() {
super(AndroidBundle.message("android.lint.inspections.mipmap.icons"), ManifestDetector.MIPMAP);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
PsiElement parent = startElement.getParent();
if (parent instanceof XmlAttribute) {
XmlAttribute attribute = (XmlAttribute)parent;
String value = attribute.getValue();
if (value != null) {
ResourceUrl url = ResourceUrl.parse(value);
if (url != null && !url.framework) {
return new AndroidLintQuickFix[]{new MigrateDrawableToMipmapFix(url)};
}
}
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintMissingApplicationIconInspection extends AndroidLintInspectionBase {
public AndroidLintMissingApplicationIconInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.application.icon"), ManifestDetector.APPLICATION_ICON);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return new AndroidLintQuickFix[] { new SetAttributeQuickFix("Set application icon", ATTR_ICON, null) };
}
}
public static class AndroidLintResourceCycleInspection extends AndroidLintInspectionBase {
public AndroidLintResourceCycleInspection() {
super(AndroidBundle.message("android.lint.inspections.resource.cycle"), ResourceCycleDetector.CYCLE);
}
}
public static class AndroidLintResourceNameInspection extends AndroidLintInspectionBase {
public AndroidLintResourceNameInspection() {
super(AndroidBundle.message("android.lint.inspections.resource.name"), ResourcePrefixDetector.ISSUE);
}
}
private static final Pattern QUOTED_PARAMETER = Pattern.compile("`.+:(.+)=\"(.*)\"`");
public static class AndroidLintRtlCompatInspection extends AndroidLintInspectionBase {
public AndroidLintRtlCompatInspection() {
super(AndroidBundle.message("android.lint.inspections.rtl.compat"), RtlDetector.COMPAT);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
if (message.startsWith("To support older versions than API 17")) {
Matcher matcher = QUOTED_PARAMETER.matcher(message);
if (matcher.find()) {
final String name = matcher.group(1);
final String value = matcher.group(2);
return new AndroidLintQuickFix[]{new SetAttributeQuickFix(String.format("Set %s", name), name, value)};
}
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintRtlEnabledInspection extends AndroidLintInspectionBase {
public AndroidLintRtlEnabledInspection() {
super(AndroidBundle.message("android.lint.inspections.rtl.enabled"), RtlDetector.ENABLED);
}
}
public static class AndroidLintRtlHardcodedInspection extends AndroidLintInspectionBase {
public AndroidLintRtlHardcodedInspection() {
super(AndroidBundle.message("android.lint.inspections.rtl.hardcoded"), RtlDetector.USE_START);
}
}
public static class AndroidLintRtlSymmetryInspection extends AndroidLintInspectionBase {
public AndroidLintRtlSymmetryInspection() {
super(AndroidBundle.message("android.lint.inspections.rtl.symmetry"), RtlDetector.SYMMETRY);
}
}
// Missing the following issues, because they require classfile analysis:
// FloatMath, FieldGetter, Override, OnClick, ViewTag, DefaultLocale, SimpleDateFormat,
// Registered, MissingRegistered, Instantiatable, HandlerLeak, ValidFragment, SecureRandom,
// ViewConstructor, Wakelock, Recycle, CommitTransaction, WrongCall, DalvikOverride
// I think DefaultLocale is already handled by a regular IDEA code check.
public static class AndroidLintAddJavascriptInterfaceInspection extends AndroidLintInspectionBase {
public AndroidLintAddJavascriptInterfaceInspection() {
super(AndroidBundle.message("android.lint.inspections.add.javascript.interface"), AddJavascriptInterfaceDetector.ISSUE);
}
}
public static class AndroidLintAllowAllHostnameVerifierInspection extends AndroidLintInspectionBase {
public AndroidLintAllowAllHostnameVerifierInspection() {
super(AndroidBundle.message("android.lint.inspections.allow.all.hostname.verifier"), AllowAllHostnameVerifierDetector.ISSUE);
}
}
public static class AndroidLintAllowBackupInspection extends AndroidLintInspectionBase {
public AndroidLintAllowBackupInspection() {
super(AndroidBundle.message("android.lint.inspections.allow.backup"), ManifestDetector.ALLOW_BACKUP);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return new AndroidLintQuickFix[] { new SetAttributeQuickFix("Set backup attribute", ATTR_ALLOW_BACKUP, null) };
}
}
public static class AndroidLintButtonStyleInspection extends AndroidLintInspectionBase {
public AndroidLintButtonStyleInspection() {
super(AndroidBundle.message("android.lint.inspections.button.style"), ButtonDetector.STYLE);
}
}
public static class AndroidLintByteOrderMarkInspection extends AndroidLintInspectionBase {
public AndroidLintByteOrderMarkInspection() {
super(AndroidBundle.message("android.lint.inspections.byte.order.mark"), ByteOrderMarkDetector.BOM);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return new AndroidLintQuickFix[] {
new DefaultLintQuickFix("Remove byte order marks") {
@Override
public void apply(@NotNull PsiElement startElement,
@NotNull PsiElement endElement,
@NotNull AndroidQuickfixContexts.Context context) {
Document document = FileDocumentManager.getInstance().getDocument(startElement.getContainingFile().getVirtualFile());
if (document != null) {
String text = document.getText();
for (int i = text.length() - 1; i >= 0; i--) {
char c = text.charAt(i);
if (c == '\uFEFF') {
document.deleteString(i, i + 1);
}
}
}
}
}
};
}
}
public static class AndroidLintCommitPrefEditsInspection extends AndroidLintInspectionBase {
public AndroidLintCommitPrefEditsInspection() {
super(AndroidBundle.message("android.lint.inspections.commit.pref.edits"), CleanupDetector.SHARED_PREF);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
if (message.contains("commit") && message.contains("apply")) {
return new AndroidLintQuickFix[] { new ReplaceStringQuickFix("Replace commit() with apply()", "(commit)\\s*\\(", "apply") };
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintCustomViewStyleableInspection extends AndroidLintInspectionBase {
public AndroidLintCustomViewStyleableInspection() {
super(AndroidBundle.message("android.lint.inspections.custom.view.styleable"), CustomViewDetector.ISSUE);
}
}
public static class AndroidLintCutPasteIdInspection extends AndroidLintInspectionBase {
public AndroidLintCutPasteIdInspection() {
super(AndroidBundle.message("android.lint.inspections.cut.paste.id"), CutPasteDetector.ISSUE);
}
}
public static class AndroidLintDuplicateActivityInspection extends AndroidLintInspectionBase {
public AndroidLintDuplicateActivityInspection() {
super(AndroidBundle.message("android.lint.inspections.duplicate.activity"), ManifestDetector.DUPLICATE_ACTIVITY);
}
}
public static class AndroidLintDuplicateDefinitionInspection extends AndroidLintInspectionBase {
public AndroidLintDuplicateDefinitionInspection() {
super(AndroidBundle.message("android.lint.inspections.duplicate.definition"), DuplicateResourceDetector.ISSUE);
}
}
public static class AndroidLintEasterEggInspection extends AndroidLintInspectionBase {
public AndroidLintEasterEggInspection() {
super(AndroidBundle.message("android.lint.inspections.easter.egg"), CommentDetector.EASTER_EGG);
}
}
public static class AndroidLintExportedContentProviderInspection extends AndroidLintInspectionBase {
public AndroidLintExportedContentProviderInspection() {
super(AndroidBundle.message("android.lint.inspections.exported.content.provider"), SecurityDetector.EXPORTED_PROVIDER);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {
new SetAttributeQuickFix("Set exported=\"false\"", ATTR_EXPORTED, VALUE_FALSE)
};
}
}
public static class AndroidLintExportedPreferenceActivityInspection extends AndroidLintInspectionBase {
public AndroidLintExportedPreferenceActivityInspection() {
super(AndroidBundle.message("android.lint.inspections.exported.preference.activity"), PreferenceActivityDetector.ISSUE);
}
}
public static class AndroidLintExportedReceiverInspection extends AndroidLintInspectionBase {
public AndroidLintExportedReceiverInspection() {
super(AndroidBundle.message("android.lint.inspections.exported.receiver"), SecurityDetector.EXPORTED_RECEIVER);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {
new SetAttributeQuickFix("Set permission attribute", ATTR_PERMISSION, null)
};
}
}
public static class AndroidLintIconColorsInspection extends AndroidLintInspectionBase {
public AndroidLintIconColorsInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.colors"), IconDetector.ICON_COLORS);
}
}
public static class AndroidLintIconExtensionInspection extends AndroidLintInspectionBase {
public AndroidLintIconExtensionInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.extension"), IconDetector.ICON_EXTENSION);
}
}
public static class AndroidLintIconLauncherShapeInspection extends AndroidLintInspectionBase {
public AndroidLintIconLauncherShapeInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.launcher.shape"), IconDetector.ICON_LAUNCHER_SHAPE);
}
}
public static class AndroidLintIconXmlAndPngInspection extends AndroidLintInspectionBase {
public AndroidLintIconXmlAndPngInspection() {
super(AndroidBundle.message("android.lint.inspections.icon.xml.and.png"), IconDetector.ICON_XML_AND_PNG);
}
}
public static class AndroidLintIllegalResourceRefInspection extends AndroidLintInspectionBase {
public AndroidLintIllegalResourceRefInspection() {
super(AndroidBundle.message("android.lint.inspections.illegal.resource.ref"), ManifestDetector.ILLEGAL_REFERENCE);
}
}
public static class AndroidLintImpliedQuantityInspection extends AndroidLintInspectionBase {
public AndroidLintImpliedQuantityInspection() {
super(AndroidBundle.message("android.lint.inspections.implied.quantity"), IMPLIED_QUANTITY);
}
}
public static class AndroidLintAuthLeakInspection extends AndroidLintInspectionBase {
public AndroidLintAuthLeakInspection() {
super(AndroidBundle.message("android.lint.inspections.credential.leak"), StringAuthLeakDetector.AUTH_LEAK);
}
}
public static class AndroidLintIncludeLayoutParamInspection extends AndroidLintInspectionBase {
public AndroidLintIncludeLayoutParamInspection() {
super(AndroidBundle.message("android.lint.inspections.include.layout.param"), IncludeDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
List<AndroidLintQuickFix> fixes = Lists.newArrayListWithExpectedSize(2);
if (IncludeDetector.requestsWidth(message)) {
fixes.add(new SetAttributeQuickFix("Set layout_width", ATTR_LAYOUT_WIDTH, null));
}
if (IncludeDetector.requestsHeight(message)) {
fixes.add(new SetAttributeQuickFix("Set layout_height", ATTR_LAYOUT_HEIGHT, null));
}
return fixes.toArray(new AndroidLintQuickFix[fixes.size()]);
}
}
public static class AndroidLintInflateParamsInspection extends AndroidLintInspectionBase {
public AndroidLintInflateParamsInspection() {
super(AndroidBundle.message("android.lint.inspections.inflate.params"), LayoutInflationDetector.ISSUE);
}
}
public static class AndroidLintInOrMmUsageInspection extends AndroidLintInspectionBase {
public AndroidLintInOrMmUsageInspection() {
super(AndroidBundle.message("android.lint.inspections.in.or.mm.usage"), PxUsageDetector.IN_MM_ISSUE);
}
}
public static class AndroidLintInnerclassSeparatorInspection extends AndroidLintInspectionBase {
public AndroidLintInnerclassSeparatorInspection() {
super(AndroidBundle.message("android.lint.inspections.innerclass.separator"), MissingClassDetector.INNERCLASS);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String current = MissingClassDetector.getOldValue(MissingClassDetector.INNERCLASS, message, RAW);
String proposed = MissingClassDetector.getNewValue(MissingClassDetector.INNERCLASS, message, RAW);
if (proposed != null && current != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, current, proposed)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintInvalidIdInspection extends AndroidLintInspectionBase {
public AndroidLintInvalidIdInspection() {
super(AndroidBundle.message("android.lint.inspections.invalid.id"), WrongIdDetector.INVALID);
}
}
public static class AndroidLintInvalidResourceFolderInspection extends AndroidLintInspectionBase {
public AndroidLintInvalidResourceFolderInspection() {
super(AndroidBundle.message("android.lint.inspections.invalid.resource.folder"), LocaleFolderDetector.INVALID_FOLDER);
}
}
public static class AndroidLintInvalidUsesTagAttributeInspection extends AndroidLintInspectionBase {
public AndroidLintInvalidUsesTagAttributeInspection() {
super(AndroidBundle.message("android.lint.inspections.invalid.uses.tag.attribute"), AndroidAutoDetector.INVALID_USES_TAG_ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
final XmlAttribute attribute = PsiTreeUtil.getParentOfType(startElement, XmlAttribute.class);
XmlAttributeValue attributeValue = attribute == null ? null : attribute.getValueElement();
if (attributeValue != null && attributeValue.getTextLength() != 0) {
String value = StringUtil.unquoteString(attributeValue.getText());
String regexp = "(" + value + ")";
String[] suggestions = AndroidAutoDetector.getAllowedAutomotiveAppTypes();
List<AndroidLintQuickFix> fixes = Lists.newArrayListWithExpectedSize(suggestions.length);
for (String suggestion: suggestions) {
fixes.add(new ReplaceStringQuickFix("Replace with \"" + suggestion + "\"", regexp, suggestion));
}
return fixes.toArray(new AndroidLintQuickFix[fixes.size()]);
} else {
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
}
public static class AndroidLintJavascriptInterfaceInspection extends AndroidLintInspectionBase {
public AndroidLintJavascriptInterfaceInspection() {
super(AndroidBundle.message("android.lint.inspections.javascript.interface"), JavaScriptInterfaceDetector.ISSUE);
}
}
public static class AndroidLintLabelForInspection extends AndroidLintInspectionBase {
public AndroidLintLabelForInspection() {
super(AndroidBundle.message("android.lint.inspections.label.for"), LabelForDetector.ISSUE);
}
}
public static class AndroidLintLocaleFolderInspection extends AndroidLintInspectionBase {
public AndroidLintLocaleFolderInspection() {
super(AndroidBundle.message("android.lint.inspections.locale.folder"), LocaleFolderDetector.DEPRECATED_CODE);
}
}
public static class AndroidLintLocalSuppressInspection extends AndroidLintInspectionBase {
public AndroidLintLocalSuppressInspection() {
super(AndroidBundle.message("android.lint.inspections.local.suppress"), AnnotationDetector.INSIDE_METHOD);
}
}
public static class AndroidLintLogConditionalInspection extends AndroidLintInspectionBase {
public AndroidLintLogConditionalInspection() {
super(AndroidBundle.message("android.lint.inspections.log.conditional"), LogDetector.CONDITIONAL);
}
}
public static class AndroidLintLogTagMismatchInspection extends AndroidLintInspectionBase {
public AndroidLintLogTagMismatchInspection() {
super(AndroidBundle.message("android.lint.inspections.log.tag.mismatch"), LogDetector.WRONG_TAG);
}
}
public static class AndroidLintLongLogTagInspection extends AndroidLintInspectionBase {
public AndroidLintLongLogTagInspection() {
super(AndroidBundle.message("android.lint.inspections.long.log.tag"), LogDetector.LONG_TAG);
}
}
// THIS ISSUE IS PROBABLY NOT NEEDED HERE!
public static class AndroidLintMangledCRLFInspection extends AndroidLintInspectionBase {
public AndroidLintMangledCRLFInspection() {
super(AndroidBundle.message("android.lint.inspections.mangled.crlf"), DosLineEndingDetector.ISSUE);
}
}
public static class AndroidLintManifestResourceInspection extends AndroidLintInspectionBase {
public AndroidLintManifestResourceInspection() {
super(AndroidBundle.message("android.lint.inspections.manifest.resource"), ManifestResourceDetector.ISSUE);
}
}
public static class AndroidLintMenuTitleInspection extends AndroidLintInspectionBase {
public AndroidLintMenuTitleInspection() {
super(AndroidBundle.message("android.lint.inspections.menu.title"), TitleDetector.ISSUE);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] { new SetAttributeQuickFix("Set title", ATTR_TITLE, null) };
}
}
public static class AndroidLintMissingConstraintsInspection extends AndroidLintInspectionBase {
public AndroidLintMissingConstraintsInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.constraints"), ConstraintLayoutDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
if (ConstraintLayoutDetector.isUpgradeDependencyError(message, RAW)) {
return new AndroidLintQuickFix[]{new UpgradeConstraintLayoutFix()};
}
else {
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
}
public static class AndroidLintMissingIdInspection extends AndroidLintInspectionBase {
public AndroidLintMissingIdInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.id"), MissingIdDetector.ISSUE);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] { new SetAttributeQuickFix("Set id", ATTR_ID, null) };
}
}
public static class AndroidLintMissingIntentFilterForMediaSearchInspection extends AndroidLintInspectionBase {
public AndroidLintMissingIntentFilterForMediaSearchInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.intent.filter.for.media.search"),
AndroidAutoDetector.MISSING_INTENT_FILTER_FOR_MEDIA_SEARCH);
}
}
public static class AndroidLintMissingMediaBrowserServiceIntentFilterInspection extends AndroidLintInspectionBase {
public AndroidLintMissingMediaBrowserServiceIntentFilterInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.media.browser.service.intent.filter"),
AndroidAutoDetector.MISSING_MEDIA_BROWSER_SERVICE_ACTION_ISSUE);
}
}
public static class AndroidLintMissingOnPlayFromSearchInspection extends AndroidLintInspectionBase {
public AndroidLintMissingOnPlayFromSearchInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.on.play.from.search"),
AndroidAutoDetector.MISSING_ON_PLAY_FROM_SEARCH);
}
}
public static class AndroidLintMissingVersionInspection extends AndroidLintInspectionBase {
public AndroidLintMissingVersionInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.version"), ManifestDetector.SET_VERSION);
}
}
public static class AndroidLintOldTargetApiInspection extends AndroidLintInspectionBase {
public AndroidLintOldTargetApiInspection() {
super(AndroidBundle.message("android.lint.inspections.old.target.api"), ManifestDetector.TARGET_NEWER);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
String highest = Integer.toString(getHighestApi(startElement)); // TODO: preview platform??
String label = "Update targetSdkVersion to " + highest;
if (startElement.getContainingFile() instanceof XmlFile) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(label, "targetSdkVersion\\s*=\\s*[\"'](.*)[\"']", highest)};
} else if (startElement.getContainingFile() instanceof GroovyFile) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(label, null, highest)};
} else{
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
private static int getHighestApi(PsiElement element) {
int max = SdkVersionInfo.HIGHEST_KNOWN_STABLE_API;
AndroidFacet instance = AndroidFacet.getInstance(element);
if (instance != null) {
AndroidSdkData sdkData = instance.getSdkData();
if (sdkData != null) {
for (IAndroidTarget target : sdkData.getTargets()) {
if (target.isPlatform()) {
AndroidVersion version = target.getVersion();
if (version.getApiLevel() > max && !version.isPreview()) {
max = version.getApiLevel();
}
}
}
}
}
return max;
}
}
public static class AndroidLintOrientationInspection extends AndroidLintInspectionBase {
public AndroidLintOrientationInspection() {
super(AndroidBundle.message("android.lint.inspections.orientation"), InefficientWeightDetector.ORIENTATION);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {
new SetAttributeQuickFix("Set orientation=\"horizontal\" (default)", ATTR_ORIENTATION, VALUE_HORIZONTAL),
new SetAttributeQuickFix("Set orientation=\"vertical\" (changes layout)", ATTR_ORIENTATION, VALUE_VERTICAL)
};
}
}
public static class AndroidLintOverrideAbstractInspection extends AndroidLintInspectionBase {
public AndroidLintOverrideAbstractInspection() {
super(AndroidBundle.message("android.lint.inspections.override.abstract"), OverrideConcreteDetector.ISSUE);
}
}
public static class AndroidLintPackagedPrivateKeyInspection extends AndroidLintInspectionBase {
public AndroidLintPackagedPrivateKeyInspection() {
super(AndroidBundle.message("android.lint.inspections.packaged.private.key"), PrivateKeyDetector.ISSUE);
}
}
public static class AndroidLintPropertyEscapeInspection extends AndroidLintInspectionBase {
public AndroidLintPropertyEscapeInspection() {
super(AndroidBundle.message("android.lint.inspections.property.escape"), PropertyFileDetector.ESCAPE);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String escaped = PropertyFileDetector.getSuggestedEscape(message, RAW);
if (escaped != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, null, escaped)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintProtectedPermissionsInspection extends AndroidLintInspectionBase {
public AndroidLintProtectedPermissionsInspection() {
super(AndroidBundle.message("android.lint.inspections.protected.permissions"), SystemPermissionsDetector.ISSUE);
}
}
public static class AndroidLintRecycleInspection extends AndroidLintInspectionBase {
public AndroidLintRecycleInspection() {
super(AndroidBundle.message("android.lint.inspections.recycle"), CleanupDetector.RECYCLE_RESOURCE);
}
}
public static class AndroidLintRecyclerViewInspection extends AndroidLintInspectionBase {
public AndroidLintRecyclerViewInspection() {
super(AndroidBundle.message("android.lint.inspections.recycler.view"), RecyclerViewDetector.FIXED_POSITION);
}
}
public static class AndroidLintReferenceTypeInspection extends AndroidLintInspectionBase {
public AndroidLintReferenceTypeInspection() {
super(AndroidBundle.message("android.lint.inspections.reference.type"), DuplicateResourceDetector.TYPE_MISMATCH);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String expected = DuplicateResourceDetector.getExpectedType(message, RAW);
if (expected != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, "(@.*/)", "@" + expected + "/")};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintRegisteredInspection extends AndroidLintInspectionBase {
public AndroidLintRegisteredInspection() {
super(AndroidBundle.message("android.lint.inspections.registered"), RegistrationDetector.ISSUE);
}
}
public static class AndroidLintRelativeOverlapInspection extends AndroidLintInspectionBase {
public AndroidLintRelativeOverlapInspection() {
super(AndroidBundle.message("android.lint.inspections.relative.overlap"), RelativeOverlapDetector.ISSUE);
}
}
public static class AndroidLintRequiredSizeInspection extends AndroidLintInspectionBase {
public AndroidLintRequiredSizeInspection() {
super(AndroidBundle.message("android.lint.inspections.required.size"), RequiredAttributeDetector.ISSUE);
}
}
public static class AndroidLintResAutoInspection extends AndroidLintInspectionBase {
public AndroidLintResAutoInspection() {
super(AndroidBundle.message("android.lint.inspections.res.auto"), NamespaceDetector.RES_AUTO);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] { new ConvertNamespaceQuickFix() };
}
}
public static class AndroidLintSecureRandomInspection extends AndroidLintInspectionBase {
public AndroidLintSecureRandomInspection() {
super(AndroidBundle.message("android.lint.inspections.secure.random"), SecureRandomDetector.ISSUE);
}
}
public static class AndroidLintSelectableTextInspection extends AndroidLintInspectionBase {
public AndroidLintSelectableTextInspection() {
super(AndroidBundle.message("android.lint.inspections.selectable.text"), TextViewDetector.SELECTABLE);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] {
new SetAttributeQuickFix("Set android:textIsSelectable=true", ATTR_TEXT_IS_SELECTABLE, VALUE_TRUE)
};
}
}
public static class AndroidLintServiceCastInspection extends AndroidLintInspectionBase {
public AndroidLintServiceCastInspection() {
super(AndroidBundle.message("android.lint.inspections.service.cast"), ServiceCastDetector.ISSUE);
}
}
public static class AndroidLintSetJavaScriptEnabledInspection extends AndroidLintInspectionBase {
public AndroidLintSetJavaScriptEnabledInspection() {
super(AndroidBundle.message("android.lint.inspections.set.java.script.enabled"), SetJavaScriptEnabledDetector.ISSUE);
}
}
public static class AndroidLintSetTextI18nInspection extends AndroidLintInspectionBase {
public AndroidLintSetTextI18nInspection() {
super(AndroidBundle.message("android.lint.inspections.set.text.i18n"), SetTextDetector.SET_TEXT_I18N);
}
}
public static class AndroidLintSetWorldReadableInspection extends AndroidLintInspectionBase {
public AndroidLintSetWorldReadableInspection() {
super(AndroidBundle.message("android.lint.inspections.set.world.readable"), SecurityDetector.SET_READABLE);
}
}
public static class AndroidLintSetWorldWritableInspection extends AndroidLintInspectionBase {
public AndroidLintSetWorldWritableInspection() {
super(AndroidBundle.message("android.lint.inspections.set.world.writable"), SecurityDetector.SET_WRITABLE);
}
}
public static class AndroidLintShiftFlagsInspection extends AndroidLintInspectionBase {
public AndroidLintShiftFlagsInspection() {
super(AndroidBundle.message("android.lint.inspections.shift.flags"), AnnotationDetector.FLAG_STYLE);
}
}
public static class AndroidLintShortAlarmInspection extends AndroidLintInspectionBase {
public AndroidLintShortAlarmInspection() {
super(AndroidBundle.message("android.lint.inspections.short.alarm"), AlarmDetector.ISSUE);
}
}
public static class AndroidLintShowToastInspection extends AndroidLintInspectionBase {
public AndroidLintShowToastInspection() {
super(AndroidBundle.message("android.lint.inspections.show.toast"), ToastDetector.ISSUE);
}
}
public static class AndroidLintSignatureOrSystemPermissionsInspection extends AndroidLintInspectionBase {
public AndroidLintSignatureOrSystemPermissionsInspection() {
super(AndroidBundle.message("android.lint.inspections.signature.or.system.permissions"), SignatureOrSystemDetector.ISSUE);
}
@Override
@NotNull
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[] { new ReplaceStringQuickFix(null, "signatureOrSystem", "signature") };
}
}
public static class AndroidLintSimpleDateFormatInspection extends AndroidLintInspectionBase {
public AndroidLintSimpleDateFormatInspection() {
super(AndroidBundle.message("android.lint.inspections.simple.date.format"), DateFormatDetector.DATE_FORMAT);
}
}
public static class AndroidLintSmallSpInspection extends AndroidLintInspectionBase {
public AndroidLintSmallSpInspection() {
super(AndroidBundle.message("android.lint.inspections.small.sp"), PxUsageDetector.SMALL_SP_ISSUE);
}
}
public static class AndroidLintSpUsageInspection extends AndroidLintInspectionBase {
public AndroidLintSpUsageInspection() {
super(AndroidBundle.message("android.lint.inspections.sp.usage"), PxUsageDetector.DP_ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, "\\d+(di?p)", "sp")};
}
}
public static class AndroidLintStaticFieldLeakInspection extends AndroidLintInspectionBase {
public AndroidLintStaticFieldLeakInspection() {
super(AndroidBundle.message("android.lint.inspections.static.field.leak"), com.android.tools.lint.checks.LeakDetector.ISSUE);
}
}
// Maybe not relevant
public static class AndroidLintStopShipInspection extends AndroidLintInspectionBase {
public AndroidLintStopShipInspection() {
super(AndroidBundle.message("android.lint.inspections.stop.ship"), CommentDetector.STOP_SHIP);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
// TODO: Remove comment if that's all that remains
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Remove STOPSHIP", "(\\s*STOPSHIP)", "")};
}
}
public static class AndroidLintStringShouldBeIntInspection extends AndroidLintInspectionBase {
public AndroidLintStringShouldBeIntInspection() {
super(AndroidBundle.message("android.lint.inspections.string.should.be.int"), GradleDetector.STRING_INTEGER);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String current = GradleDetector.getOldValue(GradleDetector.STRING_INTEGER, message, RAW);
String proposed = GradleDetector.getNewValue(GradleDetector.STRING_INTEGER, message, RAW);
if (proposed != null && current != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Replace with integer", current, proposed)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintSupportAnnotationUsageInspection extends AndroidLintInspectionBase {
public AndroidLintSupportAnnotationUsageInspection() {
super(AndroidBundle.message("android.lint.inspections.support.annotation.usage"), AnnotationDetector.ANNOTATION_USAGE);
}
}
public static class AndroidLintSuspicious0dpInspection extends AndroidLintInspectionBase {
public AndroidLintSuspicious0dpInspection() {
super(AndroidBundle.message("android.lint.inspections.suspicious0dp"), InefficientWeightDetector.WRONG_0DP);
}
}
public static class AndroidLintTyposInspection extends AndroidLintInspectionBase {
public AndroidLintTyposInspection() {
super(AndroidBundle.message("android.lint.inspections.typos"), TypoDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
TypoDetector.TypoSuggestionInfo info = TypoDetector.getSuggestions(message, RAW);
final List<String> suggestions = info.getReplacements();
if (!suggestions.isEmpty()) {
List<AndroidLintQuickFix> fixes = Lists.newArrayListWithExpectedSize(suggestions.size());
final String originalPattern = '(' + Pattern.quote(info.getOriginal()) + ')';
for (String suggestion : suggestions) {
fixes.add(new ReplaceStringQuickFix("Replace with \"" + suggestion + "\"", originalPattern, suggestion));
}
return fixes.toArray(new AndroidLintQuickFix[fixes.size()]);
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintUniqueConstantsInspection extends AndroidLintInspectionBase {
public AndroidLintUniqueConstantsInspection() {
super(AndroidBundle.message("android.lint.inspections.unique.constants"), AnnotationDetector.UNIQUE);
}
}
public static class AndroidLintUniquePermissionInspection extends AndroidLintInspectionBase {
public AndroidLintUniquePermissionInspection() {
super(AndroidBundle.message("android.lint.inspections.unique.permission"), ManifestDetector.UNIQUE_PERMISSION);
}
}
public static class AndroidLintUnlocalizedSmsInspection extends AndroidLintInspectionBase {
public AndroidLintUnlocalizedSmsInspection() {
super(AndroidBundle.message("android.lint.inspections.unlocalized.sms"), NonInternationalizedSmsDetector.ISSUE);
}
}
public static class AndroidLintWorldReadableFilesInspection extends AndroidLintInspectionBase {
public AndroidLintWorldReadableFilesInspection() {
super(AndroidBundle.message("android.lint.inspections.world.readable.files"), SecurityDetector.WORLD_READABLE);
}
}
public static class AndroidLintWrongCallInspection extends AndroidLintInspectionBase {
public AndroidLintWrongCallInspection() {
super(AndroidBundle.message("android.lint.inspections.wrong.call"), WrongCallDetector.ISSUE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
String current = WrongCallDetector.getOldValue(message, RAW);
String proposed = WrongCallDetector.getNewValue(message, RAW);
if (proposed != null && current != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix("Replace call with " + proposed + "()", current, proposed)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintWrongCaseInspection extends AndroidLintInspectionBase {
public AndroidLintWrongCaseInspection() {
super(AndroidBundle.message("android.lint.inspections.wrong.case"), WrongCaseDetector.WRONG_CASE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
final String current = WrongCaseDetector.getOldValue(message, RAW);
final String proposed = WrongCaseDetector.getNewValue(message, RAW);
if (proposed != null && current != null) {
return new AndroidLintQuickFix[]{new ReplaceStringQuickFix(null, current, proposed) {
@Override
protected void editAfter(@SuppressWarnings("UnusedParameters") @NotNull Document document) {
String text = document.getText();
int index = text.indexOf("</" + current + ">");
if (index != -1) {
document.replaceString(index + 2, index + 2 + current.length(), proposed);
}
}
}};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
public static class AndroidLintWrongFolderInspection extends AndroidLintInspectionBase {
public AndroidLintWrongFolderInspection() {
super(AndroidBundle.message("android.lint.inspections.wrong.folder"), WrongLocationDetector.ISSUE);
}
}
public static class AndroidLintMissingLeanbackLauncherInspection extends AndroidLintInspectionBase {
public AndroidLintMissingLeanbackLauncherInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.leanback.launcher"), AndroidTvDetector.MISSING_LEANBACK_LAUNCHER);
}
}
public static class AndroidLintMissingLeanbackSupportInspection extends AndroidLintInspectionBase {
public AndroidLintMissingLeanbackSupportInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.leanback.support"), AndroidTvDetector.MISSING_LEANBACK_SUPPORT);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
return new AndroidLintQuickFix[]{new DefaultLintQuickFix("Add uses-feature tag") {
@Override
public void apply(@NotNull PsiElement startElement,
@NotNull PsiElement endElement,
@NotNull AndroidQuickfixContexts.Context context) {
XmlTag parent = PsiTreeUtil.getParentOfType(startElement, XmlTag.class, false);
if (parent != null) {
XmlTag usesFeatureTag = parent.createChildTag(NODE_USES_FEATURE, null, null, false);
usesFeatureTag = parent.addSubTag(usesFeatureTag, true);
usesFeatureTag.setAttribute(ATTR_NAME, ANDROID_URI, AndroidTvDetector.SOFTWARE_FEATURE_LEANBACK);
usesFeatureTag.setAttribute(ATTRIBUTE_REQUIRED, ANDROID_URI, String.valueOf(false));
}
}
}};
}
}
public static class AndroidLintMissingTvBannerInspection extends AndroidLintInspectionBase {
public AndroidLintMissingTvBannerInspection() {
super(AndroidBundle.message("android.lint.inspections.missing.tv.banner"), AndroidTvDetector.MISSING_BANNER);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
return new AndroidLintQuickFix[] { new SetAttributeQuickFix("Set banner attribute", "banner", null) };
}
}
public static class AndroidLintPendingBindingsInspection extends AndroidLintInspectionBase {
public AndroidLintPendingBindingsInspection() {
super(AndroidBundle.message("android.lint.inspections.pending.bindings"), RecyclerViewDetector.DATA_BINDER);
}
}
public static class AndroidLintPermissionImpliesUnsupportedHardwareInspection extends AndroidLintInspectionBase {
public AndroidLintPermissionImpliesUnsupportedHardwareInspection() {
super(AndroidBundle.message("android.lint.inspections.permission.implies.unsupported.hardware"), AndroidTvDetector.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull String message) {
final String hardwareFeatureName = AndroidTvDetector.getHardwareFeature(message, RAW);
if (hardwareFeatureName != null) {
return new AndroidLintQuickFix[] {
new DefaultLintQuickFix("Add uses-feature tag") {
@Override
public void apply(@NotNull PsiElement startElement, @NotNull PsiElement endElement,
@NotNull AndroidQuickfixContexts.Context context) {
XmlTag usesPermissionTag = PsiTreeUtil.getParentOfType(startElement, XmlTag.class, false);
if (startElement.textMatches(NODE_USES_PERMISSION) && usesPermissionTag != null) {
XmlTag parent = (XmlTag)usesPermissionTag.getParent();
if (parent != null) {
XmlTag usesFeatureTag = parent.createChildTag(NODE_USES_FEATURE, null, null, false);
usesFeatureTag = parent.addSubTag(usesFeatureTag, true);
usesFeatureTag.setAttribute(ATTR_NAME, ANDROID_URI, hardwareFeatureName);
usesFeatureTag.setAttribute(ATTRIBUTE_REQUIRED, ANDROID_URI, String.valueOf(false));
}
}
}
}
};
} else {
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
}
public static class AndroidLintUnsafeDynamicallyLoadedCodeInspection extends AndroidLintInspectionBase {
public AndroidLintUnsafeDynamicallyLoadedCodeInspection() {
super(AndroidBundle.message("android.lint.inspections.unsafe.dynamically.loaded.code"), UnsafeNativeCodeDetector.LOAD);
}
}
public static class AndroidLintUnsafeNativeCodeLocationInspection extends AndroidLintInspectionBase {
public AndroidLintUnsafeNativeCodeLocationInspection() {
super(AndroidBundle.message("android.lint.inspections.unsafe.native.code.location"), UnsafeNativeCodeDetector.UNSAFE_NATIVE_CODE_LOCATION);
}
}
public static class AndroidLintUnsafeProtectedBroadcastReceiverInspection extends AndroidLintInspectionBase {
public AndroidLintUnsafeProtectedBroadcastReceiverInspection() {
super(AndroidBundle.message("android.lint.inspections.unsafe.protected.broadcast.receiver"), UnsafeBroadcastReceiverDetector.ACTION_STRING);
}
}
public static class AndroidLintUnsupportedTvHardwareInspection extends AndroidLintInspectionBase {
public AndroidLintUnsupportedTvHardwareInspection() {
super(AndroidBundle.message("android.lint.inspections.unsupported.tv.hardware"), AndroidTvDetector.UNSUPPORTED_TV_HARDWARE);
}
@NotNull
@Override
public AndroidLintQuickFix[] getQuickFixes(@NotNull PsiElement startElement, @NotNull PsiElement endElement, @NotNull String message) {
if (startElement.textMatches(PREFIX_ANDROID + ATTRIBUTE_REQUIRED)) {
// android:required attribute
XmlAttribute attr = PsiTreeUtil.getParentOfType(startElement, XmlAttribute.class);
assert attr != null;
return new AndroidLintQuickFix[] {
new ReplaceStringQuickFix("Replace with required=\"false\"",
null,
PREFIX_ANDROID + ATTRIBUTE_REQUIRED + "=\"" + false + "\""),
};
} else if (startElement.textMatches(NODE_USES_FEATURE)) {
return new AndroidLintQuickFix[]{new SetAttributeQuickFix("Set required=\"false\"", ATTRIBUTE_REQUIRED, VALUE_FALSE)};
}
return AndroidLintQuickFix.EMPTY_ARRAY;
}
}
}