1
0
Fork 0
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:
Alena Laskavaia 2010-06-22 02:15:20 +00:00
parent c5a58d72a1
commit 3d0baee8fb
9 changed files with 336 additions and 63 deletions

View file

@ -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$
}
}

View file

@ -47,6 +47,9 @@
<persistent
value="true">
</persistent>
<attribute
name="args">
</attribute>
</extension>
<extension

View file

@ -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);
}

View file

@ -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();
}

View file

@ -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,

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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.
*