aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java226
1 files changed, 226 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java
new file mode 100644
index 000000000..366e94945
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintFix.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ide.eclipse.adt.internal.lint;
+
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.tools.lint.checks.AccessibilityDetector;
+import com.android.tools.lint.checks.DetectMissingPrefix;
+import com.android.tools.lint.checks.DosLineEndingDetector;
+import com.android.tools.lint.checks.HardcodedValuesDetector;
+import com.android.tools.lint.checks.InefficientWeightDetector;
+import com.android.tools.lint.checks.ManifestDetector;
+import com.android.tools.lint.checks.MissingIdDetector;
+import com.android.tools.lint.checks.ObsoleteLayoutParamsDetector;
+import com.android.tools.lint.checks.PxUsageDetector;
+import com.android.tools.lint.checks.ScrollViewChildDetector;
+import com.android.tools.lint.checks.SecurityDetector;
+import com.android.tools.lint.checks.TextFieldDetector;
+import com.android.tools.lint.checks.TranslationDetector;
+import com.android.tools.lint.checks.TypoDetector;
+import com.android.tools.lint.checks.TypographyDetector;
+import com.android.tools.lint.checks.UseCompoundDrawableDetector;
+import com.android.tools.lint.checks.UselessViewDetector;
+import com.android.tools.lint.detector.api.Issue;
+import com.android.tools.lint.detector.api.TextFormat;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+abstract class LintFix implements ICompletionProposal {
+ protected final IMarker mMarker;
+ protected final String mId;
+
+ protected LintFix(String id, IMarker marker) {
+ mId = id;
+ mMarker = marker;
+ }
+
+ /**
+ * Returns true if this fix needs focus (which means that when the fix is
+ * performed from for example a {@link LintListDialog}'s Fix button) the
+ * editor needs to be given focus.
+ *
+ * @return true if this fix needs focus after being applied
+ */
+ public boolean needsFocus() {
+ return true;
+ }
+
+ /**
+ * Returns true if this fix can be performed along side other fixes
+ *
+ * @return true if this fix can be performed in a bulk operation with other
+ * fixes
+ */
+ public boolean isBulkCapable() {
+ return false;
+ }
+
+ /**
+ * Returns true if this fix can be cancelled once it's invoked. This is the case
+ * for fixes which shows a confirmation dialog (such as the Extract String etc).
+ * This will be used to determine whether the marker can be deleted immediately
+ * (for non-cancelable fixes) or if it should be left alone and detected fix
+ * on the next save.
+ *
+ * @return true if the fix can be cancelled
+ */
+ public boolean isCancelable() {
+ return true;
+ }
+
+ // ---- Implements ICompletionProposal ----
+
+ @Override
+ public String getDisplayString() {
+ return null;
+ }
+
+ @Override
+ public String getAdditionalProposalInfo() {
+ Issue issue = EclipseLintClient.getRegistry().getIssue(mId);
+ if (issue != null) {
+ return issue.getExplanation(TextFormat.HTML);
+ }
+
+ return null;
+ }
+
+ public void deleteMarker() {
+ try {
+ mMarker.delete();
+ } catch (PartInitException e) {
+ AdtPlugin.log(e, null);
+ } catch (CoreException e) {
+ AdtPlugin.log(e, null);
+ }
+ }
+
+ @Override
+ public Point getSelection(IDocument document) {
+ return null;
+ }
+
+ @Override
+ public Image getImage() {
+ ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
+ return sharedImages.getImage(ISharedImages.IMG_OBJS_WARN_TSK);
+ }
+
+ @Override
+ public IContextInformation getContextInformation() {
+ return null;
+ }
+
+ // --- Access to available fixes ---
+
+ private static final Map<String, Class<? extends LintFix>> sFixes =
+ new HashMap<String, Class<? extends LintFix>>();
+ // Keep this map in sync with BuiltinIssueRegistry's hasAutoFix() data
+ static {
+ sFixes.put(InefficientWeightDetector.INEFFICIENT_WEIGHT.getId(),
+ LinearLayoutWeightFix.class);
+ sFixes.put(AccessibilityDetector.ISSUE.getId(), SetAttributeFix.class);
+ sFixes.put(InefficientWeightDetector.BASELINE_WEIGHTS.getId(), SetAttributeFix.class);
+ sFixes.put(ManifestDetector.ALLOW_BACKUP.getId(), SetAttributeFix.class);
+ sFixes.put(MissingIdDetector.ISSUE.getId(), SetAttributeFix.class);
+ sFixes.put(HardcodedValuesDetector.ISSUE.getId(), ExtractStringFix.class);
+ sFixes.put(UselessViewDetector.USELESS_LEAF.getId(), RemoveUselessViewFix.class);
+ sFixes.put(UselessViewDetector.USELESS_PARENT.getId(), RemoveUselessViewFix.class);
+ sFixes.put(PxUsageDetector.PX_ISSUE.getId(), ConvertToDpFix.class);
+ sFixes.put(TextFieldDetector.ISSUE.getId(), SetAttributeFix.class);
+ sFixes.put(SecurityDetector.EXPORTED_SERVICE.getId(), SetAttributeFix.class);
+ sFixes.put(TranslationDetector.MISSING.getId(), SetAttributeFix.class);
+ sFixes.put(DetectMissingPrefix.MISSING_NAMESPACE.getId(), AddPrefixFix.class);
+ sFixes.put(ScrollViewChildDetector.ISSUE.getId(), SetScrollViewSizeFix.class);
+ sFixes.put(ObsoleteLayoutParamsDetector.ISSUE.getId(), ObsoleteLayoutParamsFix.class);
+ sFixes.put(TypographyDetector.DASHES.getId(), TypographyFix.class);
+ sFixes.put(TypographyDetector.ELLIPSIS.getId(), TypographyFix.class);
+ sFixes.put(TypographyDetector.FRACTIONS.getId(), TypographyFix.class);
+ sFixes.put(TypographyDetector.OTHER.getId(), TypographyFix.class);
+ sFixes.put(TypographyDetector.QUOTES.getId(), TypographyFix.class);
+ sFixes.put(UseCompoundDrawableDetector.ISSUE.getId(),
+ UseCompoundDrawableDetectorFix.class);
+ sFixes.put(TypoDetector.ISSUE.getId(), TypoFix.class);
+ sFixes.put(DosLineEndingDetector.ISSUE.getId(), DosLineEndingsFix.class);
+ // ApiDetector.UNSUPPORTED is provided as a marker resolution rather than
+ // a quick assistant (the marker resolution adds a suitable @TargetApi annotation)
+ }
+
+ public static boolean hasFix(String id) {
+ return sFixes.containsKey(id);
+ }
+
+ /**
+ * Returns one or more fixes for the given issue, or null if no fixes are available
+ *
+ * @param id the id o the issue to obtain a fix for (see {@link Issue#getId()})
+ * @param marker the marker corresponding to the error
+ * @return a nonempty list of fix, or null
+ */
+ @Nullable
+ public static List<LintFix> getFixes(@NonNull String id, @NonNull IMarker marker) {
+ Class<? extends LintFix> clazz = sFixes.get(id);
+ if (clazz != null) {
+ try {
+ Constructor<? extends LintFix> constructor = clazz.getDeclaredConstructor(
+ String.class, IMarker.class);
+ constructor.setAccessible(true);
+ LintFix fix = constructor.newInstance(id, marker);
+ List<LintFix> alternatives = fix.getAllFixes();
+ if (alternatives != null) {
+ return alternatives;
+ } else {
+ return Collections.singletonList(fix);
+ }
+ } catch (Throwable t) {
+ AdtPlugin.log(t, null);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns a full list of fixes for this issue. This will produce a list of
+ * multiple fixes, in the desired order, which provide alternative ways of
+ * fixing the issue.
+ *
+ * @return a list of fixes to fix this issue, or null if there are no
+ * variations
+ */
+ @Nullable
+ protected List<LintFix> getAllFixes() {
+ return null;
+ }
+}