blob: f9c46b2aa7270f5c02083806fe11a0f01cc220d7 [file] [log] [blame]
package com.google.dart.tools.core.internal.analysis.model;
import com.google.dart.engine.context.AnalysisContext;
import com.google.dart.engine.context.AnalysisDelta;
import com.google.dart.engine.context.AnalysisDelta.AnalysisLevel;
import com.google.dart.engine.context.AnalysisErrorInfo;
import com.google.dart.engine.index.Index;
import com.google.dart.engine.source.Source;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.analysis.model.Project;
import com.google.dart.tools.core.analysis.model.ProjectManager;
import com.google.dart.tools.core.internal.builder.AnalysisManager;
import com.google.dart.tools.core.internal.builder.AnalysisMarkerManager;
import com.google.dart.tools.core.internal.builder.DeltaAdapter;
import com.google.dart.tools.core.internal.builder.DeltaProcessor;
import com.google.dart.tools.core.internal.builder.ResourceDeltaEvent;
import com.google.dart.tools.core.internal.builder.SourceDeltaEvent;
import com.google.dart.tools.core.internal.model.DartIgnoreManager;
import com.google.dart.tools.core.model.DartIgnoreEvent;
import com.google.dart.tools.core.model.DartIgnoreListener;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import java.io.File;
/**
* Instances of {@code ProjectManagerIgnoreListener} listen for changes broadcast by the
* {@link DartIgnoreManager} and update the contexts affected by that change.
*/
public class ProjectManagerIgnoreListener implements DartIgnoreListener {
private final ProjectManager projectManager;
private final IWorkspaceRoot workspaceRoot;
private final AnalysisManager analysisManager;
private final AnalysisMarkerManager markerManager;
private final Index index;
public ProjectManagerIgnoreListener(ProjectManager projectManager, IWorkspaceRoot workspaceRoot,
AnalysisManager analysisManager, AnalysisMarkerManager markerManager, Index index) {
this.projectManager = projectManager;
this.workspaceRoot = workspaceRoot;
this.analysisManager = analysisManager;
this.markerManager = markerManager;
this.index = index;
}
@Override
public void ignoresChanged(DartIgnoreEvent event) {
String[] ignoresAdded = event.getAdded();
String[] ignoresRemoved = event.getRemoved();
if (ignoresAdded.length > 0) {
processIgnoresAdded(ignoresAdded);
}
if (ignoresRemoved.length > 0) {
processIgnoresRemoved(ignoresRemoved);
}
}
/**
* Answer the resource with the given path.
*
* @param path the absolute path to the resource, not <code>null</code>
* @return the resource or <code>null</code> if no match is found
*/
private IResource getResourceFromPath(String path) {
Path location = new Path(path);
if (isFilePath(location)) {
return workspaceRoot.getFileForLocation(location);
} else {
return workspaceRoot.getContainerForLocation(location);
}
}
/**
* Determine if the given path represents an existing file. If no such file or directory exists,
* then return true if the specified path has a file extension.
*
* @param location the path
* @return <code>true</code> if the path is for a file
*/
private boolean isFilePath(Path location) {
File file = location.toFile();
if (file.isFile()) {
return true;
}
if (file.isDirectory()) {
return false;
}
// File does not exist, so guess based upon the extension
return location.getFileExtension() != null;
}
/**
* Update all contexts based upon the specified paths to be ignored.
*
* @param paths an array of zero or more paths to be ignored, not <code>null</code>
*/
private void processIgnoresAdded(String[] paths) {
for (String path : paths) {
IResource resource = getResourceFromPath(path);
if (resource != null) {
//
// Visit each source and notify the appropriate context that it should not be analyzed
//
final Project project = projectManager.getProject(resource.getProject());
if (project != null) {
DeltaProcessor processor = new DeltaProcessor(project);
DeltaAdapter visitor = new DeltaAdapter() {
AnalysisContext context;
AnalysisDelta delta;
@Override
public void packageSourceAdded(SourceDeltaEvent event) {
Source source = event.getSource();
if (source != null) {
delta.setAnalysisLevel(source, AnalysisLevel.NONE);
index.removeSource(context, source);
}
}
@Override
public void sourceAdded(SourceDeltaEvent event) {
Source source = event.getSource();
if (source != null) {
delta.setAnalysisLevel(source, AnalysisLevel.NONE);
index.removeSource(context, source);
}
}
@Override
public void visitContext(ResourceDeltaEvent event) {
if (context != null) {
context.applyAnalysisDelta(delta);
}
if (event != null) {
context = event.getContext();
delta = new AnalysisDelta();
}
}
};
processor.addDeltaListener(visitor);
try {
processor.traverse(resource);
} catch (CoreException e) {
DartCore.logError("Failed to ignore " + resource, e);
}
visitor.visitContext(null);
}
markerManager.clearMarkers(resource);
}
}
}
/**
* Update all contexts based upon the specified paths to be analyzed.
*
* @param paths an array of zero or more paths to be included in analysis, not <code>null</code>
*/
private void processIgnoresRemoved(String[] paths) {
for (String path : paths) {
IResource resource = getResourceFromPath(path);
if (resource != null && resource.isAccessible()) {
//
// Visit each source and notify the appropriate context that it should be analyzed
//
final Project project = projectManager.getProject(resource.getProject());
if (project != null) {
DeltaProcessor processor = new DeltaProcessor(project);
DeltaAdapter visitor = new DeltaAdapter() {
AnalysisContext context;
AnalysisDelta delta;
@Override
public void packageSourceAdded(SourceDeltaEvent event) {
Source source = event.getSource();
if (source != null) {
delta.setAnalysisLevel(source, AnalysisLevel.RESOLVED);
}
}
@Override
public void sourceAdded(SourceDeltaEvent event) {
Source source = event.getSource();
if (source != null) {
delta.setAnalysisLevel(source, AnalysisLevel.ALL);
AnalysisErrorInfo errorInfo = context.getErrors(source);
markerManager.queueErrors(
projectManager.getResource(source),
errorInfo.getLineInfo(),
errorInfo.getErrors());
}
}
@Override
public void visitContext(ResourceDeltaEvent event) {
if (context != null) {
context.applyAnalysisDelta(delta);
analysisManager.performAnalysisInBackground(project, context);
}
if (event != null) {
context = event.getContext();
delta = new AnalysisDelta();
}
}
};
processor.addDeltaListener(visitor);
try {
processor.traverse(resource);
} catch (CoreException e) {
DartCore.logError("Failed to analyze " + resource, e);
}
visitor.visitContext(null);
}
}
}
}
}