From 3d0baee8fbf7d49e63c4f25be3dbad0de94cb590 Mon Sep 17 00:00:00 2001 From: Alena Laskavaia Date: Tue, 22 Jun 2010 02:15:20 +0000 Subject: [PATCH] Bug 317538: added framework to store arguments in a marker (add added intermediate object between reporter and marker) --- .../AssignmentInConditionCheckerTest.java | 13 ++ codan/org.eclipse.cdt.codan.core/plugin.xml | 3 + .../core/model/AbstractProblemReporter.java | 44 +++++ .../codan/core/model/ICodanProblemMarker.java | 59 ++++++ .../codan/core/model/IProblemReporter.java | 6 +- .../codan/internal/core/CodanApplication.java | 15 +- .../model/CodanMarkerProblemReporter.java | 75 ++------ .../core/model/CodanProblemMarker.java | 179 ++++++++++++++++++ .../ui/AbstractCodanCMarkerResolution.java | 5 + 9 files changed, 336 insertions(+), 63 deletions(-) create mode 100644 codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/AbstractProblemReporter.java create mode 100644 codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/core/model/ICodanProblemMarker.java create mode 100644 codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemMarker.java diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java index 38f750b2d6f..e115373abad 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/AssignmentInConditionCheckerTest.java @@ -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$ + } } diff --git a/codan/org.eclipse.cdt.codan.core/plugin.xml b/codan/org.eclipse.cdt.codan.core/plugin.xml index 1b051a34cf5..65b2f17f9e7 100644 --- a/codan/org.eclipse.cdt.codan.core/plugin.xml +++ b/codan/org.eclipse.cdt.codan.core/plugin.xml @@ -47,6 +47,9 @@ + + * EXPERIMENTAL. 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, diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java index 188be3c1d52..29d876aef7c 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/CodanApplication.java @@ -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(); diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java index f692a9baf7a..91f8bbccc6d 100644 --- a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanMarkerProblemReporter.java @@ -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; } } diff --git a/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemMarker.java b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemMarker.java new file mode 100644 index 00000000000..262f2a89a22 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.core/src/org/eclipse/cdt/codan/internal/core/model/CodanProblemMarker.java @@ -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; + } +} diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/AbstractCodanCMarkerResolution.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/AbstractCodanCMarkerResolution.java index 3e95cb97af3..540dab6b3ed 100644 --- a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/AbstractCodanCMarkerResolution.java +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/ui/AbstractCodanCMarkerResolution.java @@ -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. *