1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 22:22:11 +02:00

support for checkers with paramerers

This commit is contained in:
Alena Laskavaia 2010-02-19 02:29:18 +00:00
parent 8907380c2c
commit f67d273034
13 changed files with 375 additions and 34 deletions

View file

@ -49,8 +49,11 @@
<category
id="org.eclipse.cdt.codan.core.categories.ProgrammingProblems"
name="Potential programming problems"
/>
<category
id="org.eclipse.cdt.codan.core.categories.CodeStyle"
name="Coding Style"
>
</category>
</extension>

View file

@ -60,6 +60,7 @@
<sequence minOccurs="0" maxOccurs="unbounded">
<choice>
<element ref="problem"/>
<element ref="problemRef"/>
</choice>
</sequence>
<attribute name="id" type="string" use="required">
@ -143,6 +144,13 @@
</appinfo>
</annotation>
</attribute>
<attribute name="defaultEnabled" type="boolean" use="default" value="true">
<annotation>
<documentation>
If problem is enabled in original profile. Default is true.
</documentation>
</annotation>
</attribute>
</complexType>
</element>
@ -178,6 +186,21 @@
</complexType>
</element>
<element name="problemRef">
<complexType>
<attribute name="problem" type="string" use="required">
<annotation>
<documentation>
Reference to a problem
</documentation>
<appinfo>
<meta.attribute kind="identifier" basedOn="org.eclipse.cdt.codan.core.checkers/checker/problem/@id"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appinfo>
<meta.section type="since"/>

View file

@ -0,0 +1,76 @@
/*******************************************************************************
* Copyright (c) 2009 Alena Laskavaia
* 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:
* Alena Laskavaia - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.core.model;
import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
/**
* Checker that works with C-Index of a file (but not AST)
*
*/
public abstract class AbstractCIndexChecker extends AbstractChecker implements
ICIndexChecker {
private IFile file;
protected IIndex index;
protected IFile getFile() {
return file;
}
void processFile(IFile file) throws CoreException, InterruptedException {
// create translation unit and access index
ICElement model = CoreModel.getDefault().create(file);
if (!(model instanceof ITranslationUnit))
return;
ITranslationUnit tu = (ITranslationUnit) model;
if (tu == null)
return; // not a C/C++ file
index = CCorePlugin.getIndexManager().getIndex(tu.getCProject());
// lock the index for read access
index.acquireReadLock();
try {
// traverse the translation unit using the visitor pattern.
this.file = file;
processUnit(tu);
} finally {
this.file = null;
index.releaseReadLock();
}
}
public boolean processResource(IResource resource) {
if (resource instanceof IFile) {
IFile file = (IFile) resource;
try {
processFile(file);
} catch (CoreException e) {
CodanCorePlugin.log(e);
} catch (InterruptedException e) {
// ignore
}
return false;
}
return true;
}
@Override
public boolean runInEditor() {
return true;
}
}

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.codan.core.model;
import org.eclipse.cdt.codan.core.CodanRuntime;
import org.eclipse.cdt.codan.internal.core.CheckersRegisry;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
@ -47,6 +48,14 @@ public abstract class AbstractChecker implements IChecker {
new ProblemLocation(file, lineNumber), arg);
}
public IProblem getProblemById(String id, IFile file) {
IProblem problem = CheckersRegisry.getInstance().getResourceProfile(
file).findProblem(id);
if (problem == null)
throw new IllegalArgumentException("Id is not registered");
return problem;
}
/**
* Reports a simple problem for given file and line, error message comes
* from problem definition

View file

@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2009 Alena Laskavaia
* 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:
* Alena Laskavaia - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.core.model;
import org.eclipse.cdt.core.model.ITranslationUnit;
/**
* @author Alena
*
*/
public interface ICIndexChecker extends IChecker {
void processUnit(ITranslationUnit unit);
}

View file

@ -0,0 +1,19 @@
/*******************************************************************************
* Copyright (c) 2009 Alena Laskavaia
* 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:
* Alena Laskavaia - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.core.model;
/**
* @author Alena
*
*/
public interface ICheckerWithParameters {
void initParameters(IProblemWorkingCopy problem);
}

View file

@ -10,11 +10,10 @@
*******************************************************************************/
package org.eclipse.cdt.codan.core.model;
import java.util.Collection;
/**
* Interface representing code analysis problem
*
*
*/
public interface IProblem extends IProblemElement {
/**
@ -23,43 +22,41 @@ public interface IProblem extends IProblemElement {
String getName();
/**
* Unique problem id. Should be qualified by plugin name to maintain uniqueness.
* Unique problem id. Should be qualified by plugin name to maintain
* uniqueness.
*
* @return
*/
String getId();
/**
* Is enabled in current context (usually within profile)
*
* @return true if enabled
*/
boolean isEnabled();
/**
* Get current severity
*
* @return severity
*/
CodanSeverity getSeverity();
/**
* Message pattern, java patter like 'Variable {0} is never used here'
* @return pattern
*
* @return pattern
*/
String getMessagePattern();
void setSeverity(CodanSeverity sev);
void setEnabled(boolean checked);
void setMessagePattern(String message);
public void setProperty(Object key, Object value);
public Object getParameter(Object key);
/**
* Get custom property
* @param property name
* @return property object
* Get root paramterInfo - contains description of types of all the
* parameters or null if not defined
*
* @return
*/
public Object getProperty(Object key);
public Collection<Object> getPropertyKeys();
public IProblemParameterInfo getParameterInfo();
}

View file

@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright (c) 2009 Alena Laskavaia
* 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:
* Alena Laskavaia - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.core.model;
/**
* Problem parameter usually key=value settings that allow to alter checker
* behaviour for given problem. For example if checker finds violation of naming
* conventions for function, parameter would be the pattern of allowed names.
* ProblemParameterInfo represent parameter meta-info for the ui.
* If more that one parameter required ParameterInfo should describe hash or array of parameters.
* This is only needed for auto-generated ui for parameter editing. For complex case custom ui control should be used
*
* @author Alena
*
*/
public interface IProblemParameterInfo {
String getKey();
/**
* type of the parameter, supports boolean, integer, string, file and list.
* If list is the value - it is an array - subparameter can be accessed by number, if
* hash is the value - it is a hash - subparameter can be accesses by name
*
* @return string value of the type
*/
String getType();
/**
* Additional info on how it is represented in the ui, for example boolean
* can be represented as checkbox, drop-down and so on, Values TBD
*
* @return ui info or null if not set
*/
String getUiInfo();
/**
* User visible label for the control in UI
*/
String getLabel();
/**
* Available if type is list or hash. Returns value of subparamer with the
* name of key. For the "list" key must be "#".
*
* @param key
* - name of the subparameter.
* @return
*/
IProblemParameterInfo getElement(String key);
}

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2009 Alena Laskavaia
* 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:
* Alena Laskavaia - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.codan.core.model;
/**
* Modifiable problem
* @author Alena
*
*/
public interface IProblemWorkingCopy extends IProblem {
void setSeverity(CodanSeverity sev);
void setEnabled(boolean checked);
void setMessagePattern(String message);
public void setParameter(Object key, Object value);
public IProblemCategory getCategory();
public void setParameterInfo(IProblemParameterInfo info);
}

View file

@ -18,10 +18,12 @@ import java.util.Iterator;
import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.codan.core.PreferenceConstants;
import org.eclipse.cdt.codan.core.model.IChecker;
import org.eclipse.cdt.codan.core.model.ICheckerWithParameters;
import org.eclipse.cdt.codan.core.model.ICheckersRegistry;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemCategory;
import org.eclipse.cdt.codan.core.model.IProblemProfile;
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
import org.eclipse.cdt.codan.internal.core.model.CodanProblem;
import org.eclipse.cdt.codan.internal.core.model.CodanProblemCategory;
import org.eclipse.cdt.codan.internal.core.model.ProblemProfile;
@ -73,6 +75,21 @@ public class CheckersRegisry implements Iterable<IChecker>, ICheckersRegistry {
IConfigurationElement configurationElement = elements[i];
processChecker(configurationElement);
}
// init parameters for checkers with parameters
for (Iterator iterator = problemList.keySet().iterator(); iterator
.hasNext();) {
IChecker c = (IChecker) iterator.next();
if (c instanceof ICheckerWithParameters) {
Collection<IProblem> list = problemList.get(c);
for (Iterator iterator2 = list.iterator(); iterator2.hasNext();) {
IProblem p = (IProblem) iterator2.next();
if (p instanceof IProblemWorkingCopy) {
((ICheckerWithParameters) c)
.initParameters((IProblemWorkingCopy) p);
}
}
}
}
}
/**
@ -256,9 +273,10 @@ public class CheckersRegisry implements Iterable<IChecker>, ICheckersRegistry {
}
plist.add(p);
}
/**
* Returns list of problems registered for given checker
*
* @return collection of problems or null
*/
public Collection<IProblem> getRefProblems(IChecker checker) {

View file

@ -10,20 +10,20 @@
*******************************************************************************/
package org.eclipse.cdt.codan.internal.core.model;
import java.util.Collection;
import java.util.HashMap;
import org.eclipse.cdt.codan.core.model.CodanSeverity;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemCategory;
import org.eclipse.cdt.codan.core.model.IProblemParameterInfo;
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
public class CodanProblem implements IProblem {
public class CodanProblem implements IProblemWorkingCopy {
private String id;
private String name;
private String message;
private CodanSeverity severity = CodanSeverity.Warning;
private boolean enabled = true;
private HashMap<Object, Object> properties = new HashMap<Object, Object>(0);
private HashMap<Object, Object> parameters = new HashMap<Object, Object>(0);
private IProblemParameterInfo parameterInfo;
public CodanSeverity getSeverity() {
return severity;
@ -76,16 +76,20 @@ public class CodanProblem implements IProblem {
return super.clone();
}
public void setProperty(Object key, Object value) {
properties.put(key, value);
public void setParameter(Object key, Object value) {
parameters.put(key, value);
}
public Object getProperty(Object key) {
return properties.get(key);
public void setParameterInfo(IProblemParameterInfo info) {
parameterInfo = info;
}
public Object getParameter(Object key) {
return parameters.get(key);
};
public Collection<Object> getPropertyKeys() {
return properties.keySet();
public IProblemParameterInfo getParameterInfo() {
return parameterInfo;
}
/*
@ -98,7 +102,8 @@ public class CodanProblem implements IProblem {
}
/**
* @param message the message to set
* @param message
* the message to set
*/
public void setMessagePattern(String message) {
this.message = message;

View file

@ -13,9 +13,21 @@ package org.eclipse.cdt.codan.internal.ui.preferences;
import org.eclipse.cdt.codan.core.CodanCorePlugin;
import org.eclipse.cdt.codan.core.CodanRuntime;
import org.eclipse.cdt.codan.core.model.ICheckersRegistry;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemProfile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
@ -33,14 +45,31 @@ import org.eclipse.ui.preferences.ScopedPreferenceStore;
public class CodanPreferencePage extends FieldEditorOverlayPage implements
IWorkbenchPreferencePage {
private IProblemProfile profile;
private Composite parametersComposite;
private ISelectionChangedListener problemSelectionListener;
public CodanPreferencePage() {
super(GRID);
setPreferenceStore(new ScopedPreferenceStore(new InstanceScope(),
CodanCorePlugin.PLUGIN_ID));
setDescription("Code Analyzers Preference Page");
problemSelectionListener = new ISelectionChangedListener(){
public void selectionChanged(SelectionChangedEvent event) {
if (parametersComposite!=null ) {
if (event.getSelection() instanceof ITreeSelection) {
ITreeSelection s = (ITreeSelection) event.getSelection();
if (s.getFirstElement() instanceof IProblem)
setSelectedProblem((IProblem) s.getFirstElement());
}
}
}
};
}
protected String getPageId() {
return "org.eclipse.cdt.codan.internal.ui.preferences.CodanPreferencePage";
}
@ -57,8 +86,59 @@ public class CodanPreferencePage extends FieldEditorOverlayPage implements
CheckedTreeEditor checkedTreeEditor = new ProblemsTreeEditor(
getFieldEditorParent(), profile);
addField(checkedTreeEditor);
final TabFolder tabFolder = new TabFolder(getFieldEditorParent(),
SWT.TOP);
tabFolder.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
// createMainTab(tabFolder);
createParamtersTab(tabFolder);
createScopeTab(tabFolder);
checkedTreeEditor.getTreeViewer().addSelectionChangedListener(problemSelectionListener);
}
/**
* @param selection
*/
protected void setSelectedProblem(IProblem problem) {
Control[] children = parametersComposite.getChildren();
parametersComposite.setLayout(new GridLayout());
for (int i = 0; i < children.length; i++) {
Control control = children[i];
control.dispose();
}
if (problem.getParameterInfo()==null) {
Label label = new Label(parametersComposite, SWT.NULL);
label.setText("No Parameters");
} else {
Label label = new Label(parametersComposite, SWT.NULL);
label.setText("Parameters: TODO");
}
parametersComposite.pack(true);
parametersComposite.layout(true);
}
/**
* @param tabFolder
*/
private void createParamtersTab(TabFolder tabFolder) {
TabItem tabItem1 = new TabItem(tabFolder, SWT.NULL);
tabItem1.setText("Parameters");
parametersComposite = new Composite(tabFolder, SWT.NONE);
tabItem1.setControl(parametersComposite);
}
/**
* @param tabFolder
*/
private void createScopeTab(TabFolder tabFolder) {
TabItem tabItem1 = new TabItem(tabFolder, SWT.NULL);
tabItem1.setText("Scope");
Composite comp = new Composite(tabFolder, SWT.NONE);
tabItem1.setControl(comp);
comp.setLayout(new GridLayout());
Label label = new Label(comp, SWT.NONE);
label.setText("Scope: TODO");
label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
}
/**
* @return
*/

View file

@ -15,6 +15,7 @@ import org.eclipse.cdt.codan.core.model.CodanSeverity;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemCategory;
import org.eclipse.cdt.codan.core.model.IProblemProfile;
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
import org.eclipse.cdt.codan.internal.core.CodanPreferencesLoader;
import org.eclipse.jface.viewers.BaseLabelProvider;
import org.eclipse.jface.viewers.CellEditor;
@ -138,8 +139,8 @@ public class ProblemsTreeEditor extends CheckedTreeEditor {
public void checkStateChanged(CheckStateChangedEvent event) {
Object element = event.getElement();
if (element instanceof IProblem) {
((IProblem) element).setEnabled(event.getChecked());
if (element instanceof IProblemWorkingCopy) {
((IProblemWorkingCopy) element).setEnabled(event.getChecked());
}
}
@ -223,7 +224,7 @@ public class ProblemsTreeEditor extends CheckedTreeEditor {
protected void setValue(Object element, Object value) {
int index = ((Integer) value).intValue();
CodanSeverity val = CodanSeverity.values()[index];
((IProblem) element).setSeverity(val);
((IProblemWorkingCopy) element).setSeverity(val);
getTreeViewer().update(element, null);
}
});