mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Bug 317538: added framework to store arguments in a marker (add added intermediate object between reporter and marker)
This commit is contained in:
parent
c5a58d72a1
commit
3d0baee8fb
9 changed files with 336 additions and 63 deletions
|
@ -11,6 +11,8 @@
|
|||
package org.eclipse.cdt.codan.core.internal.checkers;
|
||||
|
||||
import org.eclipse.cdt.codan.core.test.CheckerTestCase;
|
||||
import org.eclipse.cdt.codan.internal.core.model.CodanProblemMarker;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
|
||||
/**
|
||||
* Test for {@see SuggestedParenthesisChecker} class
|
||||
|
@ -82,4 +84,15 @@ public class AssignmentInConditionCheckerTest extends CheckerTestCase {
|
|||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLine(3);
|
||||
}
|
||||
|
||||
// main() {
|
||||
// int a=1,b=3;
|
||||
// if (a=b) b=4; // error here on line 3
|
||||
// }
|
||||
public void test_basic_params() {
|
||||
loadCodeAndRun(getAboveComment());
|
||||
IMarker marker = checkErrorLine(3);
|
||||
String arg = CodanProblemMarker.getProblemArgument(marker, 0);
|
||||
assertEquals("a=b", arg); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@
|
|||
<persistent
|
||||
value="true">
|
||||
</persistent>
|
||||
<attribute
|
||||
name="args">
|
||||
</attribute>
|
||||
</extension>
|
||||
|
||||
<extension
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009,2010 QNX Software Systems
|
||||
* 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:
|
||||
* QNX Software Systems (Alena Laskavaia) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.model;
|
||||
|
||||
import org.eclipse.cdt.codan.internal.core.CheckersRegistry;
|
||||
import org.eclipse.cdt.codan.internal.core.model.CodanProblemMarker;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
|
||||
/**
|
||||
* Abstract implementation of a IProblemReporter
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public abstract class AbstractProblemReporter implements IProblemReporter {
|
||||
public void reportProblem(String id, IProblemLocation loc, Object... args) {
|
||||
IResource file = loc.getFile();
|
||||
if (file == null)
|
||||
throw new NullPointerException("file"); //$NON-NLS-1$
|
||||
if (id == null)
|
||||
throw new NullPointerException("id"); //$NON-NLS-1$
|
||||
IProblem problem = CheckersRegistry.getInstance()
|
||||
.getResourceProfile(file).findProblem(id);
|
||||
if (problem == null)
|
||||
throw new IllegalArgumentException("Id is not registered:" + id); //$NON-NLS-1$
|
||||
if (problem.isEnabled() == false)
|
||||
return; // skip
|
||||
ICodanProblemMarker codanProblemMarker = new CodanProblemMarker(
|
||||
problem, loc, args);
|
||||
reportProblem(codanProblemMarker);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param codanProblemMarker
|
||||
*/
|
||||
protected abstract void reportProblem(ICodanProblemMarker codanProblemMarker);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009,2010 QNX Software Systems
|
||||
* 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:
|
||||
* QNX Software Systems (Alena Laskavaia) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.model;
|
||||
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Instance of a problem. Intermediate representation before problem become a
|
||||
* marker.
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public interface ICodanProblemMarker {
|
||||
/**
|
||||
* @return problem location
|
||||
*/
|
||||
public IProblemLocation getLocation();
|
||||
|
||||
/**
|
||||
* Returns problem of which type this instance is created
|
||||
*
|
||||
* @return problem
|
||||
*/
|
||||
public IProblem getProblem();
|
||||
|
||||
/**
|
||||
* Resource on which this problem instance is created
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public IResource getResource();
|
||||
|
||||
/**
|
||||
* Creates a maker on a resource represented by location, which attributes
|
||||
* that this instance carries
|
||||
*
|
||||
* @return marker
|
||||
* @throws CoreException
|
||||
*/
|
||||
public IMarker createMarker() throws CoreException;
|
||||
|
||||
/**
|
||||
* Create a message by applying messagePattern from a problem to a problem
|
||||
* arguments
|
||||
*
|
||||
* @return message
|
||||
*/
|
||||
public String createMessage();
|
||||
}
|
|
@ -11,7 +11,9 @@
|
|||
package org.eclipse.cdt.codan.core.model;
|
||||
|
||||
/**
|
||||
* IProblemReporter - interface to report problems
|
||||
* IProblemReporter - interface to report problems.
|
||||
*
|
||||
* It is recommented to extend {@link AbstractProblemReporter} instead
|
||||
*
|
||||
* <p>
|
||||
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
|
||||
|
@ -33,7 +35,7 @@ public interface IProblemReporter {
|
|||
* @param loc - location object, can be created using
|
||||
* getRuntime().getProblemLocationFactory().createProblemLocation
|
||||
* methods
|
||||
* @param args - custom arguments, can be null, in this case default message
|
||||
* @param args - custom arguments, can be none, in this case default message
|
||||
* is reported
|
||||
*/
|
||||
public void reportProblem(String problemId, IProblemLocation loc,
|
||||
|
|
|
@ -15,7 +15,8 @@ import java.util.Collection;
|
|||
|
||||
import org.eclipse.cdt.codan.core.CodanRuntime;
|
||||
import org.eclipse.cdt.codan.core.Messages;
|
||||
import org.eclipse.cdt.codan.internal.core.model.CodanMarkerProblemReporter;
|
||||
import org.eclipse.cdt.codan.core.model.AbstractProblemReporter;
|
||||
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
|
@ -46,13 +47,13 @@ public class CodanApplication implements IApplication {
|
|||
extractArguments(args);
|
||||
CodanBuilder codanBuilder = new CodanBuilder();
|
||||
CodanRuntime runtime = CodanRuntime.getInstance();
|
||||
runtime.setProblemReporter(new CodanMarkerProblemReporter() {
|
||||
runtime.setProblemReporter(new AbstractProblemReporter() {
|
||||
@Override
|
||||
public void reportProblem(String id, String markerType,
|
||||
int severity, IResource file, int lineNumber,
|
||||
int startChar, int endChar, String message) {
|
||||
System.out.println(file.getLocation() + ":" + lineNumber + ": " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ message);
|
||||
protected void reportProblem(ICodanProblemMarker pm) {
|
||||
IResource file = pm.getResource();
|
||||
System.out.println(file.getLocation()
|
||||
+ ":" + pm.getLocation().getLineNumber() + ": " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ pm.createMessage());
|
||||
}
|
||||
});
|
||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||
|
|
|
@ -10,18 +10,17 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.internal.core.model;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.cdt.codan.core.CodanCorePlugin;
|
||||
import org.eclipse.cdt.codan.core.CodanRuntime;
|
||||
import org.eclipse.cdt.codan.core.model.AbstractProblemReporter;
|
||||
import org.eclipse.cdt.codan.core.model.IChecker;
|
||||
import org.eclipse.cdt.codan.core.model.ICheckersRegistry;
|
||||
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
|
||||
import org.eclipse.cdt.codan.core.model.IProblem;
|
||||
import org.eclipse.cdt.codan.core.model.IProblemLocation;
|
||||
import org.eclipse.cdt.codan.core.model.IProblemReporterPersistent;
|
||||
import org.eclipse.cdt.codan.internal.core.CheckersRegistry;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
|
@ -33,76 +32,44 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
/**
|
||||
* Problem reported that created eclipse markers
|
||||
*/
|
||||
public class CodanMarkerProblemReporter implements IProblemReporterPersistent {
|
||||
public void reportProblem(String id, IProblemLocation loc, Object... args) {
|
||||
IResource file = loc.getFile();
|
||||
int lineNumber = loc.getLineNumber();
|
||||
if (file == null)
|
||||
throw new NullPointerException("file"); //$NON-NLS-1$
|
||||
if (id == null)
|
||||
throw new NullPointerException("id"); //$NON-NLS-1$
|
||||
IProblem problem = CheckersRegistry.getInstance()
|
||||
.getResourceProfile(file).findProblem(id);
|
||||
if (problem == null)
|
||||
throw new IllegalArgumentException("Id is not registered:" + id); //$NON-NLS-1$
|
||||
if (problem.isEnabled() == false)
|
||||
return; // skip
|
||||
int severity = problem.getSeverity().intValue();
|
||||
String messagePattern = problem.getMessagePattern();
|
||||
String message = id;
|
||||
if (messagePattern == null) {
|
||||
if (args != null && args.length > 0 && args[0] instanceof String)
|
||||
message = (String) args[0];
|
||||
} else {
|
||||
message = MessageFormat.format(messagePattern, args);
|
||||
}
|
||||
reportProblem(id, problem.getMarkerType(), severity, file, lineNumber,
|
||||
loc.getStartingChar(), loc.getEndingChar(), message);
|
||||
public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
||||
implements IProblemReporterPersistent {
|
||||
@Override
|
||||
protected void reportProblem(ICodanProblemMarker codanProblemMarker) {
|
||||
createProblem(codanProblemMarker);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id - problem id
|
||||
* @param markerType - marker id
|
||||
* @param severity - marker severity
|
||||
* @param file - resource
|
||||
* @param lineNumber - line number for error
|
||||
* @param startChar - start char (offset in charts from the begging of the
|
||||
* document)
|
||||
* @param endChar - end char (offset in charts from the begging of the
|
||||
* document, exclusive)
|
||||
* @param message - marker message
|
||||
* @param codanProblemMarker
|
||||
*/
|
||||
public void reportProblem(String id, String markerType, int severity,
|
||||
IResource file, int lineNumber, int startChar, int endChar,
|
||||
String message) {
|
||||
protected IMarker createProblem(ICodanProblemMarker codanProblemMarker) {
|
||||
try {
|
||||
// Do not put in duplicates
|
||||
IMarker[] cur = file.findMarkers(markerType, false,
|
||||
IMarker[] cur = codanProblemMarker.getResource().findMarkers(
|
||||
codanProblemMarker.getProblem().getMarkerType(), false,
|
||||
IResource.DEPTH_ZERO);
|
||||
if (cur != null) {
|
||||
String message = codanProblemMarker.createMessage();
|
||||
for (IMarker element : cur) {
|
||||
int line = ((Integer) element
|
||||
.getAttribute(IMarker.LINE_NUMBER)).intValue();
|
||||
if (line == lineNumber) {
|
||||
if (line == codanProblemMarker.getLocation()
|
||||
.getLineNumber()) {
|
||||
String mesg = (String) element
|
||||
.getAttribute(IMarker.MESSAGE);
|
||||
int sev = ((Integer) element
|
||||
.getAttribute(IMarker.SEVERITY)).intValue();
|
||||
if (sev == severity && mesg.equals(message))
|
||||
return;
|
||||
if (sev == codanProblemMarker.getProblem()
|
||||
.getSeverity().intValue()
|
||||
&& mesg.equals(message))
|
||||
return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
IMarker marker = file.createMarker(markerType);
|
||||
marker.setAttribute(IMarker.MESSAGE, message);
|
||||
marker.setAttribute(IMarker.SEVERITY, severity);
|
||||
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
|
||||
marker.setAttribute(IMarker.PROBLEM, id);
|
||||
marker.setAttribute(IMarker.CHAR_END, endChar);
|
||||
marker.setAttribute(IMarker.CHAR_START, startChar);
|
||||
marker.setAttribute("org.eclipse.cdt.core.problem", 42); //$NON-NLS-1$
|
||||
return codanProblemMarker.createMarker();
|
||||
} catch (CoreException e) {
|
||||
e.printStackTrace();
|
||||
CodanCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009,2010 QNX Software Systems
|
||||
* 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:
|
||||
* QNX Software Systems (Alena Laskavaia) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.internal.core.model;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.cdt.codan.core.model.ICodanProblemMarker;
|
||||
import org.eclipse.cdt.codan.core.model.IProblem;
|
||||
import org.eclipse.cdt.codan.core.model.IProblemLocation;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
* Instance of a problem. Intermediate representation before problem become a
|
||||
* marker
|
||||
*
|
||||
* @since 1.1
|
||||
*/
|
||||
public class CodanProblemMarker implements ICodanProblemMarker {
|
||||
private static final String PROBLEM_ARGS = "args"; //$NON-NLS-1$
|
||||
private IProblemLocation loc;
|
||||
private IProblem problem;
|
||||
private Object args[];
|
||||
|
||||
/**
|
||||
* @param problem
|
||||
* @param loc
|
||||
* @param args
|
||||
*/
|
||||
public CodanProblemMarker(IProblem problem, IProblemLocation loc,
|
||||
Object[] args) {
|
||||
this.problem = problem;
|
||||
this.loc = loc;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.ICodanProblemMarker#getLocation()
|
||||
*/
|
||||
public IProblemLocation getLocation() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.ICodanProblemMarker#getProblem()
|
||||
*/
|
||||
public IProblem getProblem() {
|
||||
return problem;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.ICodanProblemMarker#getResource()
|
||||
*/
|
||||
public IResource getResource() {
|
||||
return loc.getFile();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.ICodanProblemMarker#createMarker()
|
||||
*/
|
||||
public IMarker createMarker() throws CoreException {
|
||||
IResource file = loc.getFile();
|
||||
int lineNumber = loc.getLineNumber();
|
||||
int severity = problem.getSeverity().intValue();
|
||||
String message = createMessage();
|
||||
IMarker marker = file.createMarker(problem.getMarkerType());
|
||||
marker.setAttribute(IMarker.MESSAGE, message);
|
||||
marker.setAttribute(IMarker.SEVERITY, severity);
|
||||
marker.setAttribute(IMarker.LINE_NUMBER, lineNumber);
|
||||
marker.setAttribute(IMarker.PROBLEM, problem.getId());
|
||||
marker.setAttribute(IMarker.CHAR_END, loc.getEndingChar());
|
||||
marker.setAttribute(IMarker.CHAR_START, loc.getStartingChar());
|
||||
marker.setAttribute("org.eclipse.cdt.core.problem", 42); //$NON-NLS-1$
|
||||
String propArgs = serializeArgs(args);
|
||||
marker.setAttribute(PROBLEM_ARGS, propArgs);
|
||||
return marker;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.ICodanProblemMarker#createMessage()
|
||||
*/
|
||||
public String createMessage() {
|
||||
String messagePattern = problem.getMessagePattern();
|
||||
String message = problem.getId();
|
||||
if (messagePattern == null) {
|
||||
if (args != null && args.length > 0 && args[0] instanceof String)
|
||||
message = (String) args[0];
|
||||
} else {
|
||||
message = MessageFormat.format(messagePattern, args);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param args2
|
||||
* @return
|
||||
*/
|
||||
private String serializeArgs(Object[] args) {
|
||||
if (args != null) {
|
||||
Properties prop = new Properties();
|
||||
prop.put("len", String.valueOf(args.length)); //$NON-NLS-1$
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
Object object = args[i];
|
||||
if (object != null)
|
||||
prop.put("a" + i, object.toString()); //$NON-NLS-1$
|
||||
}
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
try {
|
||||
prop.store(bout, null);
|
||||
} catch (IOException e) {
|
||||
// nope
|
||||
}
|
||||
return bout.toString();
|
||||
}
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the argument of a problem that checker passed to "reportProblem"
|
||||
* method
|
||||
*
|
||||
* @param marker - problem marker
|
||||
* @param index - index of the argument 0 based
|
||||
* @return problem argument at index, can be null if not set. Can throw AUBE
|
||||
* if out of bounds.
|
||||
*/
|
||||
public static String getProblemArgument(IMarker marker, int index) {
|
||||
String[] args = getProblemArguments(marker);
|
||||
return args[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the arguments of a problem that checker passed to "reportProblem"
|
||||
* method
|
||||
*
|
||||
* @param marker - problem marker
|
||||
* @return problem arguments, can not be null. Can be 0 sized array.
|
||||
*/
|
||||
public static String[] getProblemArguments(IMarker marker) {
|
||||
String attrs = marker.getAttribute(PROBLEM_ARGS, ""); //$NON-NLS-1$
|
||||
Properties prop = new Properties();
|
||||
ByteArrayInputStream bin = new ByteArrayInputStream(attrs.getBytes());
|
||||
try {
|
||||
prop.load(bin);
|
||||
} catch (IOException e) {
|
||||
// not happening
|
||||
}
|
||||
String len = prop.getProperty("len", "0"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
int length = Integer.valueOf(len);
|
||||
String args[] = new String[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
args[i] = prop.getProperty("a" + i); //$NON-NLS-1$
|
||||
}
|
||||
return args;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.ui;
|
||||
|
||||
import org.eclipse.cdt.codan.internal.core.model.CodanProblemMarker;
|
||||
import org.eclipse.cdt.codan.internal.ui.CodanUIActivator;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
|
@ -54,6 +55,10 @@ public abstract class AbstractCodanCMarkerResolution implements
|
|||
return position;
|
||||
}
|
||||
|
||||
public String getProblemArgument(IMarker marker, int index) {
|
||||
return CodanProblemMarker.getProblemArgument(marker, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs this resolution.
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue