diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintJob.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintJob.java | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintJob.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintJob.java new file mode 100644 index 000000000..51fa2d145 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/lint/LintJob.java @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2012 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 static com.android.SdkConstants.DOT_CLASS; +import static com.android.SdkConstants.DOT_JAVA; +import static com.android.SdkConstants.DOT_XML; + +import com.android.SdkConstants; +import com.android.annotations.NonNull; +import com.android.annotations.Nullable; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.AdtUtils; +import com.android.tools.lint.client.api.IssueRegistry; +import com.android.tools.lint.client.api.LintDriver; +import com.android.tools.lint.client.api.LintRequest; +import com.android.tools.lint.detector.api.Issue; +import com.android.tools.lint.detector.api.Scope; +import com.android.utils.SdkUtils; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; + +import java.io.File; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +/** Job to check lint on a set of resources */ +public final class LintJob extends Job { + /** Job family */ + private static final Object FAMILY_RUN_LINT = new Object(); + private final EclipseLintClient mClient; + private final List<? extends IResource> mResources; + private final IResource mSource; + private final IssueRegistry mRegistry; + private LintDriver mLint; + private boolean mFatal; + + public LintJob( + @NonNull EclipseLintClient client, + @NonNull List<? extends IResource> resources, + @Nullable IResource source, + @NonNull IssueRegistry registry) { + super("Running Android Lint"); + mClient = client; + mResources = resources; + mSource = source; + mRegistry = registry; + } + + public LintJob( + @NonNull EclipseLintClient client, + @NonNull List<? extends IResource> resources, + @Nullable IResource source) { + this(client, resources, source, EclipseLintClient.getRegistry()); + } + + @Override + public boolean belongsTo(Object family) { + return family == FAMILY_RUN_LINT; + } + + @Override + protected void canceling() { + super.canceling(); + if (mLint != null) { + mLint.cancel(); + } + } + + @Override + @NonNull + protected IStatus run(IProgressMonitor monitor) { + try { + monitor.beginTask("Looking for errors", IProgressMonitor.UNKNOWN); + EnumSet<Scope> scope = null; + List<File> files = new ArrayList<File>(mResources.size()); + for (IResource resource : mResources) { + File file = AdtUtils.getAbsolutePath(resource).toFile(); + files.add(file); + + if (resource instanceof IProject && mSource == null) { + scope = Scope.ALL; + } else { + String name = resource.getName(); + if (SdkUtils.endsWithIgnoreCase(name, DOT_XML)) { + if (name.equals(SdkConstants.FN_ANDROID_MANIFEST_XML)) { + scope = EnumSet.of(Scope.MANIFEST); + } else { + scope = Scope.RESOURCE_FILE_SCOPE; + } + } else if (name.endsWith(DOT_JAVA) && resource instanceof IFile) { + if (scope != null) { + if (!scope.contains(Scope.JAVA_FILE)) { + scope = EnumSet.copyOf(scope); + scope.add(Scope.JAVA_FILE); + } + } else { + scope = Scope.JAVA_FILE_SCOPE; + } + } else if (name.endsWith(DOT_CLASS) && resource instanceof IFile) { + if (scope != null) { + if (!scope.contains(Scope.CLASS_FILE)) { + scope = EnumSet.copyOf(scope); + scope.add(Scope.CLASS_FILE); + } + } else { + scope = Scope.CLASS_FILE_SCOPE; + } + } else { + return new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, Status.ERROR, + "Only XML & Java files are supported for single file lint", null); //$NON-NLS-1$ + } + } + } + if (scope == null) { + scope = Scope.ALL; + } + if (mSource == null) { + assert !Scope.checkSingleFile(scope) : scope + " with " + mResources; + } + // Check single file? + if (mSource != null) { + // Delete specific markers + IMarker[] markers = EclipseLintClient.getMarkers(mSource); + for (IMarker marker : markers) { + String id = marker.getAttribute(EclipseLintRunner.MARKER_CHECKID_PROPERTY, ""); + Issue issue = mRegistry.getIssue(id); + if (issue == null) { + continue; + } + if (issue.getImplementation().isAdequate(scope)) { + marker.delete(); + } + } + mClient.setSearchForSuperClasses(true); + } else { + EclipseLintClient.clearMarkers(mResources); + } + + mLint = new LintDriver(mRegistry, mClient); + mLint.analyze(new LintRequest(mClient, files).setScope(scope)); + mFatal = mClient.hasFatalErrors(); + return Status.OK_STATUS; + } catch (Exception e) { + return new Status(Status.ERROR, AdtPlugin.PLUGIN_ID, Status.ERROR, + "Failed", e); //$NON-NLS-1$ + } finally { + if (monitor != null) { + monitor.done(); + } + } + } + + /** + * Returns true if a fatal error was encountered + * + * @return true if a fatal error was encountered + */ + public boolean isFatal() { + return mFatal; + } + + /** + * Returns the associated lint client + * + * @return the associated lint client + */ + @NonNull + public EclipseLintClient getLintClient() { + return mClient; + } + + /** Returns the current lint jobs, if any (never returns null but array may be empty) */ + @NonNull + static Job[] getCurrentJobs() { + IJobManager jobManager = Job.getJobManager(); + return jobManager.find(LintJob.FAMILY_RUN_LINT); + } +} |