mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +02:00
Bug 497670 - Support compiler provided "fix-it" hints
- add new FixitErrorParser that extends RegexErrorParser and is used to replace the error parser for GNUCErrorParser - add new FixManager class to bind a fixit message with its problem marker - modify ProblemMarkerFilterManager to register the last accepted ProblemMarkerInfo for a particular resource so the FixitErrorParser can find the last error marker for the file that precedes the fixit message - FixitErrorParser looks for fix-it messages and binds them via FixitManager to the last error marker for the file - add new Fixit class to contain the details of a gcc fix-it - add new QuickFixForFixit which applies the gcc fix-it for the file - add new (.*) regex in codan.ui.checkers patterns that will trigger before any other error and will look for the fix-it message format - change cdt.core to expose cdt.internal.errorparsers to codan.checkers.ui - change codan.core to expose codan.internal.core.model to codan.checkers.ui - fix CDocumentProvider.setOverlay method to not overlay a CMarkerAnnotation that has a quick fix - when deleting all C problem markers, also make a call to FixManager.deleteAllMarkers() so markers aren't left referenced Change-Id: Ibf8ff7d8addb1bf092dc4ef35de0d92de0309589
This commit is contained in:
parent
908a609a53
commit
795a90288b
14 changed files with 388 additions and 8 deletions
|
@ -15,6 +15,7 @@ import java.util.Map;
|
|||
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.cdt.core.resources.ACBuilder;
|
||||
import org.eclipse.cdt.internal.errorparsers.FixitManager;
|
||||
import org.eclipse.cdt.make.core.makefile.IMakefileValidator;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
|
@ -147,6 +148,7 @@ public class GNUMakefileChecker extends ACBuilder {
|
|||
return validator;
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
private void removeAllMarkers(IFile file) throws CoreException {
|
||||
IWorkspace workspace = file.getWorkspace();
|
||||
|
||||
|
@ -154,6 +156,7 @@ public class GNUMakefileChecker extends ACBuilder {
|
|||
IMarker[] markers = file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
|
||||
if (markers != null) {
|
||||
workspace.deleteMarkers(markers);
|
||||
FixitManager.getInstance().deleteMarkers(markers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.List;
|
|||
import org.eclipse.cdt.core.IMarkerGenerator;
|
||||
import org.eclipse.cdt.core.ProblemMarkerInfo;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.cdt.internal.errorparsers.FixitManager;
|
||||
import org.eclipse.cdt.make.core.MakeCorePlugin;
|
||||
import org.eclipse.cdt.make.core.messages.Messages;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
|
@ -106,6 +107,7 @@ public class SCMarkerGenerator implements IMarkerGenerator {
|
|||
markerJob.schedule();
|
||||
}
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public void removeMarker(IResource file, int lineNumber, String errorDesc, int severity, String errorVar) {
|
||||
IWorkspace workspace = file.getWorkspace();
|
||||
// remove specific marker
|
||||
|
@ -126,6 +128,7 @@ public class SCMarkerGenerator implements IMarkerGenerator {
|
|||
}
|
||||
if (exactMarkers.size() > 0) {
|
||||
workspace.deleteMarkers(exactMarkers.toArray(new IMarker[exactMarkers.size()]));
|
||||
FixitManager.getInstance().deleteMarkers(exactMarkers.toArray(new IMarker[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.cdt.core.resources.ACBuilder;
|
|||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
import org.eclipse.cdt.core.resources.RefreshScopeManager;
|
||||
import org.eclipse.cdt.internal.core.BuildRunnerHelper;
|
||||
import org.eclipse.cdt.internal.errorparsers.FixitManager;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.BuildDescriptionManager;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildIOType;
|
||||
|
@ -1162,6 +1163,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
|
|||
*
|
||||
* @param project
|
||||
*/
|
||||
@SuppressWarnings("restriction")
|
||||
private void removeAllMarkers(IProject project) {
|
||||
if (project == null || !project.isAccessible()) return;
|
||||
|
||||
|
@ -1177,6 +1179,7 @@ public class GeneratedMakefileBuilder extends ACBuilder {
|
|||
if (markers != null) {
|
||||
try {
|
||||
workspace.deleteMarkers(markers);
|
||||
FixitManager.getInstance().deleteMarkers(markers);
|
||||
} catch (CoreException e) {
|
||||
// The only situation that might cause this is some sort of resource change event
|
||||
return;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.cdt.codan.ui.codanMarkerResolution">
|
||||
<resolution
|
||||
class="org.eclipse.cdt.codan.internal.checkers.ui.quickfix.QuickFixForFixit"
|
||||
messagePattern=".*">
|
||||
</resolution>
|
||||
<resolution
|
||||
class="org.eclipse.cdt.codan.internal.checkers.ui.quickfix.CatchByReferenceQuickFix"
|
||||
problemId="org.eclipse.cdt.codan.internal.checkers.CatchByReference">
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
|
||||
|
||||
import org.eclipse.cdt.codan.internal.checkers.ui.CheckersUiActivator;
|
||||
import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
|
||||
import org.eclipse.cdt.internal.errorparsers.Fixit;
|
||||
import org.eclipse.cdt.internal.errorparsers.FixitManager;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
|
||||
public class QuickFixForFixit extends AbstractCodanCMarkerResolution {
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return QuickFixMessages.QuickFixForFixit_apply_fixit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(IMarker marker, IDocument document) {
|
||||
int lineNum = marker.getAttribute(IMarker.LINE_NUMBER, -1);
|
||||
try {
|
||||
if (lineNum >= 0) {
|
||||
Fixit f = FixitManager.getInstance().findFixit(marker);
|
||||
int lineOffset = document.getLineOffset(f.getLineNumber() - 1);
|
||||
int columnOffset = f.getColumnNumber() - 1;
|
||||
try {
|
||||
document.replace(lineOffset + columnOffset, f.getLength(), f.getChange());
|
||||
} catch (BadLocationException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
FixitManager.getInstance().deleteMarker(marker);
|
||||
marker.delete();
|
||||
} catch (BadLocationException | CoreException e) {
|
||||
CheckersUiActivator.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(IMarker marker) {
|
||||
return FixitManager.getInstance().hasFixit(marker);
|
||||
}
|
||||
}
|
|
@ -11,9 +11,7 @@ Bundle-ActivationPolicy: lazy
|
|||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Export-Package: org.eclipse.cdt.codan.core,
|
||||
org.eclipse.cdt.codan.core.model,
|
||||
org.eclipse.cdt.codan.core.model.cfg;
|
||||
x-friends:="org.eclipse.cdt.codan.core.cxx,
|
||||
org.eclipse.cdt.codan.checkers",
|
||||
org.eclipse.cdt.codan.core.model.cfg;x-friends:="org.eclipse.cdt.codan.core.cxx,org.eclipse.cdt.codan.checkers",
|
||||
org.eclipse.cdt.codan.core.param,
|
||||
org.eclipse.cdt.codan.internal.core;
|
||||
x-friends:="org.eclipse.cdt.codan.core,
|
||||
|
@ -26,4 +24,5 @@ Export-Package: org.eclipse.cdt.codan.core,
|
|||
x-friends:="org.eclipse.cdt.codan.core.cxx,
|
||||
org.eclipse.cdt.codan.core.test,
|
||||
org.eclipse.cdt.codan.ui,
|
||||
org.eclipse.cdt.codan.ui.cxx"
|
||||
org.eclipse.cdt.codan.ui.cxx,
|
||||
org.eclipse.cdt.codan.checkers.ui"
|
||||
|
|
|
@ -96,7 +96,7 @@ Export-Package: org.eclipse.cdt.core,
|
|||
org.eclipse.cdt.internal.core.resources;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.make.core,org.eclipse.cdt.codan.ui.cxx",
|
||||
org.eclipse.cdt.internal.core.settings.model;x-internal:=true,
|
||||
org.eclipse.cdt.internal.core.util;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.errorparsers;x-internal:=true,
|
||||
org.eclipse.cdt.internal.errorparsers;x-friends:="org.eclipse.cdt.codan.checkers.ui",
|
||||
org.eclipse.cdt.internal.formatter;x-friends:="org.eclipse.cdt.ui",
|
||||
org.eclipse.cdt.internal.formatter.align;x-internal:=true,
|
||||
org.eclipse.cdt.internal.formatter.scanner;x-friends:="org.eclipse.cdt.ui",
|
||||
|
|
|
@ -156,7 +156,7 @@
|
|||
name="%CDTGNUCErrorParser.name"
|
||||
point="org.eclipse.cdt.core.ErrorParser">
|
||||
<errorparser
|
||||
class="org.eclipse.cdt.core.errorparsers.RegexErrorParser"
|
||||
class="org.eclipse.cdt.core.errorparsers.FixitErrorParser"
|
||||
id="org.eclipse.cdt.core.GCCErrorParser"
|
||||
name="%CDTGNUCErrorParser.name">
|
||||
<pattern description-expr="" eat-processed-line="true" file-expr="" line-expr="" regex="%CDTGNUCErrorParser.regex.ReportedOnlyOnce" severity="Ignore"/>
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat Inc - initial API
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.errorparsers;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.ProblemMarkerInfo;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.cdt.internal.core.ProblemMarkerFilterManager;
|
||||
import org.eclipse.cdt.internal.errorparsers.FixitManager;
|
||||
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.CoreException;
|
||||
|
||||
/**
|
||||
* @since 6.3
|
||||
*/
|
||||
public class FixitErrorParser extends RegexErrorParser {
|
||||
|
||||
private final static Pattern fixit = Pattern.compile("fix-it:\"(.*)\":\\{(.*-.*)\\}:\"(.*)\""); //$NON-NLS-1$
|
||||
|
||||
public FixitErrorParser (String id, String name) {
|
||||
super(id, name);
|
||||
}
|
||||
|
||||
public FixitErrorParser () {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processLine(String line, ErrorParserManager epManager) {
|
||||
Matcher m = fixit.matcher(line);
|
||||
if (m.matches()) {
|
||||
IProject project = null;
|
||||
IFile f = epManager.findFileName(m.group(1));
|
||||
if (f != null) {
|
||||
project = f.getProject();
|
||||
try {
|
||||
ProblemMarkerInfo info = ProblemMarkerFilterManager.getInstance().getLastProblemMarker(f);
|
||||
String externalLocation = null;
|
||||
if (info.externalPath != null && !info.externalPath.isEmpty()) {
|
||||
externalLocation = info.externalPath.toOSString();
|
||||
}
|
||||
|
||||
// Try to find matching marker to tie to fix-it
|
||||
IMarker[] markers = f.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true,
|
||||
IResource.DEPTH_ONE);
|
||||
for (IMarker marker : markers) {
|
||||
int lineNumber = marker.getAttribute(IMarker.LINE_NUMBER, -1);
|
||||
int sev = marker.getAttribute(IMarker.SEVERITY, -1);
|
||||
String msg = (String) marker.getAttribute(IMarker.MESSAGE);
|
||||
if (lineNumber == info.lineNumber
|
||||
&& sev == info.severity
|
||||
&& msg.equals(info.description)) {
|
||||
String extloc = (String) marker.getAttribute(ICModelMarker.C_MODEL_MARKER_EXTERNAL_LOCATION);
|
||||
if (extloc == null || extloc.equals(externalLocation)) {
|
||||
if (project == null || project.equals(info.file.getProject())) {
|
||||
FixitManager.getInstance().addMarker(marker, m.group(2), m.group(3));
|
||||
return true;
|
||||
}
|
||||
String source = (String) marker.getAttribute(IMarker.SOURCE_ID);
|
||||
if (project.getName().equals(source)) {
|
||||
FixitManager.getInstance().addMarker(marker, m.group(2), m.group(3));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException | NumberFormatException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.processLine(line, epManager);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
FixitErrorParser that = new FixitErrorParser(getId(), getName());
|
||||
for (RegexErrorPattern pattern : getPatterns()) {
|
||||
that.addPattern((RegexErrorPattern)pattern.clone());
|
||||
}
|
||||
return that;
|
||||
}
|
||||
}
|
|
@ -34,6 +34,7 @@ import org.eclipse.cdt.core.model.ICModelMarker;
|
|||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
import org.eclipse.cdt.core.resources.RefreshScopeManager;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.internal.errorparsers.FixitManager;
|
||||
import org.eclipse.cdt.utils.EFSExtensionManager;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
@ -216,6 +217,7 @@ public class BuildRunnerHelper implements Closeable {
|
|||
}
|
||||
if (markersList.size() > 0) {
|
||||
workspace.deleteMarkers(markersList.toArray(new IMarker[markersList.size()]));
|
||||
FixitManager.getInstance().deleteMarkers(markersList.toArray(new IMarker[markersList.size()]));
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
// ignore
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
package org.eclipse.cdt.internal.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
@ -17,6 +18,7 @@ import org.eclipse.cdt.core.ErrorParserManager;
|
|||
import org.eclipse.cdt.core.IProblemMarkerFilter;
|
||||
import org.eclipse.cdt.core.ProblemMarkerInfo;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
@ -50,6 +52,11 @@ public class ProblemMarkerFilterManager {
|
|||
*/
|
||||
private final Map<IProject, List<ProblemMarkerFilterDesc>> filtersCache = new WeakHashMap<IProject, List<ProblemMarkerFilterDesc>>();
|
||||
|
||||
/**
|
||||
* Last Problem Marker that was accepted.
|
||||
*/
|
||||
private Map<IResource, ProblemMarkerInfo> lastAcceptedProblemMarker = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Return singleton instance of ProblemMarkerFilterManager
|
||||
*
|
||||
|
@ -76,6 +83,15 @@ public class ProblemMarkerFilterManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last accepted problem marker for a particular file.
|
||||
* @param resource file to get last marker for
|
||||
* @return last accepted marker
|
||||
*/
|
||||
public ProblemMarkerInfo getLastProblemMarker(IResource resource) {
|
||||
return lastAcceptedProblemMarker.get(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by {@link ErrorParserManager#addProblemMarker(ProblemMarkerInfo)} to filter out unnecessary problem markers
|
||||
*
|
||||
|
@ -88,14 +104,19 @@ public class ProblemMarkerFilterManager {
|
|||
*/
|
||||
public boolean acceptMarker(ProblemMarkerInfo markerInfo) {
|
||||
IProject project = markerInfo.file.getProject();
|
||||
if (project == null || !project.isOpen())
|
||||
if (project == null || !project.isOpen()) {
|
||||
// store last marker for a file for back-tracking (e.g. fix-it messages)
|
||||
lastAcceptedProblemMarker.put(markerInfo.file, markerInfo);
|
||||
return true;
|
||||
}
|
||||
List<ProblemMarkerFilterDesc> enabledFilters = findEnabledFilters(project);
|
||||
for (ProblemMarkerFilterDesc filterDesc: enabledFilters) {
|
||||
if ( ! filterDesc.getFilter().acceptMarker(markerInfo) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// store last marker for a file for back-tracking (e.g. fix-it messages)
|
||||
lastAcceptedProblemMarker.put(markerInfo.file, markerInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat Inc. - initial API
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.errorparsers;
|
||||
|
||||
public class Fixit {
|
||||
|
||||
private String change;
|
||||
private int lineNumber;
|
||||
private int columnNumber;
|
||||
private int length;
|
||||
|
||||
public Fixit(String range, String change) {
|
||||
this.change = change;
|
||||
parseRange(range);
|
||||
}
|
||||
|
||||
private void parseRange(String range) {
|
||||
String[] region = range.split("-"); //$NON-NLS-1$
|
||||
String start = region[0];
|
||||
String[] token = start.split(":"); //$NON-NLS-1$
|
||||
this.lineNumber = Integer.valueOf(token[0]).intValue();
|
||||
this.columnNumber = Integer.valueOf(token[1]).intValue();
|
||||
String end = region[1];
|
||||
token = end.split(":"); //$NON-NLS-1$
|
||||
int endColumnNumber = Integer.valueOf(token[1]).intValue();
|
||||
this.length = endColumnNumber - columnNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line number.
|
||||
*
|
||||
* @return 1-based line number of fix-it
|
||||
*/
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column number.
|
||||
*
|
||||
* @return 1-based column number of fix-it
|
||||
*/
|
||||
public int getColumnNumber() {
|
||||
return columnNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get length.
|
||||
*
|
||||
* @return length of change for fix-it
|
||||
*/
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the change string.
|
||||
* @return the string to change the region to (can be empty).
|
||||
*/
|
||||
public String getChange() {
|
||||
return change;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Red Hat Inc. - initial API
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.errorparsers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||
import org.eclipse.core.resources.IResourceChangeListener;
|
||||
import org.eclipse.core.resources.IResourceDelta;
|
||||
import org.eclipse.core.resources.IResourceDeltaVisitor;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public class FixitManager implements IResourceChangeListener {
|
||||
|
||||
private static FixitManager instance;
|
||||
|
||||
private Map<IMarker, Fixit> fixitMap = new HashMap<>();
|
||||
private Map<IResource, Set<IMarker>> fixitResourceMap = new HashMap<>();
|
||||
|
||||
private FixitManager() {
|
||||
// add resource change listener so we can remove any stored
|
||||
// markers if the resource is removed.
|
||||
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
|
||||
}
|
||||
|
||||
public static FixitManager getInstance() {
|
||||
if (instance == null)
|
||||
instance = new FixitManager();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void addMarker(IMarker marker, String range, String value) {
|
||||
Fixit f = new Fixit(range, value);
|
||||
fixitMap.put(marker, f);
|
||||
IResource r = marker.getResource();
|
||||
// register marker for resource
|
||||
Set<IMarker> markerSet = fixitResourceMap.get(r);
|
||||
// create marker set if one doesn't yet exist
|
||||
if (markerSet == null) {
|
||||
markerSet = new HashSet<>();
|
||||
fixitResourceMap.put(r, markerSet);
|
||||
}
|
||||
markerSet.add(marker);
|
||||
}
|
||||
|
||||
public void deleteMarker(IMarker marker) {
|
||||
fixitMap.remove(marker);
|
||||
IResource r = marker.getResource();
|
||||
Set<IMarker> markerSet = fixitResourceMap.get(r);
|
||||
// remove marker from registered markers for resource
|
||||
if (markerSet != null) {
|
||||
markerSet.remove(marker);
|
||||
// remove whole marker set if empty
|
||||
if (markerSet.isEmpty()) {
|
||||
fixitResourceMap.remove(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteMarkers(IMarker[] markers) {
|
||||
for (IMarker marker : markers) {
|
||||
deleteMarker(marker);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasFixit(IMarker marker) {
|
||||
return fixitMap.containsKey(marker);
|
||||
}
|
||||
|
||||
public Fixit findFixit(IMarker marker) {
|
||||
return fixitMap.get(marker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resourceChanged(IResourceChangeEvent event) {
|
||||
try {
|
||||
// look for resource removals that remove a resource we have
|
||||
// saved a marker for
|
||||
if (event.getType() == IResourceChangeEvent.POST_CHANGE){
|
||||
event.getDelta().accept(new IResourceDeltaVisitor(){
|
||||
@Override
|
||||
public boolean visit(IResourceDelta delta) throws CoreException {
|
||||
// we only care about removal of an IResource we have registered
|
||||
if (delta.getKind() == IResourceDelta.REMOVED) {
|
||||
Set<IMarker> markerSet = fixitResourceMap.get(delta.getResource());
|
||||
if (markerSet != null) {
|
||||
for (IMarker marker : markerSet) {
|
||||
deleteMarker(marker);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e); // should not happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -546,7 +546,7 @@ public class CDocumentProvider extends TextFileDocumentProvider {
|
|||
private void setOverlay(Object value, ProblemAnnotation problemAnnotation) {
|
||||
if (value instanceof CMarkerAnnotation) {
|
||||
CMarkerAnnotation annotation= (CMarkerAnnotation) value;
|
||||
if (annotation.isProblem()) {
|
||||
if (annotation.isProblem() && !annotation.isQuickFixable()) {
|
||||
annotation.setOverlay(problemAnnotation);
|
||||
fPreviouslyOverlaid.remove(annotation);
|
||||
fCurrentlyOverlaid.add(annotation);
|
||||
|
|
Loading…
Add table
Reference in a new issue