mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
auto-format code using project formatter
This commit is contained in:
parent
9164b9a756
commit
598b6fc042
132 changed files with 1117 additions and 1889 deletions
|
@ -19,13 +19,11 @@ import org.osgi.framework.BundleContext;
|
|||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class CheckersUiActivator extends AbstractUIPlugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "org.eclipse.cdt.codan.checkers.ui"; //$NON-NLS-1$
|
||||
|
||||
// The shared instance
|
||||
private static CheckersUiActivator plugin;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
|
@ -34,7 +32,10 @@ public class CheckersUiActivator extends AbstractUIPlugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
|
||||
* )
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
|
@ -43,7 +44,10 @@ public class CheckersUiActivator extends AbstractUIPlugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
|
||||
* )
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
|
@ -52,18 +56,18 @@ public class CheckersUiActivator extends AbstractUIPlugin {
|
|||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static CheckersUiActivator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logs the specified status with this plug-in's log.
|
||||
*
|
||||
* @param status
|
||||
* status to log
|
||||
* status to log
|
||||
*/
|
||||
public static void log(IStatus status) {
|
||||
getDefault().getLog().log(status);
|
||||
|
@ -73,7 +77,7 @@ public class CheckersUiActivator extends AbstractUIPlugin {
|
|||
* Logs an internal error with the specified throwable
|
||||
*
|
||||
* @param e
|
||||
* the exception to be logged
|
||||
* the exception to be logged
|
||||
*/
|
||||
public static void log(Throwable e) {
|
||||
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, "Internal Error", e)); //$NON-NLS-1$
|
||||
|
@ -83,10 +87,9 @@ public class CheckersUiActivator extends AbstractUIPlugin {
|
|||
* Logs an internal error with the specified message.
|
||||
*
|
||||
* @param message
|
||||
* the error message to log
|
||||
* the error message to log
|
||||
*/
|
||||
public static void log(String message) {
|
||||
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, message, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@ import org.eclipse.jface.text.FindReplaceDocumentAdapter;
|
|||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
|
||||
public abstract class AbstractAstRewriteQuickFix extends
|
||||
AbstractCodanCMarkerResolution {
|
||||
public abstract class AbstractAstRewriteQuickFix extends AbstractCodanCMarkerResolution {
|
||||
private IDocument document;
|
||||
|
||||
@Override
|
||||
public void apply(final IMarker marker, IDocument document) {
|
||||
try {
|
||||
|
@ -69,7 +69,7 @@ public abstract class AbstractAstRewriteQuickFix extends
|
|||
public IDocument getDocument() {
|
||||
return document;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param marker
|
||||
* @param ast
|
||||
|
@ -77,8 +77,7 @@ public abstract class AbstractAstRewriteQuickFix extends
|
|||
* @return
|
||||
* @throws BadLocationException
|
||||
*/
|
||||
public IASTName getAstNameFromProblemArgument(IMarker marker,
|
||||
IASTTranslationUnit ast, int argumentIndex) {
|
||||
public IASTName getAstNameFromProblemArgument(IMarker marker, IASTTranslationUnit ast, int argumentIndex) {
|
||||
IASTName astName = null;
|
||||
int pos = getOffset(marker, getDocument());
|
||||
String name = null;
|
||||
|
@ -89,8 +88,7 @@ public abstract class AbstractAstRewriteQuickFix extends
|
|||
}
|
||||
if (name == null)
|
||||
return null;
|
||||
FindReplaceDocumentAdapter dad = new FindReplaceDocumentAdapter(
|
||||
getDocument());
|
||||
FindReplaceDocumentAdapter dad = new FindReplaceDocumentAdapter(getDocument());
|
||||
IRegion region;
|
||||
try {
|
||||
region = dad.find(pos, name,
|
||||
|
@ -99,8 +97,7 @@ public abstract class AbstractAstRewriteQuickFix extends
|
|||
} catch (BadLocationException e) {
|
||||
return null;
|
||||
}
|
||||
astName = getASTNameFromPositions(ast, region.getOffset(),
|
||||
region.getLength());
|
||||
astName = getASTNameFromPositions(ast, region.getOffset(), region.getLength());
|
||||
return astName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,7 @@ public class CatchByReferenceQuickFix extends AbstractCodanCMarkerResolution {
|
|||
}
|
||||
|
||||
public void apply(IMarker marker, IDocument document) {
|
||||
FindReplaceDocumentAdapter dad = new FindReplaceDocumentAdapter(
|
||||
document);
|
||||
FindReplaceDocumentAdapter dad = new FindReplaceDocumentAdapter(document);
|
||||
try {
|
||||
int pos = getOffset(marker, document);
|
||||
dad.find(pos, " ", /* forwardSearch *///$NON-NLS-1$
|
||||
|
|
|
@ -21,19 +21,16 @@ import org.eclipse.jface.text.IDocument;
|
|||
/**
|
||||
* quick fix for assignment in condition
|
||||
*/
|
||||
public class QuickFixAssignmentInCondition extends
|
||||
AbstractCodanCMarkerResolution {
|
||||
public class QuickFixAssignmentInCondition extends AbstractCodanCMarkerResolution {
|
||||
public String getLabel() {
|
||||
return Messages.QuickFixAssignmentInCondition_Message;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void apply(IMarker marker, IDocument document) {
|
||||
int pos = getOffset(marker, document);
|
||||
try {
|
||||
FindReplaceDocumentAdapter dad = new FindReplaceDocumentAdapter(
|
||||
document);
|
||||
FindReplaceDocumentAdapter dad = new FindReplaceDocumentAdapter(document);
|
||||
dad.find(pos, "=", /* forwardSearch *///$NON-NLS-1$
|
||||
true, /* caseSensitive */false,
|
||||
/* wholeWord */false, /* regExSearch */false);
|
||||
|
|
|
@ -39,27 +39,22 @@ public class QuickFixCreateField extends AbstractAstRewriteQuickFix {
|
|||
public void modifyAST(IIndex index, IMarker marker) {
|
||||
CxxAstUtils utils = CxxAstUtils.getInstance();
|
||||
try {
|
||||
IASTTranslationUnit ast = getTranslationUnitViaEditor(marker)
|
||||
.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
|
||||
IASTTranslationUnit ast = getTranslationUnitViaEditor(marker).getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
|
||||
IASTName astName = getASTNameFromMarker(marker, ast);
|
||||
if (astName == null) {
|
||||
return;
|
||||
}
|
||||
IASTDeclaration declaration = utils
|
||||
.createDeclaration(astName, ast.getASTNodeFactory(), index);
|
||||
IASTCompositeTypeSpecifier targetCompositeType = utils
|
||||
.getEnclosingCompositeTypeSpecifier(astName);
|
||||
IASTDeclaration declaration = utils.createDeclaration(astName, ast.getASTNodeFactory(), index);
|
||||
IASTCompositeTypeSpecifier targetCompositeType = utils.getEnclosingCompositeTypeSpecifier(astName);
|
||||
if (targetCompositeType == null) {
|
||||
// We're not in an inline method;
|
||||
// check if we're in a method at all
|
||||
targetCompositeType = utils.getCompositeTypeFromFunction(
|
||||
utils.getEnclosingFunction(astName), index);
|
||||
targetCompositeType = utils.getCompositeTypeFromFunction(utils.getEnclosingFunction(astName), index);
|
||||
if (targetCompositeType == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
ASTRewrite r = ASTRewrite.create(targetCompositeType
|
||||
.getTranslationUnit());
|
||||
ASTRewrite r = ASTRewrite.create(targetCompositeType.getTranslationUnit());
|
||||
IASTNode where = findInsertionPlace(targetCompositeType);
|
||||
r.insertBefore(targetCompositeType, where, declaration, null);
|
||||
Change c = r.rewriteAST();
|
||||
|
@ -69,8 +64,6 @@ public class QuickFixCreateField extends AbstractAstRewriteQuickFix {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Suggests a default place to insert a field:
|
||||
*
|
||||
|
@ -96,8 +89,7 @@ public class QuickFixCreateField extends AbstractAstRewriteQuickFix {
|
|||
// Get initial candidate at the beginning (after class name and
|
||||
// composite type specifiers)
|
||||
for (IASTNode child : children) {
|
||||
if (child instanceof IASTName
|
||||
|| child instanceof ICPPASTBaseSpecifier) {
|
||||
if (child instanceof IASTName || child instanceof ICPPASTBaseSpecifier) {
|
||||
continue;
|
||||
}
|
||||
bestMatch = child;
|
||||
|
@ -109,21 +101,16 @@ public class QuickFixCreateField extends AbstractAstRewriteQuickFix {
|
|||
IASTNode child = children[i];
|
||||
if (child instanceof ICPPASTVisibilityLabel) {
|
||||
ICPPASTVisibilityLabel label = (ICPPASTVisibilityLabel) child;
|
||||
inDesiredAccessibilityContext = (wantPublicContext && label
|
||||
.getVisibility() == ICPPASTVisibilityLabel.v_public)
|
||||
inDesiredAccessibilityContext = (wantPublicContext && label.getVisibility() == ICPPASTVisibilityLabel.v_public)
|
||||
|| (!wantPublicContext && label.getVisibility() == ICPPASTVisibilityLabel.v_private);
|
||||
} else if (inDesiredAccessibilityContext
|
||||
&& (child instanceof IASTDeclaration)
|
||||
&& !(child instanceof IASTFunctionDefinition)) {
|
||||
} else if (inDesiredAccessibilityContext && (child instanceof IASTDeclaration) && !(child instanceof IASTFunctionDefinition)) {
|
||||
// TODO: the above condition needs to also check if child is not
|
||||
// a typedef
|
||||
for (IASTNode gchild : child.getChildren()) {
|
||||
if ((gchild instanceof IASTDeclarator)
|
||||
&& !(gchild instanceof IASTFunctionDeclarator)) {
|
||||
if ((gchild instanceof IASTDeclarator) && !(gchild instanceof IASTFunctionDeclarator)) {
|
||||
// Before the next node or at the end (= after the
|
||||
// current node)
|
||||
bestMatch = (i + 1 < children.length) ? children[i + 1]
|
||||
: null;
|
||||
bestMatch = (i + 1 < children.length) ? children[i + 1] : null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,16 +58,13 @@ public class QuickFixCreateLocalVariable extends AbstractAstRewriteQuickFix {
|
|||
}
|
||||
ASTRewrite r = ASTRewrite.create(ast);
|
||||
INodeFactory factory = ast.getASTNodeFactory();
|
||||
IASTDeclaration declaration = utils.createDeclaration(astName, factory,
|
||||
index);
|
||||
IASTDeclarationStatement newStatement = factory
|
||||
.newDeclarationStatement(declaration);
|
||||
IASTDeclaration declaration = utils.createDeclaration(astName, factory, index);
|
||||
IASTDeclarationStatement newStatement = factory.newDeclarationStatement(declaration);
|
||||
IASTNode targetStatement = utils.getEnclosingStatement(astName);
|
||||
if (targetStatement == null) {
|
||||
return;
|
||||
}
|
||||
r.insertBefore(targetStatement.getParent(), targetStatement,
|
||||
newStatement, null);
|
||||
r.insertBefore(targetStatement.getParent(), targetStatement, newStatement, null);
|
||||
Change c = r.rewriteAST();
|
||||
try {
|
||||
c.perform(new NullProgressMonitor());
|
||||
|
|
|
@ -44,25 +44,19 @@ public class QuickFixCreateParameter extends AbstractAstRewriteQuickFix {
|
|||
@Override
|
||||
public void modifyAST(IIndex index, IMarker marker) {
|
||||
CxxAstUtils utils = CxxAstUtils.getInstance();
|
||||
CompositeChange c = new CompositeChange(
|
||||
Messages.QuickFixCreateParameter_0);
|
||||
CompositeChange c = new CompositeChange(Messages.QuickFixCreateParameter_0);
|
||||
try {
|
||||
ITranslationUnit baseTU = getTranslationUnitViaEditor(marker);
|
||||
IASTTranslationUnit baseAST = baseTU.getAST(index,
|
||||
ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
|
||||
IASTTranslationUnit baseAST = baseTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
|
||||
IASTName astName = getASTNameFromMarker(marker, baseAST);
|
||||
if (astName == null) {
|
||||
return;
|
||||
}
|
||||
IASTDeclaration declaration = CxxAstUtils.getInstance()
|
||||
.createDeclaration(astName, baseAST.getASTNodeFactory(), index);
|
||||
IASTDeclaration declaration = CxxAstUtils.getInstance().createDeclaration(astName, baseAST.getASTNodeFactory(), index);
|
||||
// We'll need a FunctionParameterDeclaration later
|
||||
final IASTDeclSpecifier finalDeclSpec = (IASTDeclSpecifier) declaration
|
||||
.getChildren()[0];
|
||||
final IASTDeclarator finalDeclarator = (IASTDeclarator) declaration
|
||||
.getChildren()[1];
|
||||
IASTFunctionDefinition function = utils
|
||||
.getEnclosingFunction(astName);
|
||||
final IASTDeclSpecifier finalDeclSpec = (IASTDeclSpecifier) declaration.getChildren()[0];
|
||||
final IASTDeclarator finalDeclarator = (IASTDeclarator) declaration.getChildren()[1];
|
||||
IASTFunctionDefinition function = utils.getEnclosingFunction(astName);
|
||||
if (function == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -71,21 +65,18 @@ public class QuickFixCreateParameter extends AbstractAstRewriteQuickFix {
|
|||
function.accept(nameFinderVisitor);
|
||||
IASTName funcName = nameFinderVisitor.name;
|
||||
IBinding binding = funcName.resolveBinding();
|
||||
IIndexName[] declarations = index.findNames(binding,
|
||||
IIndex.FIND_DECLARATIONS_DEFINITIONS);
|
||||
IIndexName[] declarations = index.findNames(binding, IIndex.FIND_DECLARATIONS_DEFINITIONS);
|
||||
if (declarations.length == 0) {
|
||||
return;
|
||||
}
|
||||
HashMap<ITranslationUnit, IASTTranslationUnit> cachedASTs = new HashMap<ITranslationUnit, IASTTranslationUnit>();
|
||||
HashMap<ITranslationUnit, ASTRewrite> cachedRewrites = new HashMap<ITranslationUnit, ASTRewrite>();
|
||||
for (IIndexName iname : declarations) {
|
||||
ITranslationUnit declTU = utils
|
||||
.getTranslationUnitFromIndexName(iname);
|
||||
ITranslationUnit declTU = utils.getTranslationUnitFromIndexName(iname);
|
||||
ASTRewrite rewrite;
|
||||
IASTTranslationUnit declAST;
|
||||
if (!cachedASTs.containsKey(declTU)) {
|
||||
declAST = declTU.getAST(index,
|
||||
ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
|
||||
declAST = declTU.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
|
||||
rewrite = ASTRewrite.create(declAST);
|
||||
cachedASTs.put(declTU, declAST);
|
||||
cachedRewrites.put(declTU, rewrite);
|
||||
|
@ -94,9 +85,8 @@ public class QuickFixCreateParameter extends AbstractAstRewriteQuickFix {
|
|||
rewrite = cachedRewrites.get(declTU);
|
||||
}
|
||||
IASTFileLocation fileLocation = iname.getFileLocation();
|
||||
IASTName declName = declAST.getNodeSelector(null)
|
||||
.findEnclosingName(fileLocation.getNodeOffset(),
|
||||
fileLocation.getNodeLength());
|
||||
IASTName declName = declAST.getNodeSelector(null).findEnclosingName(fileLocation.getNodeOffset(),
|
||||
fileLocation.getNodeLength());
|
||||
if (declName == null) {
|
||||
continue;
|
||||
}
|
||||
|
@ -109,8 +99,7 @@ public class QuickFixCreateParameter extends AbstractAstRewriteQuickFix {
|
|||
}
|
||||
functionDecl = (IASTFunctionDeclarator) n;
|
||||
}
|
||||
IASTParameterDeclaration newParam = factory
|
||||
.newParameterDeclaration(finalDeclSpec, finalDeclarator);
|
||||
IASTParameterDeclaration newParam = factory.newParameterDeclaration(finalDeclSpec, finalDeclarator);
|
||||
rewrite.insertBefore(functionDecl, null, newParam, null);
|
||||
}
|
||||
for (ASTRewrite rewrite : cachedRewrites.values()) {
|
||||
|
|
|
@ -17,8 +17,7 @@ import org.eclipse.core.resources.IMarker;
|
|||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
|
||||
public class SuggestedParenthesisQuickFix extends
|
||||
AbstractCodanCMarkerResolution {
|
||||
public class SuggestedParenthesisQuickFix extends AbstractCodanCMarkerResolution {
|
||||
public String getLabel() {
|
||||
return Messages.SuggestedParenthesisQuickFix_Message;
|
||||
}
|
||||
|
@ -39,7 +38,7 @@ public class SuggestedParenthesisQuickFix extends
|
|||
return;
|
||||
try {
|
||||
document.replace(charStart, 0, "("); //$NON-NLS-1$
|
||||
document.replace(charEnd+1, 0, ")"); //$NON-NLS-1$
|
||||
document.replace(charEnd + 1, 0, ")"); //$NON-NLS-1$
|
||||
} catch (BadLocationException e) {
|
||||
CheckersUiActivator.log(e);
|
||||
}
|
||||
|
|
|
@ -37,8 +37,7 @@ public class AssignmentInConditionChecker extends AbstractIndexAstChecker {
|
|||
}
|
||||
|
||||
public int visit(IASTExpression expression) {
|
||||
if (isAssignmentExpression(expression)
|
||||
&& isUsedAsCondition(expression)) {
|
||||
if (isAssignmentExpression(expression) && isUsedAsCondition(expression)) {
|
||||
reportProblem(ER_ID, expression, expression.getRawSignature());
|
||||
}
|
||||
return PROCESS_CONTINUE;
|
||||
|
@ -54,16 +53,13 @@ public class AssignmentInConditionChecker extends AbstractIndexAstChecker {
|
|||
|
||||
private boolean isUsedAsCondition(IASTExpression expression) {
|
||||
ASTNodeProperty prop = expression.getPropertyInParent();
|
||||
if (prop == IASTForStatement.CONDITION
|
||||
|| prop == IASTIfStatement.CONDITION
|
||||
|| prop == IASTWhileStatement.CONDITIONEXPRESSION
|
||||
if (prop == IASTForStatement.CONDITION || prop == IASTIfStatement.CONDITION || prop == IASTWhileStatement.CONDITIONEXPRESSION
|
||||
|| prop == IASTDoStatement.CONDITION)
|
||||
return true;
|
||||
if (prop == IASTUnaryExpression.OPERAND) {
|
||||
IASTUnaryExpression expr = (IASTUnaryExpression) expression
|
||||
.getParent();
|
||||
if (expr.getOperator() == IASTUnaryExpression.op_bracketedPrimary &&
|
||||
expr.getPropertyInParent() == IASTConditionalExpression.LOGICAL_CONDITION) {
|
||||
IASTUnaryExpression expr = (IASTUnaryExpression) expression.getParent();
|
||||
if (expr.getOperator() == IASTUnaryExpression.op_bracketedPrimary
|
||||
&& expr.getPropertyInParent() == IASTConditionalExpression.LOGICAL_CONDITION) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,16 +22,15 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|||
* a[f()]=a[f()] - but who write codes like that?
|
||||
*/
|
||||
public class AssignmentToItselfChecker extends AbstractIndexAstChecker {
|
||||
|
||||
private static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem"; //$NON-NLS-1$
|
||||
|
||||
|
||||
public void processAst(IASTTranslationUnit ast) {
|
||||
// traverse the ast using the visitor pattern.
|
||||
ast.accept(new ASTVisitor() {
|
||||
{ // constructor
|
||||
shouldVisitExpressions = true;
|
||||
}
|
||||
|
||||
|
||||
// visit expressions
|
||||
public int visit(IASTExpression expression) {
|
||||
if (isAssignmentToItself(expression)) {
|
||||
|
@ -39,7 +38,7 @@ public class AssignmentToItselfChecker extends AbstractIndexAstChecker {
|
|||
}
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
private boolean isAssignmentToItself(IASTExpression e) {
|
||||
if (e instanceof IASTBinaryExpression) {
|
||||
IASTBinaryExpression binExpr = (IASTBinaryExpression) e;
|
||||
|
@ -48,8 +47,8 @@ public class AssignmentToItselfChecker extends AbstractIndexAstChecker {
|
|||
String op2 = binExpr.getOperand2().getRawSignature();
|
||||
String expr = binExpr.getRawSignature();
|
||||
return op1.equals(op2)
|
||||
// when macro is used RawSignature returns macro name, see Bug 321933
|
||||
&& !op1.equals(expr);
|
||||
// when macro is used RawSignature returns macro name, see Bug 321933
|
||||
&& !op1.equals(expr);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -28,8 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
|
||||
public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
||||
ICheckerWithPreferences {
|
||||
public class CaseBreakChecker extends AbstractIndexAstChecker implements ICheckerWithPreferences {
|
||||
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem"; //$NON-NLS-1$
|
||||
public static final String PARAM_LAST_CASE = "last_case_param"; //$NON-NLS-1$
|
||||
public static final String PARAM_EMPTY_CASE = "empty_case_param"; //$NON-NLS-1$
|
||||
|
@ -74,8 +73,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
* @return Is the next comment located after 'node'
|
||||
*/
|
||||
public boolean isNextAfterThis(IASTNode node) {
|
||||
return (_comments[_next].getFileLocation().getNodeOffset() > node
|
||||
.getFileLocation().getNodeOffset());
|
||||
return (_comments[_next].getFileLocation().getNodeOffset() > node.getFileLocation().getNodeOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,8 +81,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
* @return Is the next comment located after 'node' ends
|
||||
*/
|
||||
public boolean isNextAfterThisEnds(IASTNode node) {
|
||||
return (_comments[_next].getFileLocation().getNodeOffset() > node
|
||||
.getFileLocation().getNodeOffset()
|
||||
return (_comments[_next].getFileLocation().getNodeOffset() > node.getFileLocation().getNodeOffset()
|
||||
+ node.getFileLocation().getNodeLength());
|
||||
}
|
||||
|
||||
|
@ -112,8 +109,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
public int visit(IASTStatement statement) {
|
||||
if (statement instanceof IASTSwitchStatement) {
|
||||
// Are we already visiting this statement?
|
||||
if (_switchStatement == null
|
||||
|| !statement.equals(_switchStatement)) {
|
||||
if (_switchStatement == null || !statement.equals(_switchStatement)) {
|
||||
SwitchVisitor switch_visitor = new SwitchVisitor(statement);
|
||||
statement.accept(switch_visitor);
|
||||
return PROCESS_SKIP;
|
||||
|
@ -157,8 +153,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
* @return Was a "break" statement the last statement in this case
|
||||
*/
|
||||
private boolean breakFoundPrevious() {
|
||||
return _prev_normal_stmnt_offset < _prev_break_stmnt_offset
|
||||
&& _prev_case_stmnt_offset < _prev_break_stmnt_offset;
|
||||
return _prev_normal_stmnt_offset < _prev_break_stmnt_offset && _prev_case_stmnt_offset < _prev_break_stmnt_offset;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,8 +193,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
|
||||
@Override
|
||||
public int visit(IASTStatement statement) {
|
||||
if (statement instanceof IASTCaseStatement
|
||||
|| statement instanceof IASTDefaultStatement) {
|
||||
if (statement instanceof IASTCaseStatement || statement instanceof IASTDefaultStatement) {
|
||||
if (_first_case_statement) {
|
||||
/*
|
||||
* This is the first "case", i.e. the beginning of the
|
||||
|
@ -214,8 +208,7 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
*/
|
||||
IASTComment comment = null;
|
||||
// Do we have a comment which is before this "case" statement (but after the previous statement)?
|
||||
while (_commentsIt.hasNext()
|
||||
&& !_commentsIt.isNextAfterThis(statement)) {
|
||||
while (_commentsIt.hasNext() && !_commentsIt.isNextAfterThis(statement)) {
|
||||
comment = _commentsIt.getNext();
|
||||
_commentsIt.advance();
|
||||
}
|
||||
|
@ -226,19 +219,15 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
checkPreviousCase(comment, false);
|
||||
}
|
||||
/* Update variables with the new opened "case" */
|
||||
_prev_case_stmnt_offset = statement.getFileLocation()
|
||||
.getNodeOffset();
|
||||
_prev_case_stmnt_offset = statement.getFileLocation().getNodeOffset();
|
||||
_prev_case_stmnt = statement;
|
||||
} else if (isBreakOrExitStatement(statement)) { // A "break" statement
|
||||
_prev_break_stmnt_offset = statement.getFileLocation()
|
||||
.getNodeOffset();
|
||||
_prev_break_stmnt_offset = statement.getFileLocation().getNodeOffset();
|
||||
} else { // a non-switch related statement
|
||||
_prev_normal_stmnt_offset = statement.getFileLocation()
|
||||
.getNodeOffset();
|
||||
_prev_normal_stmnt_offset = statement.getFileLocation().getNodeOffset();
|
||||
}
|
||||
/* advance comments we already passed */
|
||||
while (_commentsIt.hasNext()
|
||||
&& !_commentsIt.isNextAfterThis(statement))
|
||||
while (_commentsIt.hasNext() && !_commentsIt.isNextAfterThis(statement))
|
||||
_commentsIt.advance();
|
||||
return super.visit(statement); // This would handle nested "switch"s
|
||||
}
|
||||
|
@ -249,12 +238,10 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
* Are we leaving the "switch" altogether? (we need to see how the
|
||||
* last "case" ended)
|
||||
*/
|
||||
if (_checkLastCase && statement instanceof IASTCompoundStatement
|
||||
&& statement.getParent() == _switchStatement) {
|
||||
if (_checkLastCase && statement instanceof IASTCompoundStatement && statement.getParent() == _switchStatement) {
|
||||
IASTComment comment = null;
|
||||
// is "Next" still in the switch's scope? if it is it was after the last statement
|
||||
while (_commentsIt.hasNext()
|
||||
&& !_commentsIt.isNextAfterThisEnds(statement)) {
|
||||
while (_commentsIt.hasNext() && !_commentsIt.isNextAfterThisEnds(statement)) {
|
||||
comment = _commentsIt.getNext();
|
||||
_commentsIt.advance();
|
||||
}
|
||||
|
@ -280,36 +267,23 @@ public class CaseBreakChecker extends AbstractIndexAstChecker implements
|
|||
*/
|
||||
public boolean isBreakOrExitStatement(IASTStatement statement) {
|
||||
CxxAstUtils utils = CxxAstUtils.getInstance();
|
||||
return statement instanceof IASTBreakStatement
|
||||
|| statement instanceof IASTReturnStatement
|
||||
|| statement instanceof IASTContinueStatement
|
||||
|| statement instanceof IASTGotoStatement
|
||||
return statement instanceof IASTBreakStatement || statement instanceof IASTReturnStatement
|
||||
|| statement instanceof IASTContinueStatement || statement instanceof IASTGotoStatement
|
||||
|| utils.isThrowStatement(statement) || utils.isExitStatement(statement);
|
||||
}
|
||||
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
addPreference(
|
||||
problem,
|
||||
PARAM_NO_BREAK_COMMENT,
|
||||
CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
|
||||
addPreference(problem, PARAM_NO_BREAK_COMMENT, CheckersMessages.CaseBreakChecker_DefaultNoBreakCommentDescription,
|
||||
DEFAULT_NO_BREAK_COMMENT);
|
||||
addPreference(problem, PARAM_LAST_CASE,
|
||||
CheckersMessages.CaseBreakChecker_LastCaseDescription,
|
||||
Boolean.TRUE);
|
||||
addPreference(problem, PARAM_EMPTY_CASE,
|
||||
CheckersMessages.CaseBreakChecker_EmptyCaseDescription,
|
||||
Boolean.FALSE);
|
||||
|
||||
addPreference(problem, PARAM_LAST_CASE, CheckersMessages.CaseBreakChecker_LastCaseDescription, Boolean.TRUE);
|
||||
addPreference(problem, PARAM_EMPTY_CASE, CheckersMessages.CaseBreakChecker_EmptyCaseDescription, Boolean.FALSE);
|
||||
}
|
||||
|
||||
public void processAst(IASTTranslationUnit ast) {
|
||||
_checkLastCase = (Boolean) getPreference(
|
||||
getProblemById(ER_ID, getFile()), PARAM_LAST_CASE);
|
||||
_checkEmptyCase = (Boolean) getPreference(
|
||||
getProblemById(ER_ID, getFile()), PARAM_EMPTY_CASE);
|
||||
_noBreakComment = (String) getPreference(
|
||||
getProblemById(ER_ID, getFile()), PARAM_NO_BREAK_COMMENT);
|
||||
_checkLastCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_LAST_CASE);
|
||||
_checkEmptyCase = (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_EMPTY_CASE);
|
||||
_noBreakComment = (String) getPreference(getProblemById(ER_ID, getFile()), PARAM_NO_BREAK_COMMENT);
|
||||
SwitchFindingVisitor visitor = new SwitchFindingVisitor();
|
||||
_commentsIt = new CommentsIterator(ast.getComments());
|
||||
ast.accept(visitor);
|
||||
|
|
|
@ -59,8 +59,7 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
|||
if (stmt instanceof ICPPASTTryBlockStatement) {
|
||||
try {
|
||||
ICPPASTTryBlockStatement tblock = (ICPPASTTryBlockStatement) stmt;
|
||||
ICPPASTCatchHandler[] catchHandlers = tblock
|
||||
.getCatchHandlers();
|
||||
ICPPASTCatchHandler[] catchHandlers = tblock.getCatchHandlers();
|
||||
for (int i = 0; i < catchHandlers.length; i++) {
|
||||
ICPPASTCatchHandler catchHandler = catchHandlers[i];
|
||||
IASTDeclaration decl = catchHandler.getDeclaration();
|
||||
|
@ -69,15 +68,10 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
|||
IASTDeclSpecifier spec = sdecl.getDeclSpecifier();
|
||||
if (!usesReference(catchHandler)) {
|
||||
if (spec instanceof IASTNamedTypeSpecifier) {
|
||||
IASTName tname = ((IASTNamedTypeSpecifier) spec)
|
||||
.getName();
|
||||
IType typeName = (IType) tname
|
||||
.resolveBinding();
|
||||
typeName = CxxAstUtils.getInstance()
|
||||
.unwindTypedef(typeName);
|
||||
if (typeName instanceof IBasicType
|
||||
|| typeName instanceof IPointerType
|
||||
|| typeName == null)
|
||||
IASTName tname = ((IASTNamedTypeSpecifier) spec).getName();
|
||||
IType typeName = (IType) tname.resolveBinding();
|
||||
typeName = CxxAstUtils.getInstance().unwindTypedef(typeName);
|
||||
if (typeName instanceof IBasicType || typeName instanceof IPointerType || typeName == null)
|
||||
continue;
|
||||
if (typeName instanceof IProblemBinding && !shouldReportForUnknownType())
|
||||
continue;
|
||||
|
@ -106,12 +100,10 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
|||
private boolean usesReference(ICPPASTCatchHandler catchHandler) {
|
||||
IASTDeclaration declaration = catchHandler.getDeclaration();
|
||||
if (declaration instanceof IASTSimpleDeclaration) {
|
||||
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) declaration)
|
||||
.getDeclarators();
|
||||
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) declaration).getDeclarators();
|
||||
for (int i = 0; i < declarators.length; i++) {
|
||||
IASTDeclarator d = declarators[i];
|
||||
IASTPointerOperator[] pointerOperators = d
|
||||
.getPointerOperators();
|
||||
IASTPointerOperator[] pointerOperators = d.getPointerOperators();
|
||||
for (int j = 0; j < pointerOperators.length; j++) {
|
||||
IASTPointerOperator po = pointerOperators[j];
|
||||
if (po instanceof ICPPASTReferenceOperator) {
|
||||
|
@ -130,16 +122,13 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
|||
@Override
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
addPreference(problem, PARAM_UNKNOWN_TYPE,
|
||||
CheckersMessages.CatchByReference_ReportForUnknownType, Boolean.FALSE);
|
||||
addListPreference(problem, PARAM_EXCEPT_ARG_LIST,
|
||||
CheckersMessages.GenericParameter_ParameterExceptions,
|
||||
addPreference(problem, PARAM_UNKNOWN_TYPE, CheckersMessages.CatchByReference_ReportForUnknownType, Boolean.FALSE);
|
||||
addListPreference(problem, PARAM_EXCEPT_ARG_LIST, CheckersMessages.GenericParameter_ParameterExceptions,
|
||||
CheckersMessages.GenericParameter_ParameterExceptionsItem);
|
||||
}
|
||||
|
||||
public boolean isFilteredArg(String arg) {
|
||||
Object[] arr = (Object[]) getPreference(
|
||||
getProblemById(ER_ID, getFile()), PARAM_EXCEPT_ARG_LIST);
|
||||
Object[] arr = (Object[]) getPreference(getProblemById(ER_ID, getFile()), PARAM_EXCEPT_ARG_LIST);
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
String str = (String) arr[i];
|
||||
if (arg.equals(str))
|
||||
|
@ -152,7 +141,6 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
|||
* @return
|
||||
*/
|
||||
public boolean shouldReportForUnknownType() {
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()),
|
||||
PARAM_UNKNOWN_TYPE);
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_UNKNOWN_TYPE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,9 +28,7 @@ public class CheckersMessages extends NLS {
|
|||
public static String StatementHasNoEffectChecker_ParameterMacro;
|
||||
public static String SuggestedParenthesisChecker_SuggestParanthesesAroundNot;
|
||||
public static String SuspiciousSemicolonChecker_ParamElse;
|
||||
|
||||
public static String ProblemBindingChecker_Candidates;
|
||||
|
||||
static {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, CheckersMessages.class);
|
||||
|
|
|
@ -28,13 +28,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
|||
* regular expression defining the style.
|
||||
*
|
||||
*/
|
||||
public class NamingConventionFunctionChecker extends AbstractIndexAstChecker
|
||||
implements ICheckerWithPreferences {
|
||||
public class NamingConventionFunctionChecker extends AbstractIndexAstChecker implements ICheckerWithPreferences {
|
||||
private static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker"; //$NON-NLS-1$
|
||||
public static final String PARAM_KEY = "pattern"; //$NON-NLS-1$
|
||||
public static final String PARAM_METHODS = "macro"; //$NON-NLS-1$
|
||||
public static final String PARAM_EXCEPT_ARG_LIST = "exceptions"; //$NON-NLS-1$
|
||||
|
||||
|
||||
public void processAst(IASTTranslationUnit ast) {
|
||||
final IProblem pt = getProblemById(ER_ID, getFile());
|
||||
try {
|
||||
|
@ -47,8 +46,7 @@ public class NamingConventionFunctionChecker extends AbstractIndexAstChecker
|
|||
if (element instanceof IASTFunctionDefinition) {
|
||||
String parameter = (String) getPreference(pt, PARAM_KEY);
|
||||
Pattern pattern = Pattern.compile(parameter);
|
||||
IASTName astName = ((IASTFunctionDefinition) element)
|
||||
.getDeclarator().getName();
|
||||
IASTName astName = ((IASTFunctionDefinition) element).getDeclarator().getName();
|
||||
String name = astName.toString();
|
||||
if (astName instanceof ICPPASTQualifiedName) {
|
||||
if (!shouldReportCppMethods())
|
||||
|
@ -59,10 +57,9 @@ public class NamingConventionFunctionChecker extends AbstractIndexAstChecker
|
|||
name = cppAstName.getLastName().toString();
|
||||
if (name.startsWith("~")) // destructor //$NON-NLS-1$
|
||||
return PROCESS_SKIP;
|
||||
|
||||
IASTName[] names = cppAstName.getNames();
|
||||
if (names.length>=2) {
|
||||
if (names[names.length-1].toString().equals(names[names.length-2].toString())) {
|
||||
if (names.length >= 2) {
|
||||
if (names[names.length - 1].toString().equals(names[names.length - 2].toString())) {
|
||||
// constructor
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
@ -89,29 +86,19 @@ public class NamingConventionFunctionChecker extends AbstractIndexAstChecker
|
|||
*/
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
addPreference(
|
||||
problem,
|
||||
PARAM_KEY,
|
||||
CheckersMessages.NamingConventionFunctionChecker_LabelNamePattern,
|
||||
"^[a-z]"); //$NON-NLS-1$
|
||||
addPreference(problem, PARAM_METHODS,
|
||||
"Also check C++ method names",
|
||||
Boolean.TRUE);
|
||||
addListPreference(
|
||||
problem,
|
||||
PARAM_EXCEPT_ARG_LIST,
|
||||
CheckersMessages.GenericParameter_ParameterExceptions,
|
||||
addPreference(problem, PARAM_KEY, CheckersMessages.NamingConventionFunctionChecker_LabelNamePattern, "^[a-z]"); //$NON-NLS-1$
|
||||
addPreference(problem, PARAM_METHODS, "Also check C++ method names", Boolean.TRUE);
|
||||
addListPreference(problem, PARAM_EXCEPT_ARG_LIST, CheckersMessages.GenericParameter_ParameterExceptions,
|
||||
CheckersMessages.GenericParameter_ParameterExceptionsItem);
|
||||
}
|
||||
|
||||
public boolean shouldReportCppMethods() {
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()),
|
||||
PARAM_METHODS);
|
||||
}
|
||||
public boolean isFilteredArg(String arg) {
|
||||
return isFilteredArg(arg, getProblemById(ER_ID, getFile()),
|
||||
PARAM_EXCEPT_ARG_LIST);
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_METHODS);
|
||||
}
|
||||
|
||||
public boolean isFilteredArg(String arg) {
|
||||
return isFilteredArg(arg, getProblemById(ER_ID, getFile()), PARAM_EXCEPT_ARG_LIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean runInEditor() {
|
||||
|
|
|
@ -60,7 +60,7 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
|||
if (destructorName instanceof ICPPInternalBinding) {
|
||||
ICPPInternalBinding bin = (ICPPInternalBinding) destructorName;
|
||||
IASTNode[] decls = bin.getDeclarations();
|
||||
if (decls!=null && decls.length>0)
|
||||
if (decls != null && decls.length > 0)
|
||||
ast = decls[0];
|
||||
}
|
||||
reportProblem(ER_ID, ast, clazz, method, destructorName.getName());
|
||||
|
@ -80,8 +80,7 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
|||
* @param decl
|
||||
* @throws DOMException
|
||||
*/
|
||||
private boolean hasErrorCondition(IASTDeclSpecifier decl)
|
||||
throws DOMException {
|
||||
private boolean hasErrorCondition(IASTDeclSpecifier decl) throws DOMException {
|
||||
ICPPASTCompositeTypeSpecifier spec = (ICPPASTCompositeTypeSpecifier) decl;
|
||||
className = spec.getName();
|
||||
IBinding binding = className.getBinding();
|
||||
|
@ -123,8 +122,7 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
|
|||
// class does not have virtual methods but has virtual
|
||||
// destructor
|
||||
// - not an error
|
||||
if (hasOwnVirtualMethod == false && hasDestructor == true
|
||||
&& hasOwnNonVirDestructor == false) {
|
||||
if (hasOwnVirtualMethod == false && hasDestructor == true && hasOwnNonVirDestructor == false) {
|
||||
return false;
|
||||
}
|
||||
ICPPMethod[] allDeclaredMethods = type.getAllDeclaredMethods();
|
||||
|
|
|
@ -73,77 +73,56 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
|
|||
IASTNode parentNode = name.getParent();
|
||||
// Don't report multiple problems with qualified names
|
||||
if (parentNode instanceof ICPPASTQualifiedName) {
|
||||
if (((ICPPASTQualifiedName) parentNode)
|
||||
.resolveBinding() instanceof IProblemBinding)
|
||||
if (((ICPPASTQualifiedName) parentNode).resolveBinding() instanceof IProblemBinding)
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
String contextFlagsString = createContextFlagsString(name);
|
||||
IProblemBinding problemBinding = (IProblemBinding) binding;
|
||||
int id = problemBinding.getID();
|
||||
if (id == IProblemBinding.SEMANTIC_INVALID_OVERLOAD) {
|
||||
reportProblem(ERR_ID_OverloadProblem, name,
|
||||
name.getRawSignature(),
|
||||
contextFlagsString);
|
||||
reportProblem(ERR_ID_OverloadProblem, name, name.getRawSignature(), contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (id == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) {
|
||||
String candidatesString = getCandidatesString(problemBinding);
|
||||
reportProblem(ERR_ID_AmbiguousProblem, name,
|
||||
name.getRawSignature(),
|
||||
candidatesString, contextFlagsString);
|
||||
reportProblem(ERR_ID_AmbiguousProblem, name, name.getRawSignature(), candidatesString, contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (id == IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE) {
|
||||
String typeString;
|
||||
IASTNode problemNode;
|
||||
if (parentNode instanceof IASTFieldReference) {
|
||||
IASTExpression ownerExpression = ((IASTFieldReference) parentNode)
|
||||
.getFieldOwner();
|
||||
typeString = ASTTypeUtil
|
||||
.getType(ownerExpression
|
||||
.getExpressionType());
|
||||
IASTExpression ownerExpression = ((IASTFieldReference) parentNode).getFieldOwner();
|
||||
typeString = ASTTypeUtil.getType(ownerExpression.getExpressionType());
|
||||
problemNode = ownerExpression;
|
||||
} else {
|
||||
problemNode = name;
|
||||
typeString = name.getRawSignature();
|
||||
}
|
||||
reportProblem(ERR_ID_CircularReferenceProblem,
|
||||
problemNode, typeString,
|
||||
contextFlagsString);
|
||||
reportProblem(ERR_ID_CircularReferenceProblem, problemNode, typeString, contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (id == IProblemBinding.SEMANTIC_INVALID_REDECLARATION) {
|
||||
reportProblem(ERR_ID_RedeclarationProblem,
|
||||
name, name.getRawSignature(),
|
||||
contextFlagsString);
|
||||
reportProblem(ERR_ID_RedeclarationProblem, name, name.getRawSignature(), contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (id == IProblemBinding.SEMANTIC_INVALID_REDEFINITION) {
|
||||
reportProblem(ERR_ID_RedefinitionProblem, name,
|
||||
name.getRawSignature(),
|
||||
contextFlagsString);
|
||||
reportProblem(ERR_ID_RedefinitionProblem, name, name.getRawSignature(), contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (id == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) {
|
||||
reportProblem(
|
||||
ERR_ID_MemberDeclarationNotFoundProblem,
|
||||
name, contextFlagsString);
|
||||
reportProblem(ERR_ID_MemberDeclarationNotFoundProblem, name, contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (id == IProblemBinding.SEMANTIC_LABEL_STATEMENT_NOT_FOUND) {
|
||||
reportProblem(
|
||||
ERR_ID_LabelStatementNotFoundProblem,
|
||||
name, name.getRawSignature(),
|
||||
contextFlagsString);
|
||||
reportProblem(ERR_ID_LabelStatementNotFoundProblem, name, name.getRawSignature(), contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (id == IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS) {
|
||||
// We use the templateName since we don't want the whole
|
||||
// argument list to be underlined. That way we can see which argument is invalid.
|
||||
IASTNode templateName = getTemplateName(name);
|
||||
reportProblem(
|
||||
ERR_ID_InvalidTemplateArgumentsProblem,
|
||||
templateName, contextFlagsString);
|
||||
reportProblem(ERR_ID_InvalidTemplateArgumentsProblem, templateName, contextFlagsString);
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
// From this point, we'll deal only with NAME_NOT_FOUND problems.
|
||||
|
@ -152,15 +131,11 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
|
|||
return PROCESS_CONTINUE;
|
||||
}
|
||||
if (isFunctionCall(parentNode)) {
|
||||
handleFunctionProblem(name, problemBinding,
|
||||
contextFlagsString);
|
||||
handleFunctionProblem(name, problemBinding, contextFlagsString);
|
||||
} else if (parentNode instanceof IASTFieldReference) {
|
||||
handleMemberProblem(name, parentNode,
|
||||
problemBinding, contextFlagsString);
|
||||
handleMemberProblem(name, parentNode, problemBinding, contextFlagsString);
|
||||
} else if (parentNode instanceof IASTNamedTypeSpecifier) {
|
||||
reportProblem(ERR_ID_TypeResolutionProblem,
|
||||
name, name.getRawSignature(),
|
||||
contextFlagsString);
|
||||
reportProblem(ERR_ID_TypeResolutionProblem, name, name.getRawSignature(), contextFlagsString);
|
||||
}
|
||||
// Probably a variable
|
||||
else {
|
||||
|
@ -199,8 +174,7 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
|
|||
return false;
|
||||
}
|
||||
@SuppressWarnings("restriction")
|
||||
IASTDeclarator innermostDeclarator = ASTQueries
|
||||
.findInnermostDeclarator(function.getDeclarator());
|
||||
IASTDeclarator innermostDeclarator = ASTQueries.findInnermostDeclarator(function.getDeclarator());
|
||||
IBinding binding = innermostDeclarator.getName().resolveBinding();
|
||||
return (binding instanceof ICPPMethod);
|
||||
}
|
||||
|
@ -211,42 +185,32 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
|
|||
return (function != null);
|
||||
}
|
||||
|
||||
private void handleFunctionProblem(IASTName name,
|
||||
IProblemBinding problemBinding, String contextFlagsString)
|
||||
throws DOMException {
|
||||
private void handleFunctionProblem(IASTName name, IProblemBinding problemBinding, String contextFlagsString) throws DOMException {
|
||||
if (problemBinding.getCandidateBindings().length == 0) {
|
||||
reportProblem(ERR_ID_FunctionResolutionProblem, name.getLastName(),
|
||||
name.getRawSignature(), contextFlagsString);
|
||||
reportProblem(ERR_ID_FunctionResolutionProblem, name.getLastName(), name.getRawSignature(), contextFlagsString);
|
||||
} else {
|
||||
String candidatesString = getCandidatesString(problemBinding);
|
||||
reportProblem(ERR_ID_InvalidArguments, name.getLastName(),
|
||||
candidatesString, contextFlagsString);
|
||||
reportProblem(ERR_ID_InvalidArguments, name.getLastName(), candidatesString, contextFlagsString);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMemberProblem(IASTName name, IASTNode parentNode,
|
||||
IProblemBinding problemBinding, String contextFlagsString)
|
||||
private void handleMemberProblem(IASTName name, IASTNode parentNode, IProblemBinding problemBinding, String contextFlagsString)
|
||||
throws DOMException {
|
||||
IASTNode parentParentNode = parentNode.getParent();
|
||||
if (parentParentNode instanceof IASTFunctionCallExpression) {
|
||||
if (problemBinding.getCandidateBindings().length == 0) {
|
||||
reportProblem(ERR_ID_MethodResolutionProblem,
|
||||
name.getLastName(), name.getRawSignature(),
|
||||
contextFlagsString);
|
||||
reportProblem(ERR_ID_MethodResolutionProblem, name.getLastName(), name.getRawSignature(), contextFlagsString);
|
||||
} else {
|
||||
String candidatesString = getCandidatesString(problemBinding);
|
||||
reportProblem(ERR_ID_InvalidArguments, name.getLastName(),
|
||||
candidatesString, contextFlagsString);
|
||||
reportProblem(ERR_ID_InvalidArguments, name.getLastName(), candidatesString, contextFlagsString);
|
||||
}
|
||||
} else {
|
||||
reportProblem(ERR_ID_FieldResolutionProblem, name.getLastName(),
|
||||
name.getRawSignature(), contextFlagsString);
|
||||
reportProblem(ERR_ID_FieldResolutionProblem, name.getLastName(), name.getRawSignature(), contextFlagsString);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleVariableProblem(IASTName name, String contextFlagsString) {
|
||||
reportProblem(ERR_ID_VariableResolutionProblem, name,
|
||||
name.getRawSignature(), contextFlagsString);
|
||||
reportProblem(ERR_ID_VariableResolutionProblem, name, name.getRawSignature(), contextFlagsString);
|
||||
}
|
||||
|
||||
private boolean isFunctionCall(IASTNode parentNode) {
|
||||
|
@ -254,11 +218,7 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
|
|||
IASTIdExpression expression = (IASTIdExpression) parentNode;
|
||||
IASTNode parentParentNode = expression.getParent();
|
||||
if (parentParentNode instanceof IASTFunctionCallExpression
|
||||
&& expression
|
||||
.getPropertyInParent()
|
||||
.getName()
|
||||
.equals(IASTFunctionCallExpression.FUNCTION_NAME
|
||||
.getName())) {
|
||||
&& expression.getPropertyInParent().getName().equals(IASTFunctionCallExpression.FUNCTION_NAME.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -280,8 +240,7 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
|
|||
* @return A string of the candidates, one per line
|
||||
* @throws DOMException
|
||||
*/
|
||||
private String getCandidatesString(IProblemBinding problemBinding)
|
||||
throws DOMException {
|
||||
private String getCandidatesString(IProblemBinding problemBinding) throws DOMException {
|
||||
String candidatesString = "\n" + CheckersMessages.ProblemBindingChecker_Candidates + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
String lastSignature = ""; //$NON-NLS-1$
|
||||
for (IBinding candidateBinding : problemBinding.getCandidateBindings()) {
|
||||
|
@ -314,14 +273,11 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
|
|||
* @return A string of the function signature
|
||||
* @throws DOMException
|
||||
*/
|
||||
private String getFunctionSignature(ICPPFunction functionBinding)
|
||||
throws DOMException {
|
||||
private String getFunctionSignature(ICPPFunction functionBinding) throws DOMException {
|
||||
IFunctionType functionType = functionBinding.getType();
|
||||
String returnTypeString = ASTTypeUtil.getType(functionBinding.getType()
|
||||
.getReturnType()) + " "; //$NON-NLS-1$
|
||||
String returnTypeString = ASTTypeUtil.getType(functionBinding.getType().getReturnType()) + " "; //$NON-NLS-1$
|
||||
String functionName = functionBinding.getName();
|
||||
String parameterTypeString = ASTTypeUtil
|
||||
.getParameterTypeString(functionType);
|
||||
String parameterTypeString = ASTTypeUtil.getParameterTypeString(functionType);
|
||||
return returnTypeString + functionName + parameterTypeString;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
|
|||
* <li>Function declared as returning non-void has no return (requires control
|
||||
* flow graph)
|
||||
*/
|
||||
public class ReturnChecker extends AbstractAstFunctionChecker {
|
||||
public class ReturnChecker extends AbstractAstFunctionChecker {
|
||||
public static final String PARAM_IMPLICIT = "implicit"; //$NON-NLS-1$
|
||||
public static final String RET_NO_VALUE_ID = "org.eclipse.cdt.codan.checkers.noreturn"; //$NON-NLS-1$
|
||||
public static final String RET_ERR_VALUE_ID = "org.eclipse.cdt.codan.checkers.errreturnvalue"; //$NON-NLS-1$
|
||||
|
@ -64,31 +64,30 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
this.func = func;
|
||||
this.hasret = false;
|
||||
}
|
||||
|
||||
public int visit(IASTDeclaration element) {
|
||||
if (element!=func)
|
||||
return PROCESS_SKIP; // skip inner functions
|
||||
if (element != func)
|
||||
return PROCESS_SKIP; // skip inner functions
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
public int visit(IASTStatement stmt) {
|
||||
if (stmt instanceof IASTReturnStatement) {
|
||||
hasret = true;
|
||||
IASTReturnStatement ret = (IASTReturnStatement) stmt;
|
||||
if (!isVoid(func) && !isConstructorDestructor()) {
|
||||
if (checkImplicitReturn(RET_NO_VALUE_ID)
|
||||
|| isExplicitReturn(func)) {
|
||||
|
||||
if (checkImplicitReturn(RET_NO_VALUE_ID) || isExplicitReturn(func)) {
|
||||
if (ret.getReturnValue() == null)
|
||||
reportProblem(RET_NO_VALUE_ID, ret);
|
||||
}
|
||||
} else {
|
||||
if (ret.getReturnValue() != null) {
|
||||
IType type = ret.getReturnValue().getExpressionType();
|
||||
if (isVoid(type))
|
||||
if (isVoid(type))
|
||||
return PROCESS_SKIP;
|
||||
reportProblem(RET_ERR_VALUE_ID, ret.getReturnValue());
|
||||
}
|
||||
}
|
||||
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
if (stmt instanceof IASTExpressionStatement) {
|
||||
|
@ -101,20 +100,20 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
}
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* @return
|
||||
*
|
||||
*/
|
||||
public boolean isConstructorDestructor() {
|
||||
if (func instanceof ICPPASTFunctionDefinition) {
|
||||
IBinding method = func.getDeclarator().getName().resolveBinding();
|
||||
if (method instanceof ICPPConstructor || method instanceof ICPPMethod && ((ICPPMethod)method).isDestructor()) {
|
||||
if (method instanceof ICPPConstructor || method instanceof ICPPMethod && ((ICPPMethod) method).isDestructor()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -129,8 +128,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
func.accept(visitor);
|
||||
if (!visitor.hasret) {
|
||||
// no return at all
|
||||
if (!isVoid(func)
|
||||
&& (checkImplicitReturn(RET_NORET_ID) || isExplicitReturn(func))) {
|
||||
if (!isVoid(func) && (checkImplicitReturn(RET_NORET_ID) || isExplicitReturn(func))) {
|
||||
if (endsWithNoExitNode(func))
|
||||
reportProblem(RET_NORET_ID, func.getDeclSpecifier());
|
||||
}
|
||||
|
@ -143,7 +141,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
*/
|
||||
protected boolean checkImplicitReturn(String id) {
|
||||
final IProblem pt = getProblemById(id, getFile());
|
||||
return (Boolean) getPreference(pt,PARAM_IMPLICIT);
|
||||
return (Boolean) getPreference(pt, PARAM_IMPLICIT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,8 +149,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
* @return
|
||||
*/
|
||||
protected boolean endsWithNoExitNode(IASTFunctionDefinition func) {
|
||||
IControlFlowGraph graph = CxxModelsCache.getInstance()
|
||||
.getControlFlowGraph(func);
|
||||
IControlFlowGraph graph = CxxModelsCache.getInstance().getControlFlowGraph(func);
|
||||
Iterator<IExitNode> exitNodeIterator = graph.getExitNodeIterator();
|
||||
boolean noexitop = false;
|
||||
for (; exitNodeIterator.hasNext();) {
|
||||
|
@ -189,9 +186,11 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if type if void
|
||||
* (uses deprecated API for compatibility with 6.0)
|
||||
*
|
||||
* @param type
|
||||
* @throws DOMException
|
||||
*/
|
||||
|
@ -199,7 +198,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
public boolean isVoid(IType type) {
|
||||
if (type instanceof IBasicType) {
|
||||
try {
|
||||
if (((IBasicType) type).getType()==IBasicType.t_void)
|
||||
if (((IBasicType) type).getType() == IBasicType.t_void)
|
||||
return true;
|
||||
} catch (DOMException e) {
|
||||
return false;
|
||||
|
@ -207,6 +206,7 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param func
|
||||
* @return
|
||||
|
@ -217,10 +217,8 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
if (declSpecifier instanceof IASTSimpleDeclSpecifier) {
|
||||
type = ((IASTSimpleDeclSpecifier) declSpecifier).getType();
|
||||
} else if (declSpecifier instanceof IASTNamedTypeSpecifier) {
|
||||
IBinding binding = ((IASTNamedTypeSpecifier) declSpecifier)
|
||||
.getName().resolveBinding();
|
||||
IType utype = CxxAstUtils.getInstance().unwindTypedef(
|
||||
(IType) binding);
|
||||
IBinding binding = ((IASTNamedTypeSpecifier) declSpecifier).getName().resolveBinding();
|
||||
IType utype = CxxAstUtils.getInstance().unwindTypedef((IType) binding);
|
||||
if (isVoid(utype))
|
||||
return IASTSimpleDeclSpecifier.t_void;
|
||||
}
|
||||
|
@ -230,10 +228,8 @@ public class ReturnChecker extends AbstractAstFunctionChecker {
|
|||
/* checker must implement @link ICheckerWithPreferences */
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
if (problem.getId().equals(RET_NO_VALUE_ID)
|
||||
|| problem.getId().equals(RET_NORET_ID)) {
|
||||
addPreference(problem, PARAM_IMPLICIT,
|
||||
CheckersMessages.ReturnChecker_Param0, Boolean.FALSE);
|
||||
if (problem.getId().equals(RET_NO_VALUE_ID) || problem.getId().equals(RET_NORET_ID)) {
|
||||
addPreference(problem, PARAM_IMPLICIT, CheckersMessages.ReturnChecker_Param0, Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
|||
|
||||
public class ReturnStyleChecker extends AbstractIndexAstChecker {
|
||||
public final String ERR_ID = "org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem"; //$NON-NLS-1$
|
||||
|
||||
|
||||
@Override
|
||||
public boolean runInEditor() {
|
||||
return true;
|
||||
|
@ -35,21 +35,17 @@ public class ReturnStyleChecker extends AbstractIndexAstChecker {
|
|||
@Override
|
||||
public int visit(IASTStatement statement) {
|
||||
if (statement instanceof IASTReturnStatement) {
|
||||
|
||||
boolean isValidStyle = false;
|
||||
|
||||
IASTNode[] children = statement.getChildren();
|
||||
|
||||
if (children.length == 0) {
|
||||
isValidStyle = true;
|
||||
} else if (children.length == 1
|
||||
&& children[0] instanceof IASTUnaryExpression) {
|
||||
} else if (children.length == 1 && children[0] instanceof IASTUnaryExpression) {
|
||||
IASTUnaryExpression unaryExpression = (IASTUnaryExpression) children[0];
|
||||
if (unaryExpression.getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
||||
isValidStyle = true;
|
||||
}
|
||||
}
|
||||
if(!isValidStyle) {
|
||||
if (!isValidStyle) {
|
||||
reportProblem(ERR_ID, statement);
|
||||
}
|
||||
}
|
||||
|
@ -57,5 +53,4 @@ public class ReturnStyleChecker extends AbstractIndexAstChecker {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -55,11 +55,9 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker {
|
|||
@Override
|
||||
public int visit(IASTStatement stmt) {
|
||||
if (stmt instanceof IASTExpressionStatement) {
|
||||
IASTExpression expression = ((IASTExpressionStatement) stmt)
|
||||
.getExpression();
|
||||
IASTExpression expression = ((IASTExpressionStatement) stmt).getExpression();
|
||||
if (hasNoEffect(expression)) {
|
||||
boolean inMacro = CxxAstUtils.getInstance().isInMacro(
|
||||
expression);
|
||||
boolean inMacro = CxxAstUtils.getInstance().isInMacro(expression);
|
||||
boolean shouldReportInMacro = shouldReportInMacro();
|
||||
if (inMacro && !shouldReportInMacro)
|
||||
return PROCESS_SKIP;
|
||||
|
@ -88,8 +86,7 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker {
|
|||
switch (binExpr.getOperator()) {
|
||||
case IASTBinaryExpression.op_logicalOr:
|
||||
case IASTBinaryExpression.op_logicalAnd:
|
||||
return hasNoEffect(binExpr.getOperand1())
|
||||
&& hasNoEffect(binExpr.getOperand2());
|
||||
return hasNoEffect(binExpr.getOperand1()) && hasNoEffect(binExpr.getOperand2());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -130,25 +127,20 @@ public class StatementHasNoEffectChecker extends AbstractIndexAstChecker {
|
|||
@Override
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
addPreference(problem, PARAM_MACRO_ID,
|
||||
CheckersMessages.StatementHasNoEffectChecker_ParameterMacro,
|
||||
Boolean.TRUE);
|
||||
addListPreference(problem, PARAM_EXCEPT_ARG_LIST,
|
||||
CheckersMessages.GenericParameter_ParameterExceptions,
|
||||
addPreference(problem, PARAM_MACRO_ID, CheckersMessages.StatementHasNoEffectChecker_ParameterMacro, Boolean.TRUE);
|
||||
addListPreference(problem, PARAM_EXCEPT_ARG_LIST, CheckersMessages.GenericParameter_ParameterExceptions,
|
||||
CheckersMessages.GenericParameter_ParameterExceptionsItem);
|
||||
}
|
||||
|
||||
public boolean isFilteredArg(String arg) {
|
||||
return isFilteredArg(arg, getProblemById(ER_ID, getFile()),
|
||||
PARAM_EXCEPT_ARG_LIST);
|
||||
return isFilteredArg(arg, getProblemById(ER_ID, getFile()), PARAM_EXCEPT_ARG_LIST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public boolean shouldReportInMacro() {
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()),
|
||||
PARAM_MACRO_ID);
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_MACRO_ID);
|
||||
}
|
||||
|
||||
public boolean isPossibleAssignment(IASTBinaryExpression expr) {
|
||||
|
|
|
@ -35,8 +35,6 @@ public class SuggestedParenthesisChecker extends AbstractIndexAstChecker {
|
|||
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem"; //$NON-NLS-1$
|
||||
public static final String PARAM_NOT = "paramNot"; //$NON-NLS-1$
|
||||
|
||||
|
||||
|
||||
public void processAst(IASTTranslationUnit ast) {
|
||||
// traverse the ast using the visitor pattern.
|
||||
ast.accept(new ExpressionVisitor());
|
||||
|
@ -121,8 +119,7 @@ public class SuggestedParenthesisChecker extends AbstractIndexAstChecker {
|
|||
}
|
||||
|
||||
public boolean isParamNot() {
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()),
|
||||
PARAM_NOT);
|
||||
return (Boolean) getPreference(getProblemById(ER_ID, getFile()), PARAM_NOT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -135,7 +132,6 @@ public class SuggestedParenthesisChecker extends AbstractIndexAstChecker {
|
|||
@Override
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
addPreference(problem, PARAM_NOT,
|
||||
CheckersMessages.SuggestedParenthesisChecker_SuggestParanthesesAroundNot, Boolean.FALSE);
|
||||
addPreference(problem, PARAM_NOT, CheckersMessages.SuggestedParenthesisChecker_SuggestParanthesesAroundNot, Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,14 +35,11 @@ public class SuspiciousSemicolonChecker extends AbstractIndexAstChecker {
|
|||
@Override
|
||||
public int visit(IASTStatement statement) {
|
||||
if (statement instanceof IASTIfStatement) {
|
||||
IASTStatement thenStmt = ((IASTIfStatement) statement)
|
||||
.getThenClause();
|
||||
IASTStatement elseStmt = ((IASTIfStatement) statement)
|
||||
.getElseClause();
|
||||
IASTStatement thenStmt = ((IASTIfStatement) statement).getThenClause();
|
||||
IASTStatement elseStmt = ((IASTIfStatement) statement).getElseClause();
|
||||
if (elseStmt != null && doNotReportIfElse() == true)
|
||||
return PROCESS_CONTINUE;
|
||||
if (thenStmt instanceof IASTNullStatement
|
||||
&& noMacroInvolved(thenStmt)) {
|
||||
if (thenStmt instanceof IASTNullStatement && noMacroInvolved(thenStmt)) {
|
||||
reportProblem(ER_ID, thenStmt, (Object) null);
|
||||
}
|
||||
}
|
||||
|
@ -57,19 +54,14 @@ public class SuspiciousSemicolonChecker extends AbstractIndexAstChecker {
|
|||
}
|
||||
|
||||
protected boolean noMacroInvolved(IASTStatement node) {
|
||||
IASTNodeSelector nodeSelector = node.getTranslationUnit()
|
||||
.getNodeSelector(node.getTranslationUnit().getFilePath());
|
||||
IASTNodeSelector nodeSelector = node.getTranslationUnit().getNodeSelector(node.getTranslationUnit().getFilePath());
|
||||
IASTFileLocation fileLocation = node.getFileLocation();
|
||||
IASTPreprocessorMacroExpansion macro = nodeSelector
|
||||
.findEnclosingMacroExpansion(fileLocation.getNodeOffset() - 1,
|
||||
1);
|
||||
IASTPreprocessorMacroExpansion macro = nodeSelector.findEnclosingMacroExpansion(fileLocation.getNodeOffset() - 1, 1);
|
||||
return macro == null;
|
||||
}
|
||||
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
addPreference(problem, PARAM_ELSE,
|
||||
CheckersMessages.SuspiciousSemicolonChecker_ParamElse,
|
||||
Boolean.FALSE);
|
||||
addPreference(problem, PARAM_ELSE, CheckersMessages.SuspiciousSemicolonChecker_ParamElse, Boolean.FALSE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
* Contributors:
|
||||
* Meisam Fathi - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.codan.internal.checkers.fs;
|
||||
|
||||
import java.util.Collection;
|
||||
|
@ -19,16 +18,15 @@ import java.util.regex.Pattern;
|
|||
|
||||
/**
|
||||
* This class parses the format string argument and extracts all %s tokens.
|
||||
*
|
||||
* @version 0.2, June 04, 2010
|
||||
* @author Meisam Fathi
|
||||
*/
|
||||
public class CFormatStringParser {
|
||||
|
||||
/**
|
||||
* At least one digit should be present
|
||||
*/
|
||||
private static final String DIGIT_PATTERN = "[0-9][0-9]*";//$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The general format for a <strong>format string</strong> argument is
|
||||
* "%[*][size][modifier]type", in which type is one of the following items:
|
||||
|
@ -46,7 +44,6 @@ public class CFormatStringParser {
|
|||
* for more information.
|
||||
*/
|
||||
private static final String STRING_FORMAT_PATTERN = "%[\\*]?[0-9]*[hlL]?[cdeEfgGsuxX]";//$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* If there is an asterisk in the format argument, then it cannot be
|
||||
* vulnerable. If there is a [modifier] (i.e. hlL), then compiler warns.
|
||||
|
@ -57,29 +54,24 @@ public class CFormatStringParser {
|
|||
* @see #FORMAT_STRING_PATTERN
|
||||
*/
|
||||
private static final String VULNERABLE_PATTERN = "%[0-9]*s";//$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The pattern which represents a string format.
|
||||
*/
|
||||
private final Pattern argumentPattern;
|
||||
|
||||
/**
|
||||
* The matcher which matches string format arguments.
|
||||
*/
|
||||
private final Matcher argumentMatcher;
|
||||
|
||||
/**
|
||||
* The pattern which may lead to vulnerability in <code>scanf</code>
|
||||
* function calls.
|
||||
*/
|
||||
private final Pattern vulnerablePattern;
|
||||
|
||||
/**
|
||||
* I guess, this must be a concurrent Collection, but I'm not sure. --
|
||||
* Meisam
|
||||
*/
|
||||
private final Collection<VulnerableFormatStringArgument> vulnerableArguments;
|
||||
|
||||
public final static int ARGUMENT_SIZE_NOT_SPECIFIED = -1;
|
||||
|
||||
/**
|
||||
|
@ -88,10 +80,8 @@ public class CFormatStringParser {
|
|||
* @param argument
|
||||
*/
|
||||
protected CFormatStringParser(final String argument) {
|
||||
|
||||
this.argumentPattern = Pattern.compile(STRING_FORMAT_PATTERN);
|
||||
this.argumentMatcher = this.argumentPattern.matcher(argument);
|
||||
|
||||
this.vulnerablePattern = Pattern.compile(VULNERABLE_PATTERN);
|
||||
this.vulnerableArguments = new ConcurrentLinkedQueue<VulnerableFormatStringArgument>();
|
||||
extractVulnerableArguments();
|
||||
|
@ -120,22 +110,19 @@ public class CFormatStringParser {
|
|||
* I'm not sure if clearing the collection is necessary. -- Meisam Fathi
|
||||
*/
|
||||
this.vulnerableArguments.clear();
|
||||
|
||||
boolean hasMore = this.argumentMatcher.find();
|
||||
int indexOfCurrentArgument = 0;
|
||||
while (hasMore) {
|
||||
final String formatString = this.argumentMatcher.group();
|
||||
final String matchedArgument = formatString;
|
||||
final Matcher vulnerabilityMatcher = this.vulnerablePattern
|
||||
.matcher(matchedArgument);
|
||||
final Matcher vulnerabilityMatcher = this.vulnerablePattern.matcher(matchedArgument);
|
||||
final boolean isVulnerable = vulnerabilityMatcher.find();
|
||||
if (isVulnerable) {
|
||||
final int argumentSize = parseArgumentSize(formatString);
|
||||
final VulnerableFormatStringArgument vulnerableArgument = new VulnerableFormatStringArgument(
|
||||
indexOfCurrentArgument, formatString, argumentSize);
|
||||
final VulnerableFormatStringArgument vulnerableArgument = new VulnerableFormatStringArgument(indexOfCurrentArgument,
|
||||
formatString, argumentSize);
|
||||
this.vulnerableArguments.add(vulnerableArgument);
|
||||
}
|
||||
|
||||
hasMore = this.argumentMatcher.find();
|
||||
indexOfCurrentArgument++;
|
||||
}
|
||||
|
@ -144,7 +131,8 @@ public class CFormatStringParser {
|
|||
/**
|
||||
* This method takes a string as input. The format of the input string is
|
||||
* %[0-9]*s. If there is no digit present in the given string it returns
|
||||
* <code>ARGUMENT_SIZE_NOT_SPECIFIED</code>, otherwise it returns the number specified after "%". For example:
|
||||
* <code>ARGUMENT_SIZE_NOT_SPECIFIED</code>, otherwise it returns the number
|
||||
* specified after "%". For example:
|
||||
* <ul>
|
||||
* <li>%s ==> -1</li>
|
||||
* <li>%123s ==> 123</li>
|
||||
|
@ -154,19 +142,17 @@ public class CFormatStringParser {
|
|||
* </ul>
|
||||
*
|
||||
* @param formatString
|
||||
* The given format string.
|
||||
* @return Either ARGUMENT_SIZE_NOT_SPECIFIED or the number embedded in the input string.
|
||||
* The given format string.
|
||||
* @return Either ARGUMENT_SIZE_NOT_SPECIFIED or the number embedded in the
|
||||
* input string.
|
||||
*/
|
||||
private int parseArgumentSize(final String formatString) {
|
||||
|
||||
// The minimum possible size for a string of format %[0-9]*s
|
||||
final int MINIMUM_POSSIBLE_SIZE = 2;
|
||||
|
||||
int argumentSize = ARGUMENT_SIZE_NOT_SPECIFIED;
|
||||
if (formatString.length() > MINIMUM_POSSIBLE_SIZE) {
|
||||
final Pattern numberPattern = Pattern.compile(DIGIT_PATTERN);
|
||||
final Matcher numberMatcher = numberPattern.matcher(formatString);
|
||||
|
||||
if (numberMatcher.find()) {
|
||||
final String sizeModifierString = numberMatcher.group();
|
||||
argumentSize = Integer.parseInt(sizeModifierString);
|
||||
|
|
|
@ -29,37 +29,37 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
|||
* e.g:
|
||||
* <p>
|
||||
* <code>
|
||||
* int f() { <br>
|
||||
* char inputstr[5]; <br>
|
||||
* scanf("%s", inputstr); // detects vulnerability here <br>
|
||||
* return 0; <br>
|
||||
* int f() { <br>
|
||||
* char inputstr[5]; <br>
|
||||
* scanf("%s", inputstr); // detects vulnerability here <br>
|
||||
* return 0; <br>
|
||||
* }
|
||||
* </code>
|
||||
* <p>
|
||||
* e.g:
|
||||
* <p>
|
||||
* <code>
|
||||
* int f(void) { <br>
|
||||
* char inputstr[5]; <br>
|
||||
* int inputval; <br>
|
||||
* int i = 5; <br>
|
||||
* scanf("%d %9s", inputval, inputstr); // detects vulnerability here <br>
|
||||
* printf("%d" ,i); <br>
|
||||
* return 0; <br>
|
||||
* } <br>
|
||||
* int f(void) { <br>
|
||||
* char inputstr[5]; <br>
|
||||
* int inputval; <br>
|
||||
* int i = 5; <br>
|
||||
* scanf("%d %9s", inputval, inputstr); // detects vulnerability here <br>
|
||||
* printf("%d" ,i); <br>
|
||||
* return 0; <br>
|
||||
* } <br>
|
||||
* </code> <br>
|
||||
* <p>
|
||||
* e.g:
|
||||
* <p>
|
||||
* <code>
|
||||
* int main(void) { <br>
|
||||
* char inputstr[5]; <br>
|
||||
* int inputval; <br>
|
||||
* int i = 5; <br>
|
||||
* scanf("%4s %i", inputstr, inputval); // no vulnerability here <br>
|
||||
* printf("%d" ,i); <br>
|
||||
* return 0; <br>
|
||||
* } <br>
|
||||
* int main(void) { <br>
|
||||
* char inputstr[5]; <br>
|
||||
* int inputval; <br>
|
||||
* int i = 5; <br>
|
||||
* scanf("%4s %i", inputstr, inputval); // no vulnerability here <br>
|
||||
* printf("%d" ,i); <br>
|
||||
* return 0; <br>
|
||||
* } <br>
|
||||
* </code>
|
||||
*
|
||||
* @version 0.3 July 29, 2010
|
||||
|
@ -68,7 +68,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
|||
*/
|
||||
public class ScanfFormatStringSecurityChecker extends AbstractIndexAstChecker {
|
||||
private static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem"; //$NON-NLS-1$
|
||||
|
||||
private final static VulnerableFunction[] VULNERABLE_FUNCTIONS = {//
|
||||
// list of all format string vulnerable functions
|
||||
new VulnerableFunction("scanf", 0), //$NON-NLS-1$
|
||||
|
@ -85,7 +84,6 @@ public class ScanfFormatStringSecurityChecker extends AbstractIndexAstChecker {
|
|||
|
||||
private static final class VulnerableFunction {
|
||||
private final String name;
|
||||
|
||||
private final int formatStringArgumentIndex;
|
||||
|
||||
private VulnerableFunction(String name, int formatStringArgumentIndex) {
|
||||
|
@ -106,7 +104,6 @@ public class ScanfFormatStringSecurityChecker extends AbstractIndexAstChecker {
|
|||
public int getFormatStringArgumentIndex() {
|
||||
return formatStringArgumentIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class FormatStringVisitor extends ASTVisitor {
|
||||
|
@ -121,22 +118,15 @@ public class ScanfFormatStringSecurityChecker extends AbstractIndexAstChecker {
|
|||
if (vulnerableFunction == null) {
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
IASTInitializerClause[] arguments = callExpression
|
||||
.getArguments();
|
||||
int stringArgumentIndex = vulnerableFunction
|
||||
.getFormatStringArgumentIndex();
|
||||
|
||||
detectFaulyArguments(callExpression, arguments,
|
||||
stringArgumentIndex);
|
||||
|
||||
IASTInitializerClause[] arguments = callExpression.getArguments();
|
||||
int stringArgumentIndex = vulnerableFunction.getFormatStringArgumentIndex();
|
||||
detectFaulyArguments(callExpression, arguments, stringArgumentIndex);
|
||||
}
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
|
||||
private VulnerableFunction getVulnerableFunctionForExpression(
|
||||
IASTFunctionCallExpression callExpression) {
|
||||
String rawSignature = callExpression.getFunctionNameExpression()
|
||||
.getRawSignature();
|
||||
private VulnerableFunction getVulnerableFunctionForExpression(IASTFunctionCallExpression callExpression) {
|
||||
String rawSignature = callExpression.getFunctionNameExpression().getRawSignature();
|
||||
for (int i = 0; i < VULNERABLE_FUNCTIONS.length; i++) {
|
||||
if (VULNERABLE_FUNCTIONS[i].getName().equals(rawSignature)) {
|
||||
return VULNERABLE_FUNCTIONS[i];
|
||||
|
@ -145,57 +135,41 @@ public class ScanfFormatStringSecurityChecker extends AbstractIndexAstChecker {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void detectFaulyArguments(
|
||||
IASTFunctionCallExpression callExpression,
|
||||
IASTInitializerClause[] arguments, int formatStringArgumentIndex) {
|
||||
private void detectFaulyArguments(IASTFunctionCallExpression callExpression, IASTInitializerClause[] arguments,
|
||||
int formatStringArgumentIndex) {
|
||||
final IASTInitializerClause formatArgument = arguments[formatStringArgumentIndex];
|
||||
final String formatArgumentValue = formatArgument.getRawSignature();
|
||||
final CFormatStringParser formatStringParser = new CFormatStringParser(
|
||||
formatArgumentValue);
|
||||
|
||||
final CFormatStringParser formatStringParser = new CFormatStringParser(formatArgumentValue);
|
||||
if (!formatStringParser.isVulnerable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// match arguments;
|
||||
final Iterator<VulnerableFormatStringArgument> vulnerableArgumentsIterator = formatStringParser
|
||||
.getVulnerableArgumentsIterator();
|
||||
|
||||
while (vulnerableArgumentsIterator.hasNext()) {
|
||||
final VulnerableFormatStringArgument currentArgument = vulnerableArgumentsIterator
|
||||
.next();
|
||||
final VulnerableFormatStringArgument currentArgument = vulnerableArgumentsIterator.next();
|
||||
final int argumentIndex = currentArgument.getArgumentIndex();
|
||||
final int argumentSize = currentArgument.getArgumentSize();
|
||||
|
||||
if (argumentSize == CFormatStringParser.ARGUMENT_SIZE_NOT_SPECIFIED) {
|
||||
reportProblem(ER_ID, callExpression,
|
||||
callExpression.getRawSignature());
|
||||
reportProblem(ER_ID, callExpression, callExpression.getRawSignature());
|
||||
}
|
||||
|
||||
// else there some size is specified, so it should be less than
|
||||
// or equal
|
||||
// the size of the string variable.
|
||||
int suspectArgumentIndex = 1 + formatStringArgumentIndex
|
||||
+ argumentIndex;
|
||||
int suspectArgumentIndex = 1 + formatStringArgumentIndex + argumentIndex;
|
||||
IASTInitializerClause suspectArgument = arguments[suspectArgumentIndex];
|
||||
|
||||
if (suspectArgument instanceof IASTIdExpression) {
|
||||
final IASTIdExpression idExpression = (IASTIdExpression) suspectArgument;
|
||||
|
||||
IType expressionType = idExpression.getExpressionType();
|
||||
if (expressionType instanceof IArrayType) {
|
||||
IArrayType arrayExpressionType = (IArrayType) expressionType;
|
||||
long arraySize = arrayExpressionType.getSize()
|
||||
.numericalValue().longValue();
|
||||
|
||||
long arraySize = arrayExpressionType.getSize().numericalValue().longValue();
|
||||
if (argumentSize > arraySize) {
|
||||
reportProblem(ER_ID, idExpression,
|
||||
idExpression.getRawSignature());
|
||||
reportProblem(ER_ID, idExpression, idExpression.getRawSignature());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,23 +15,20 @@ package org.eclipse.cdt.codan.internal.checkers.fs;
|
|||
* @author Meisam Fathi
|
||||
*/
|
||||
public class VulnerableFormatStringArgument {
|
||||
|
||||
/**
|
||||
* The index of the argument that is matched, starting at zero.
|
||||
*/
|
||||
private final int indexOfArgument;
|
||||
|
||||
/**
|
||||
* The string format argument that may contain the fault
|
||||
*/
|
||||
private final String argument;
|
||||
|
||||
/**
|
||||
* the size of the argument.
|
||||
* <ul>
|
||||
* <li><code>%15s ==> 15 </code>
|
||||
* <li><code>%15s ==> 15 </code>
|
||||
* <li><code>%128s ==> 128 </code>
|
||||
* <li><code>%s ==> infinity </code>
|
||||
* <li><code>%s ==> infinity </code>
|
||||
* </ul>
|
||||
*/
|
||||
private final int size;
|
||||
|
@ -40,8 +37,7 @@ public class VulnerableFormatStringArgument {
|
|||
* @param indexOfCurrentArgument
|
||||
* @param group
|
||||
*/
|
||||
public VulnerableFormatStringArgument(final int indexOfArgument,
|
||||
final String rgument, final int size) {
|
||||
public VulnerableFormatStringArgument(final int indexOfArgument, final String rgument, final int size) {
|
||||
this.indexOfArgument = indexOfArgument;
|
||||
this.argument = rgument;
|
||||
this.size = size;
|
||||
|
@ -67,5 +63,4 @@ public class VulnerableFormatStringArgument {
|
|||
public int getArgumentSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,13 +19,11 @@ import org.osgi.framework.BundleContext;
|
|||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class Activator extends Plugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "org.eclipse.cdt.codan.core.cxx"; //$NON-NLS-1$
|
||||
|
||||
// The shared instance
|
||||
private static Activator plugin;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
|
@ -34,7 +32,9 @@ public class Activator extends Plugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
|
@ -43,7 +43,9 @@ public class Activator extends Plugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
|
@ -52,17 +54,18 @@ public class Activator extends Plugin {
|
|||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static Activator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the specified status with this plug-in's log.
|
||||
*
|
||||
* @param status
|
||||
* status to log
|
||||
* status to log
|
||||
*/
|
||||
public static void log(IStatus status) {
|
||||
getDefault().getLog().log(status);
|
||||
|
@ -72,7 +75,7 @@ public class Activator extends Plugin {
|
|||
* Logs an internal error with the specified throwable
|
||||
*
|
||||
* @param e
|
||||
* the exception to be logged
|
||||
* the exception to be logged
|
||||
*/
|
||||
public static void log(Throwable e) {
|
||||
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, "Internal Error", e)); //$NON-NLS-1$
|
||||
|
@ -82,7 +85,7 @@ public class Activator extends Plugin {
|
|||
* Logs an internal error with the specified message.
|
||||
*
|
||||
* @param message
|
||||
* the error message to log
|
||||
* the error message to log
|
||||
*/
|
||||
public static void log(String message) {
|
||||
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, message, null));
|
||||
|
|
|
@ -59,11 +59,8 @@ import org.eclipse.core.runtime.Path;
|
|||
* Useful functions for doing code analysis on c/c++ AST
|
||||
*/
|
||||
public final class CxxAstUtils {
|
||||
|
||||
public static class NameFinderVisitor extends ASTVisitor {
|
||||
|
||||
public IASTName name;
|
||||
|
||||
{
|
||||
shouldVisitNames = true;
|
||||
}
|
||||
|
@ -74,7 +71,6 @@ public final class CxxAstUtils {
|
|||
return PROCESS_ABORT;
|
||||
}
|
||||
}
|
||||
|
||||
private static CxxAstUtils instance;
|
||||
|
||||
private CxxAstUtils() {
|
||||
|
@ -107,13 +103,10 @@ public final class CxxAstUtils {
|
|||
}
|
||||
|
||||
public boolean isInMacro(IASTNode node) {
|
||||
IASTNodeSelector nodeSelector = node.getTranslationUnit()
|
||||
.getNodeSelector(node.getTranslationUnit().getFilePath());
|
||||
IASTNodeSelector nodeSelector = node.getTranslationUnit().getNodeSelector(node.getTranslationUnit().getFilePath());
|
||||
IASTFileLocation fileLocation = node.getFileLocation();
|
||||
|
||||
IASTPreprocessorMacroExpansion macro = nodeSelector
|
||||
.findEnclosingMacroExpansion(fileLocation.getNodeOffset(),
|
||||
fileLocation.getNodeLength());
|
||||
IASTPreprocessorMacroExpansion macro = nodeSelector.findEnclosingMacroExpansion(fileLocation.getNodeOffset(),
|
||||
fileLocation.getNodeLength());
|
||||
return macro != null;
|
||||
}
|
||||
|
||||
|
@ -124,8 +117,7 @@ public final class CxxAstUtils {
|
|||
return (IASTFunctionDefinition) node;
|
||||
}
|
||||
|
||||
public IASTCompositeTypeSpecifier getEnclosingCompositeTypeSpecifier(
|
||||
IASTNode node) {
|
||||
public IASTCompositeTypeSpecifier getEnclosingCompositeTypeSpecifier(IASTNode node) {
|
||||
while (node != null && !(node instanceof IASTCompositeTypeSpecifier)) {
|
||||
node = node.getParent();
|
||||
}
|
||||
|
@ -141,47 +133,36 @@ public final class CxxAstUtils {
|
|||
|
||||
/**
|
||||
* @param astName
|
||||
* a name for the declaration
|
||||
* a name for the declaration
|
||||
* @param factory
|
||||
* the factory
|
||||
* @param index
|
||||
* the factory
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public IASTDeclaration createDeclaration(IASTName astName,
|
||||
INodeFactory factory, IIndex index) {
|
||||
|
||||
public IASTDeclaration createDeclaration(IASTName astName, INodeFactory factory, IIndex index) {
|
||||
// Depending on context, either a type or a declaration is easier to
|
||||
// infer
|
||||
|
||||
IType inferredType = null;
|
||||
IASTSimpleDeclaration declaration = null;
|
||||
|
||||
inferredType = tryInferTypeFromBinaryExpr(astName);
|
||||
if (inferredType == null)
|
||||
declaration = tryInferTypeFromFunctionCall(astName, factory, index);
|
||||
|
||||
// After the inference, create the statement is needed
|
||||
|
||||
if (declaration != null) { // A declaration was generated
|
||||
return declaration;
|
||||
} else if (inferredType != null) { // A type was inferred, create the
|
||||
// declaration and return it
|
||||
DeclarationGenerator generator = DeclarationGenerator
|
||||
.create(factory);
|
||||
IASTDeclarator declarator = generator.createDeclaratorFromType(
|
||||
inferredType, astName.toCharArray());
|
||||
IASTDeclSpecifier declspec = generator
|
||||
.createDeclSpecFromType(inferredType);
|
||||
IASTSimpleDeclaration simpleDeclaration = factory
|
||||
.newSimpleDeclaration(declspec);
|
||||
DeclarationGenerator generator = DeclarationGenerator.create(factory);
|
||||
IASTDeclarator declarator = generator.createDeclaratorFromType(inferredType, astName.toCharArray());
|
||||
IASTDeclSpecifier declspec = generator.createDeclSpecFromType(inferredType);
|
||||
IASTSimpleDeclaration simpleDeclaration = factory.newSimpleDeclaration(declspec);
|
||||
simpleDeclaration.addDeclarator(declarator);
|
||||
return simpleDeclaration;
|
||||
} else { // Fallback - return a `void` declaration
|
||||
IASTDeclarator declarator = factory.newDeclarator(astName.copy());
|
||||
IASTSimpleDeclSpecifier declspec = factory.newSimpleDeclSpecifier();
|
||||
declspec.setType(Kind.eInt);
|
||||
IASTSimpleDeclaration simpleDeclaration = factory
|
||||
.newSimpleDeclaration(declspec);
|
||||
IASTSimpleDeclaration simpleDeclaration = factory.newSimpleDeclaration(declspec);
|
||||
simpleDeclaration.addDeclarator(declarator);
|
||||
return simpleDeclaration;
|
||||
}
|
||||
|
@ -194,8 +175,7 @@ public final class CxxAstUtils {
|
|||
* @return inferred type or null if couldn't infer
|
||||
*/
|
||||
private IType tryInferTypeFromBinaryExpr(IASTName astName) {
|
||||
if (astName.getParent() instanceof IASTIdExpression
|
||||
&& astName.getParent().getParent() instanceof IASTBinaryExpression) {
|
||||
if (astName.getParent() instanceof IASTIdExpression && astName.getParent().getParent() instanceof IASTBinaryExpression) {
|
||||
IASTNode binaryExpr = astName.getParent().getParent();
|
||||
for (IASTNode node : binaryExpr.getChildren()) {
|
||||
if (node != astName.getParent()) {
|
||||
|
@ -210,28 +190,23 @@ public final class CxxAstUtils {
|
|||
/**
|
||||
* For a function call, tries to find a matching function declaration.
|
||||
* Checks the argument count.
|
||||
* @param index
|
||||
*
|
||||
* @param index
|
||||
*
|
||||
* @return a generated declaration or null if not suitable
|
||||
*/
|
||||
private IASTSimpleDeclaration tryInferTypeFromFunctionCall(
|
||||
IASTName astName, INodeFactory factory, IIndex index) {
|
||||
if (astName.getParent() instanceof IASTIdExpression
|
||||
&& astName.getParent().getParent() instanceof IASTFunctionCallExpression
|
||||
private IASTSimpleDeclaration tryInferTypeFromFunctionCall(IASTName astName, INodeFactory factory, IIndex index) {
|
||||
if (astName.getParent() instanceof IASTIdExpression && astName.getParent().getParent() instanceof IASTFunctionCallExpression
|
||||
&& astName.getParent().getPropertyInParent() == IASTFunctionCallExpression.ARGUMENT) {
|
||||
|
||||
IASTFunctionCallExpression call = (IASTFunctionCallExpression) astName
|
||||
.getParent().getParent();
|
||||
IASTFunctionCallExpression call = (IASTFunctionCallExpression) astName.getParent().getParent();
|
||||
NameFinderVisitor visitor = new NameFinderVisitor();
|
||||
call.getFunctionNameExpression().accept(visitor);
|
||||
IASTName funcname = visitor.name;
|
||||
|
||||
int expectedParametersNum = 0;
|
||||
int targetParameterNum = -1;
|
||||
for (IASTNode n : call.getChildren()) {
|
||||
if (n.getPropertyInParent() == IASTFunctionCallExpression.ARGUMENT) {
|
||||
if (n instanceof IASTIdExpression
|
||||
&& n.getChildren()[0] == astName) {
|
||||
if (n instanceof IASTIdExpression && n.getChildren()[0] == astName) {
|
||||
targetParameterNum = expectedParametersNum;
|
||||
}
|
||||
expectedParametersNum++;
|
||||
|
@ -240,13 +215,11 @@ public final class CxxAstUtils {
|
|||
if (targetParameterNum == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IBinding[] bindings;
|
||||
{
|
||||
IBinding binding = funcname.resolveBinding();
|
||||
if (binding instanceof IProblemBinding) {
|
||||
bindings = ((IProblemBinding) binding)
|
||||
.getCandidateBindings();
|
||||
bindings = ((IProblemBinding) binding).getCandidateBindings();
|
||||
} else {
|
||||
bindings = new IBinding[] { binding };
|
||||
}
|
||||
|
@ -266,44 +239,32 @@ public final class CxxAstUtils {
|
|||
}
|
||||
}
|
||||
for (IIndexName decl : declSet) {
|
||||
|
||||
// for now, just use the first overload found
|
||||
|
||||
ITranslationUnit tu = getTranslationUnitFromIndexName(decl);
|
||||
IASTName name = (IASTName) tu.getAST(null,
|
||||
ITranslationUnit.AST_SKIP_INDEXED_HEADERS)
|
||||
.getNodeSelector(null).findEnclosingNode(
|
||||
decl.getNodeOffset(), decl.getNodeLength());
|
||||
|
||||
IASTName name = (IASTName) tu.getAST(null, ITranslationUnit.AST_SKIP_INDEXED_HEADERS).getNodeSelector(null)
|
||||
.findEnclosingNode(decl.getNodeOffset(), decl.getNodeLength());
|
||||
IASTNode fdecl = name;
|
||||
while (fdecl instanceof IASTName) {
|
||||
fdecl = fdecl.getParent();
|
||||
}
|
||||
assert (fdecl instanceof IASTFunctionDeclarator);
|
||||
|
||||
// find the needed param number
|
||||
int nthParam = 0;
|
||||
for (IASTNode child : fdecl.getChildren()) {
|
||||
if (child instanceof IASTParameterDeclaration) {
|
||||
if (nthParam == targetParameterNum) {
|
||||
IASTParameterDeclaration pd = (IASTParameterDeclaration) child;
|
||||
IASTDeclSpecifier declspec = pd
|
||||
.getDeclSpecifier().copy();
|
||||
IASTDeclarator declarator = pd.getDeclarator()
|
||||
.copy();
|
||||
setNameInNestedDeclarator(declarator, astName
|
||||
.copy());
|
||||
IASTSimpleDeclaration declaration = factory
|
||||
.newSimpleDeclaration(declspec);
|
||||
IASTDeclSpecifier declspec = pd.getDeclSpecifier().copy();
|
||||
IASTDeclarator declarator = pd.getDeclarator().copy();
|
||||
setNameInNestedDeclarator(declarator, astName.copy());
|
||||
IASTSimpleDeclaration declaration = factory.newSimpleDeclaration(declspec);
|
||||
declaration.addDeclarator(declarator);
|
||||
return declaration;
|
||||
}
|
||||
nthParam++;
|
||||
}
|
||||
|
||||
}
|
||||
name.getParent();
|
||||
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// skip
|
||||
|
@ -312,25 +273,21 @@ public final class CxxAstUtils {
|
|||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setNameInNestedDeclarator(IASTDeclarator declarator,
|
||||
IASTName astName) {
|
||||
private void setNameInNestedDeclarator(IASTDeclarator declarator, IASTName astName) {
|
||||
while (declarator.getNestedDeclarator() != null) {
|
||||
declarator = declarator.getNestedDeclarator();
|
||||
}
|
||||
declarator.setName(astName);
|
||||
}
|
||||
|
||||
public ITranslationUnit getTranslationUnitFromIndexName(IIndexName decl)
|
||||
throws CoreException {
|
||||
public ITranslationUnit getTranslationUnitFromIndexName(IIndexName decl) throws CoreException {
|
||||
Path path = new Path(decl.getFile().getLocation().getFullPath());
|
||||
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
|
||||
ITranslationUnit tu = (ITranslationUnit) CoreModel.getDefault().create(
|
||||
file);
|
||||
ITranslationUnit tu = (ITranslationUnit) CoreModel.getDefault().create(file);
|
||||
return tu;
|
||||
}
|
||||
|
||||
|
@ -339,17 +296,14 @@ public final class CxxAstUtils {
|
|||
* Otherwise, returns null.
|
||||
*
|
||||
* @param function
|
||||
* the function definition to check
|
||||
* the function definition to check
|
||||
* @param index
|
||||
* the index to use for name lookup
|
||||
* the index to use for name lookup
|
||||
* @return Either a type specifier or null
|
||||
*/
|
||||
public IASTCompositeTypeSpecifier getCompositeTypeFromFunction(
|
||||
final IASTFunctionDefinition function, final IIndex index) {
|
||||
|
||||
public IASTCompositeTypeSpecifier getCompositeTypeFromFunction(final IASTFunctionDefinition function, final IIndex index) {
|
||||
// return value to be set via visitor
|
||||
final IASTCompositeTypeSpecifier returnSpecifier[] = { null };
|
||||
|
||||
function.accept(new ASTVisitor() {
|
||||
{
|
||||
shouldVisitDeclarators = true;
|
||||
|
@ -358,43 +312,31 @@ public final class CxxAstUtils {
|
|||
|
||||
@Override
|
||||
public int visit(IASTName name) {
|
||||
if (!(name instanceof ICPPASTQualifiedName && name.getParent()
|
||||
.getParent() == function))
|
||||
if (!(name instanceof ICPPASTQualifiedName && name.getParent().getParent() == function))
|
||||
return PROCESS_CONTINUE;
|
||||
|
||||
ICPPASTQualifiedName qname = (ICPPASTQualifiedName) name;
|
||||
|
||||
// A qualified name may have 1 name, but in our case needs to
|
||||
// have 2.
|
||||
// The pre-last name is either a namespace or a class.
|
||||
if (qname.getChildren().length < 2) {
|
||||
return PROCESS_CONTINUE;
|
||||
}
|
||||
IASTName namePart = (IASTName) qname.getChildren()[qname
|
||||
.getChildren().length - 2];
|
||||
|
||||
IASTName namePart = (IASTName) qname.getChildren()[qname.getChildren().length - 2];
|
||||
IBinding binding = namePart.resolveBinding();
|
||||
try {
|
||||
index.acquireReadLock();
|
||||
IIndexName[] declarations = index.findDeclarations(binding);
|
||||
|
||||
// Check the declarations and use first suitable
|
||||
for (IIndexName decl : declarations) {
|
||||
|
||||
ITranslationUnit tu = getTranslationUnitFromIndexName(decl);
|
||||
IASTNode node = tu.getAST(index,
|
||||
ITranslationUnit.AST_SKIP_INDEXED_HEADERS)
|
||||
.getNodeSelector(null).findEnclosingNode(
|
||||
decl.getNodeOffset(),
|
||||
decl.getNodeLength());
|
||||
IASTNode node = tu.getAST(index, ITranslationUnit.AST_SKIP_INDEXED_HEADERS).getNodeSelector(null)
|
||||
.findEnclosingNode(decl.getNodeOffset(), decl.getNodeLength());
|
||||
IASTCompositeTypeSpecifier specifier = getEnclosingCompositeTypeSpecifier(node);
|
||||
|
||||
if (specifier != null) {
|
||||
returnSpecifier[0] = specifier;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
return PROCESS_ABORT;
|
||||
} catch (CoreException e) {
|
||||
|
@ -403,14 +345,12 @@ public final class CxxAstUtils {
|
|||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
|
||||
return PROCESS_ABORT;
|
||||
}
|
||||
|
||||
});
|
||||
return returnSpecifier[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param body
|
||||
* @return
|
||||
|
@ -418,8 +358,7 @@ public final class CxxAstUtils {
|
|||
public boolean isThrowStatement(IASTNode body) {
|
||||
if (!(body instanceof IASTExpressionStatement))
|
||||
return false;
|
||||
IASTExpression expression = ((IASTExpressionStatement) body)
|
||||
.getExpression();
|
||||
IASTExpression expression = ((IASTExpressionStatement) body).getExpression();
|
||||
if (!(expression instanceof IASTUnaryExpression))
|
||||
return false;
|
||||
return ((IASTUnaryExpression) expression).getOperator() == IASTUnaryExpression.op_throw;
|
||||
|
@ -428,12 +367,10 @@ public final class CxxAstUtils {
|
|||
public boolean isExitStatement(IASTNode body) {
|
||||
if (!(body instanceof IASTExpressionStatement))
|
||||
return false;
|
||||
IASTExpression expression = ((IASTExpressionStatement) body)
|
||||
.getExpression();
|
||||
IASTExpression expression = ((IASTExpressionStatement) body).getExpression();
|
||||
if (!(expression instanceof IASTFunctionCallExpression))
|
||||
return false;
|
||||
IASTExpression functionNameExpression = ((IASTFunctionCallExpression) expression)
|
||||
.getFunctionNameExpression();
|
||||
IASTExpression functionNameExpression = ((IASTFunctionCallExpression) expression).getFunctionNameExpression();
|
||||
return functionNameExpression.getRawSignature().equals("exit"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,23 +25,20 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
*
|
||||
*/
|
||||
public class CxxCodanReconciler {
|
||||
private CodanBuilder builder = (CodanBuilder) CodanRuntime.getInstance()
|
||||
.getBuilder();
|
||||
private CodanBuilder builder = (CodanBuilder) CodanRuntime.getInstance().getBuilder();
|
||||
|
||||
public void reconciledAst(IASTTranslationUnit ast, IResource resource,
|
||||
IProgressMonitor monitor) {
|
||||
public void reconciledAst(IASTTranslationUnit ast, IResource resource, IProgressMonitor monitor) {
|
||||
if (ast == null)
|
||||
return;
|
||||
IProject project = resource.getProject();
|
||||
if (project==null) return;
|
||||
if (project == null)
|
||||
return;
|
||||
try {
|
||||
if (project.hasNature(CProjectNature.C_NATURE_ID)
|
||||
|| project.hasNature(CCProjectNature.CC_NATURE_ID)) {
|
||||
if (project.hasNature(CProjectNature.C_NATURE_ID) || project.hasNature(CCProjectNature.CC_NATURE_ID)) {
|
||||
builder.runInEditor(ast, resource, monitor);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,8 +86,7 @@ public class ControlFlowGraphBuilder {
|
|||
for (Iterator iterator = dead.iterator(); iterator.hasNext();) {
|
||||
IBasicBlock ds = (IBasicBlock) iterator.next();
|
||||
IBasicBlock dl = findLast(ds);
|
||||
if (dl != null && dl.getOutgoingSize() == 0
|
||||
&& dl != returnExit) {
|
||||
if (dl != null && dl.getOutgoingSize() == 0 && dl != returnExit) {
|
||||
((AbstractBasicBlock) dl).addOutgoing(returnExit);
|
||||
}
|
||||
}
|
||||
|
@ -124,9 +123,7 @@ public class ControlFlowGraphBuilder {
|
|||
IBasicBlock last = createSubGraph(prev, node);
|
||||
prev = last;
|
||||
}
|
||||
} else if (body instanceof IASTExpressionStatement
|
||||
|| body instanceof IASTDeclarationStatement
|
||||
|| body instanceof IASTNullStatement) {
|
||||
} else if (body instanceof IASTExpressionStatement || body instanceof IASTDeclarationStatement || body instanceof IASTNullStatement) {
|
||||
if (isThrowStatement(body) || isExitStatement(body)) {
|
||||
CxxExitNode node = createExitNode(prev, body);
|
||||
return node;
|
||||
|
@ -204,8 +201,7 @@ public class ControlFlowGraphBuilder {
|
|||
* @param body
|
||||
* @return
|
||||
*/
|
||||
private IBasicBlock createTry(IBasicBlock prev,
|
||||
ICPPASTTryBlockStatement body) {
|
||||
private IBasicBlock createTry(IBasicBlock prev, ICPPASTTryBlockStatement body) {
|
||||
DecisionNode ifNode = factory.createDecisionNode(body);
|
||||
addOutgoing(prev, ifNode);
|
||||
IConnectorNode mergeNode = factory.createConnectorNode();
|
||||
|
@ -217,11 +213,9 @@ public class ControlFlowGraphBuilder {
|
|||
ICPPASTCatchHandler[] catchHandlers = body.getCatchHandlers();
|
||||
for (int i = 0; i < catchHandlers.length; i++) {
|
||||
ICPPASTCatchHandler handler = catchHandlers[i];
|
||||
IBranchNode handlerNode = factory.createBranchNode(handler
|
||||
.getDeclaration());
|
||||
IBranchNode handlerNode = factory.createBranchNode(handler.getDeclaration());
|
||||
addOutgoing(ifNode, handlerNode);
|
||||
IBasicBlock els = createSubGraph(handlerNode,
|
||||
handler.getCatchBody());
|
||||
IBasicBlock els = createSubGraph(handlerNode, handler.getCatchBody());
|
||||
addJump(els, mergeNode);
|
||||
}
|
||||
return mergeNode;
|
||||
|
@ -234,8 +228,7 @@ public class ControlFlowGraphBuilder {
|
|||
private boolean isThrowStatement(IASTNode body) {
|
||||
if (!(body instanceof IASTExpressionStatement))
|
||||
return false;
|
||||
IASTExpression expression = ((IASTExpressionStatement) body)
|
||||
.getExpression();
|
||||
IASTExpression expression = ((IASTExpressionStatement) body).getExpression();
|
||||
if (!(expression instanceof IASTUnaryExpression))
|
||||
return false;
|
||||
return ((IASTUnaryExpression) expression).getOperator() == IASTUnaryExpression.op_throw;
|
||||
|
@ -244,12 +237,10 @@ public class ControlFlowGraphBuilder {
|
|||
private boolean isExitStatement(IASTNode body) {
|
||||
if (!(body instanceof IASTExpressionStatement))
|
||||
return false;
|
||||
IASTExpression expression = ((IASTExpressionStatement) body)
|
||||
.getExpression();
|
||||
IASTExpression expression = ((IASTExpressionStatement) body).getExpression();
|
||||
if (!(expression instanceof IASTFunctionCallExpression))
|
||||
return false;
|
||||
IASTExpression functionNameExpression = ((IASTFunctionCallExpression) expression)
|
||||
.getFunctionNameExpression();
|
||||
IASTExpression functionNameExpression = ((IASTFunctionCallExpression) expression).getFunctionNameExpression();
|
||||
return functionNameExpression.getRawSignature().equals("exit"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
|
@ -287,8 +278,7 @@ public class ControlFlowGraphBuilder {
|
|||
* @return
|
||||
*/
|
||||
protected IBasicBlock createIf(IBasicBlock prev, IASTIfStatement body) {
|
||||
DecisionNode ifNode = factory.createDecisionNode(body
|
||||
.getConditionExpression());
|
||||
DecisionNode ifNode = factory.createDecisionNode(body.getConditionExpression());
|
||||
addOutgoing(prev, ifNode);
|
||||
IConnectorNode mergeNode = factory.createConnectorNode();
|
||||
ifNode.setMergeNode(mergeNode);
|
||||
|
@ -309,8 +299,7 @@ public class ControlFlowGraphBuilder {
|
|||
* @return
|
||||
*/
|
||||
private IBasicBlock createSwitch(IBasicBlock prev, IASTSwitchStatement body) {
|
||||
DecisionNode node = factory.createDecisionNode(body
|
||||
.getControllerExpression());
|
||||
DecisionNode node = factory.createDecisionNode(body.getControllerExpression());
|
||||
addOutgoing(prev, node);
|
||||
IConnectorNode conn = factory.createConnectorNode();
|
||||
node.setMergeNode(conn);
|
||||
|
@ -324,8 +313,7 @@ public class ControlFlowGraphBuilder {
|
|||
* @param def
|
||||
* @param body
|
||||
*/
|
||||
private void createSwitchBody(DecisionNode switchNode,
|
||||
IConnectorNode mergeNode, IASTStatement body) {
|
||||
private void createSwitchBody(DecisionNode switchNode, IConnectorNode mergeNode, IASTStatement body) {
|
||||
if (!(body instanceof IASTCompoundStatement))
|
||||
return; // bad
|
||||
IASTCompoundStatement comp = (IASTCompoundStatement) body;
|
||||
|
@ -333,8 +321,7 @@ public class ControlFlowGraphBuilder {
|
|||
IBasicBlock prev = switchNode;
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
IASTNode elem = children[i];
|
||||
if (elem instanceof IASTCaseStatement
|
||||
|| elem instanceof IASTDefaultStatement) {
|
||||
if (elem instanceof IASTCaseStatement || elem instanceof IASTDefaultStatement) {
|
||||
IBranchNode lbl = null;
|
||||
if (elem instanceof IASTCaseStatement) {
|
||||
IASTCaseStatement caseSt = (IASTCaseStatement) elem;
|
||||
|
@ -370,16 +357,14 @@ public class ControlFlowGraphBuilder {
|
|||
*/
|
||||
private IBasicBlock createFor(IBasicBlock prev, IASTForStatement forNode) {
|
||||
// add initializer
|
||||
IPlainNode init = factory.createPlainNode(forNode
|
||||
.getInitializerStatement());
|
||||
IPlainNode init = factory.createPlainNode(forNode.getInitializerStatement());
|
||||
addOutgoing(prev, init);
|
||||
prev = init;
|
||||
// add continue connector
|
||||
IConnectorNode beforeCheck = factory.createConnectorNode();
|
||||
addOutgoing(prev, beforeCheck);
|
||||
// decision node
|
||||
CxxDecisionNode decision = factory.createDecisionNode(forNode
|
||||
.getConditionExpression());
|
||||
CxxDecisionNode decision = factory.createDecisionNode(forNode.getConditionExpression());
|
||||
addOutgoing(beforeCheck, decision);
|
||||
// add break connector
|
||||
IConnectorNode nBreak = factory.createConnectorNode();
|
||||
|
@ -397,8 +382,7 @@ public class ControlFlowGraphBuilder {
|
|||
outerContinue = savedContinue;
|
||||
outerBreak = savedBreak;
|
||||
// inc
|
||||
IPlainNode inc = factory.createPlainNode(forNode
|
||||
.getIterationExpression());
|
||||
IPlainNode inc = factory.createPlainNode(forNode.getIterationExpression());
|
||||
addOutgoing(endBody, nContinue);
|
||||
addOutgoing(nContinue, inc);
|
||||
// connect with backward link
|
||||
|
@ -420,8 +404,7 @@ public class ControlFlowGraphBuilder {
|
|||
IConnectorNode nContinue = factory.createConnectorNode();
|
||||
addOutgoing(prev, nContinue);
|
||||
// decision node
|
||||
CxxDecisionNode decision = factory.createDecisionNode(body
|
||||
.getCondition());
|
||||
CxxDecisionNode decision = factory.createDecisionNode(body.getCondition());
|
||||
addOutgoing(nContinue, decision);
|
||||
// add break connector
|
||||
IConnectorNode nBreak = factory.createConnectorNode();
|
||||
|
@ -465,8 +448,7 @@ public class ControlFlowGraphBuilder {
|
|||
// add continue connector
|
||||
addOutgoing(endBody, nContinue);
|
||||
// decision node
|
||||
CxxDecisionNode decision = factory.createDecisionNode(body
|
||||
.getCondition());
|
||||
CxxDecisionNode decision = factory.createDecisionNode(body.getCondition());
|
||||
addOutgoing(nContinue, decision);
|
||||
// then branch
|
||||
IBranchNode thenNode = factory.createBranchNode(IBranchNode.THEN);
|
||||
|
@ -489,8 +471,7 @@ public class ControlFlowGraphBuilder {
|
|||
return addJump(prev, conn, false);
|
||||
}
|
||||
|
||||
private IJumpNode addJump(IBasicBlock prev, IConnectorNode conn,
|
||||
boolean backward) {
|
||||
private IJumpNode addJump(IBasicBlock prev, IConnectorNode conn, boolean backward) {
|
||||
if (prev instanceof IJumpNode)
|
||||
return (IJumpNode) prev;
|
||||
if (prev instanceof IExitNode)
|
||||
|
|
|
@ -19,8 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
public class CxxBranchNode extends BranchNode {
|
||||
private IASTNode labelData;
|
||||
|
||||
|
||||
CxxBranchNode(IASTNode label) {
|
||||
CxxBranchNode(IASTNode label) {
|
||||
super(label.getRawSignature());
|
||||
this.labelData = label;
|
||||
}
|
||||
|
@ -32,6 +31,6 @@ public class CxxBranchNode extends BranchNode {
|
|||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return labelData.getRawSignature()+":"; //$NON-NLS-1$
|
||||
return labelData.getRawSignature() + ":"; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,10 @@ public class CxxControlFlowGraph extends ControlFlowGraph {
|
|||
public static CxxControlFlowGraph build(IASTFunctionDefinition def) {
|
||||
return new ControlFlowGraphBuilder().build(def);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
|
@ -41,5 +43,4 @@ public class CxxControlFlowGraph extends ControlFlowGraph {
|
|||
// TODO Auto-generated method stub
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
public class CxxDecisionNode extends DecisionNode {
|
||||
/**
|
||||
* @param node
|
||||
* the node to set
|
||||
* the node to set
|
||||
*/
|
||||
public void setNode(IASTNode node) {
|
||||
setData(node);
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
public class CxxExitNode extends ExitNode implements IExitNode {
|
||||
/**
|
||||
* @param node
|
||||
* the node to set
|
||||
* the node to set
|
||||
*/
|
||||
public void setNode(IASTNode node) {
|
||||
setData(node);
|
||||
|
|
|
@ -17,11 +17,9 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|||
* TODO: add description
|
||||
*/
|
||||
public class CxxPlainNode extends PlainNode {
|
||||
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* the node to set
|
||||
* the node to set
|
||||
*/
|
||||
public void setNode(IASTNode node) {
|
||||
setData(node);
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Alena Laskavaia - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.core.cxx.internal.model.cfg;
|
||||
|
||||
import org.eclipse.cdt.codan.internal.core.cfg.StartNode;
|
||||
|
@ -17,15 +16,16 @@ import org.eclipse.cdt.codan.internal.core.cfg.StartNode;
|
|||
* TODO: add description
|
||||
*/
|
||||
public class CxxStartNode extends StartNode {
|
||||
|
||||
/**
|
||||
* @param next
|
||||
*/
|
||||
public CxxStartNode() {
|
||||
super();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
|
|
|
@ -19,8 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|||
/**
|
||||
* Abstract class for checkers that do all the work on function definition level
|
||||
*/
|
||||
public abstract class AbstractAstFunctionChecker extends
|
||||
AbstractIndexAstChecker implements ICheckerWithPreferences {
|
||||
public abstract class AbstractAstFunctionChecker extends AbstractIndexAstChecker implements ICheckerWithPreferences {
|
||||
public void processAst(IASTTranslationUnit ast) {
|
||||
// traverse the ast using the visitor pattern.
|
||||
ast.accept(new ASTVisitor() {
|
||||
|
@ -30,7 +29,7 @@ public abstract class AbstractAstFunctionChecker extends
|
|||
|
||||
public int visit(IASTDeclaration element) {
|
||||
if (element instanceof IASTFunctionDefinition) {
|
||||
processFunction((IASTFunctionDefinition) element);
|
||||
processFunction((IASTFunctionDefinition) element);
|
||||
}
|
||||
// visit all nodes to support inner functions within class definitions
|
||||
// and gcc extensions
|
||||
|
@ -43,9 +42,7 @@ public abstract class AbstractAstFunctionChecker extends
|
|||
* Process function.
|
||||
*
|
||||
* @param func
|
||||
* - ast node representing function definition
|
||||
* - ast node representing function definition
|
||||
*/
|
||||
protected abstract void processFunction(IASTFunctionDefinition func);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,10 +34,11 @@ public abstract class AbstractCIndexChecker extends AbstractCheckerWithProblemPr
|
|||
return file;
|
||||
}
|
||||
|
||||
void processFile(IFile file) throws CoreException, InterruptedException {
|
||||
void processFile(IFile file) throws CoreException, InterruptedException {
|
||||
// create translation unit and access index
|
||||
ICElement model = CoreModel.getDefault().create(file);
|
||||
if (!(model instanceof ITranslationUnit)) return; // not a C/C++ file
|
||||
if (!(model instanceof ITranslationUnit))
|
||||
return; // not a C/C++ file
|
||||
ITranslationUnit tu = (ITranslationUnit) model;
|
||||
index = CCorePlugin.getIndexManager().getIndex(tu.getCProject());
|
||||
// lock the index for read access
|
||||
|
|
|
@ -33,8 +33,8 @@ import org.eclipse.core.runtime.Path;
|
|||
*
|
||||
* Clients may extend this class.
|
||||
*/
|
||||
public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblemPreferences implements
|
||||
ICAstChecker, IRunnableInEditorChecker {
|
||||
public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblemPreferences implements ICAstChecker,
|
||||
IRunnableInEditorChecker {
|
||||
private IFile file;
|
||||
|
||||
protected IFile getFile() {
|
||||
|
@ -63,7 +63,8 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
|
|||
}
|
||||
|
||||
public synchronized boolean processResource(IResource resource) {
|
||||
if (!shouldProduceProblems(resource)) return false;
|
||||
if (!shouldProduceProblems(resource))
|
||||
return false;
|
||||
if (resource instanceof IFile) {
|
||||
IFile file = (IFile) resource;
|
||||
try {
|
||||
|
@ -82,8 +83,7 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
|
|||
public void reportProblem(String id, IASTNode astNode, Object... args) {
|
||||
IASTFileLocation astLocation = astNode.getFileLocation();
|
||||
IPath location = new Path(astLocation.getFileName());
|
||||
IFile astFile = ResourceLookup.selectFileForLocation(location,
|
||||
getProject());
|
||||
IFile astFile = ResourceLookup.selectFileForLocation(location, getProject());
|
||||
if (astFile == null) {
|
||||
astFile = file;
|
||||
}
|
||||
|
@ -94,15 +94,10 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
|
|||
IProblemLocation loc;
|
||||
int line = astLocation.getStartingLineNumber();
|
||||
if (line == astLocation.getEndingLineNumber())
|
||||
loc = getRuntime().getProblemLocationFactory()
|
||||
.createProblemLocation(
|
||||
astFile,
|
||||
astLocation.getNodeOffset(),
|
||||
astLocation.getNodeOffset()
|
||||
+ astLocation.getNodeLength(), line);
|
||||
loc = getRuntime().getProblemLocationFactory().createProblemLocation(astFile, astLocation.getNodeOffset(),
|
||||
astLocation.getNodeOffset() + astLocation.getNodeLength(), line);
|
||||
else
|
||||
loc = getRuntime().getProblemLocationFactory()
|
||||
.createProblemLocation(astFile, line);
|
||||
loc = getRuntime().getProblemLocationFactory().createProblemLocation(astFile, line);
|
||||
reportProblem(id, loc, args);
|
||||
}
|
||||
|
||||
|
@ -121,11 +116,10 @@ public abstract class AbstractIndexAstChecker extends AbstractCheckerWithProblem
|
|||
@SuppressWarnings("restriction")
|
||||
public synchronized void processModel(Object model) {
|
||||
if (model instanceof IASTTranslationUnit) {
|
||||
CxxModelsCache.getInstance().clearCash();
|
||||
CxxModelsCache.getInstance().clearCash();
|
||||
IASTTranslationUnit ast = (IASTTranslationUnit) model;
|
||||
IPath location = new Path(ast.getFilePath());
|
||||
IFile astFile = ResourceLookup.selectFileForLocation(location,
|
||||
getProject());
|
||||
IFile astFile = ResourceLookup.selectFileForLocation(location, getProject());
|
||||
file = astFile;
|
||||
processAst(ast);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,6 @@ public class CxxModelsCache {
|
|||
private ITranslationUnit tu;
|
||||
private IIndex index;
|
||||
private WeakHashMap<IASTFunctionDefinition, IControlFlowGraph> cfgmap = new WeakHashMap<IASTFunctionDefinition, IControlFlowGraph>(0);
|
||||
|
||||
private static CxxModelsCache instance = new CxxModelsCache();
|
||||
|
||||
public static CxxModelsCache getInstance() {
|
||||
|
@ -42,20 +41,20 @@ public class CxxModelsCache {
|
|||
|
||||
public synchronized IControlFlowGraph getControlFlowGraph(IASTFunctionDefinition func) {
|
||||
IControlFlowGraph cfg = cfgmap.get(func);
|
||||
if (cfg!=null) return cfg;
|
||||
if (cfg != null)
|
||||
return cfg;
|
||||
cfg = CxxControlFlowGraph.build(func);
|
||||
if (cfgmap.size()>20) { // if too many function better drop the cash XXX should be LRU
|
||||
if (cfgmap.size() > 20) { // if too many function better drop the cash XXX should be LRU
|
||||
cfgmap.clear();
|
||||
}
|
||||
cfgmap.put(func, cfg);
|
||||
return cfg;
|
||||
}
|
||||
public synchronized IASTTranslationUnit getAst(IFile file)
|
||||
throws CoreException, InterruptedException {
|
||||
|
||||
public synchronized IASTTranslationUnit getAst(IFile file) throws CoreException, InterruptedException {
|
||||
if (file.equals(this.file)) {
|
||||
return ast;
|
||||
}
|
||||
|
||||
// create translation unit and access index
|
||||
ICElement celement = CoreModel.getDefault().create(file);
|
||||
if (!(celement instanceof ITranslationUnit))
|
||||
|
@ -88,8 +87,7 @@ public class CxxModelsCache {
|
|||
index = null;
|
||||
}
|
||||
|
||||
public synchronized IIndex getIndex(IFile file)
|
||||
throws CoreException, InterruptedException {
|
||||
public synchronized IIndex getIndex(IFile file) throws CoreException, InterruptedException {
|
||||
if (file.equals(this.file)) {
|
||||
return index;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,8 @@ import org.eclipse.cdt.codan.core.model.IChecker;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
|
||||
/**
|
||||
* Checker that can/want to process C/C++ AST (Abstract Syntax Tree) of a program
|
||||
* Checker that can/want to process C/C++ AST (Abstract Syntax Tree) of a
|
||||
* program
|
||||
* Default implementation {@link AbstractIndexAstChecker}
|
||||
*
|
||||
* Clients may implement and extend this interface.
|
||||
|
@ -28,8 +29,9 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|||
public interface ICAstChecker extends IChecker {
|
||||
/**
|
||||
* Run this checker on a given ast.
|
||||
* Ast locks would be obtained by the framework before calling this method.
|
||||
* @param ast
|
||||
* Ast locks would be obtained by the framework before calling this method.
|
||||
*
|
||||
* @param ast
|
||||
*/
|
||||
void processAst(IASTTranslationUnit ast);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
|
|||
public interface ICIndexChecker extends IChecker {
|
||||
/**
|
||||
* Run checker on translation unit
|
||||
*
|
||||
* @param unit - translation unit
|
||||
*/
|
||||
void processUnit(ITranslationUnit unit);
|
||||
|
|
|
@ -51,8 +51,7 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
|
|||
@Override
|
||||
public int visit(IASTDeclaration decl) {
|
||||
if (decl instanceof IASTFunctionDefinition) {
|
||||
graph = new ControlFlowGraphBuilder()
|
||||
.build((IASTFunctionDefinition) decl);
|
||||
graph = new ControlFlowGraphBuilder().build((IASTFunctionDefinition) decl);
|
||||
return PROCESS_ABORT;
|
||||
}
|
||||
return PROCESS_CONTINUE;
|
||||
|
@ -72,8 +71,7 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
|
|||
assertNotNull(graph);
|
||||
assertNotNull(graph.getStartNode());
|
||||
Collection<IBasicBlock> nodes = graph.getNodes();
|
||||
for (Iterator<IBasicBlock> iterator = nodes.iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<IBasicBlock> iterator = nodes.iterator(); iterator.hasNext();) {
|
||||
IBasicBlock node = iterator.next();
|
||||
checkNode(node, decision);
|
||||
}
|
||||
|
@ -88,8 +86,7 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
|
|||
IBasicBlock b = incomingNodes[i];
|
||||
if (b == null) {
|
||||
// check if dead node
|
||||
Iterator<IBasicBlock> iterator = graph
|
||||
.getUnconnectedNodeIterator();
|
||||
Iterator<IBasicBlock> iterator = graph.getUnconnectedNodeIterator();
|
||||
boolean dead = false;
|
||||
for (; iterator.hasNext();) {
|
||||
IBasicBlock d = iterator.next();
|
||||
|
@ -112,8 +109,7 @@ public class ControlFlowGraphTest extends CodanFastCxxAstTestCase {
|
|||
fail("Block " + node + " inconsitent next/prev " + b);
|
||||
}
|
||||
if (node instanceof IDecisionNode && decision) {
|
||||
assertTrue("decision node outgoing size " + node.getOutgoingSize(),
|
||||
node.getOutgoingSize() > 1);
|
||||
assertTrue("decision node outgoing size " + node.getOutgoingSize(), node.getOutgoingSize() > 1);
|
||||
assertNotNull(((IDecisionNode) node).getMergeNode());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,8 +63,7 @@ public class CxxAstUtilsTest extends CodanFastCxxAstTestCase {
|
|||
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl;
|
||||
IASTDeclSpecifier spec = sdecl.getDeclSpecifier();
|
||||
if (spec instanceof IASTNamedTypeSpecifier) {
|
||||
IASTName tname = ((IASTNamedTypeSpecifier) spec)
|
||||
.getName();
|
||||
IASTName tname = ((IASTNamedTypeSpecifier) spec).getName();
|
||||
IType typeName = (IType) tname.resolveBinding();
|
||||
result[0] = instance.unwindTypedef(typeName);
|
||||
}
|
||||
|
@ -96,9 +95,7 @@ public class CxxAstUtilsTest extends CodanFastCxxAstTestCase {
|
|||
@Override
|
||||
public int visit(IASTStatement stmt) {
|
||||
if (stmt instanceof IASTExpressionStatement) {
|
||||
boolean check = instance
|
||||
.isInMacro(((IASTExpressionStatement) stmt)
|
||||
.getExpression());
|
||||
boolean check = instance.isInMacro(((IASTExpressionStatement) stmt).getExpression());
|
||||
result[i] = check;
|
||||
i++;
|
||||
}
|
||||
|
|
|
@ -309,8 +309,7 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
|
|||
public void testGeneral1() {
|
||||
setEmpty(true);
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLines(4, 6, 7, 11, 14, 16, 19, 20, 24, 27, 32, 37, 41, 46,
|
||||
49, 51);
|
||||
checkErrorLines(4, 6, 7, 11, 14, 16, 19, 20, 24, 27, 32, 37, 41, 46, 49, 51);
|
||||
}
|
||||
|
||||
// void foo(void) {
|
||||
|
@ -429,14 +428,12 @@ public class CaseBreakCheckerTest extends CheckerTestCase {
|
|||
}
|
||||
|
||||
private void setLast(boolean val) {
|
||||
IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID,
|
||||
CaseBreakChecker.PARAM_LAST_CASE);
|
||||
IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID, CaseBreakChecker.PARAM_LAST_CASE);
|
||||
pref.setValue(val);
|
||||
}
|
||||
|
||||
private void setEmpty(boolean val) {
|
||||
IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID,
|
||||
CaseBreakChecker.PARAM_EMPTY_CASE);
|
||||
IProblemPreference pref = getPreference(CaseBreakChecker.ER_ID, CaseBreakChecker.PARAM_EMPTY_CASE);
|
||||
pref.setValue(val);
|
||||
}
|
||||
|
||||
|
|
|
@ -108,8 +108,7 @@ public class CatchByReferenceTest extends CheckerTestCase {
|
|||
// }
|
||||
// }
|
||||
public void test_class_unknown() {
|
||||
setPreferenceValue(CatchByReference.ER_ID,
|
||||
CatchByReference.PARAM_UNKNOWN_TYPE, false);
|
||||
setPreferenceValue(CatchByReference.ER_ID, CatchByReference.PARAM_UNKNOWN_TYPE, false);
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkNoErrors();
|
||||
}
|
||||
|
@ -121,8 +120,7 @@ public class CatchByReferenceTest extends CheckerTestCase {
|
|||
// }
|
||||
// }
|
||||
public void test_class_unknown_on() {
|
||||
setPreferenceValue(CatchByReference.ER_ID,
|
||||
CatchByReference.PARAM_UNKNOWN_TYPE, true);
|
||||
setPreferenceValue(CatchByReference.ER_ID, CatchByReference.PARAM_UNKNOWN_TYPE, true);
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLine(4);
|
||||
}
|
||||
|
|
|
@ -132,8 +132,7 @@ public class ReturnCheckerTest extends CheckerTestCase {
|
|||
// }
|
||||
// };
|
||||
public void testContructor_Bug323602() {
|
||||
IProblemPreference macro = getPreference(ReturnChecker.RET_NO_VALUE_ID,
|
||||
ReturnChecker.PARAM_IMPLICIT);
|
||||
IProblemPreference macro = getPreference(ReturnChecker.RET_NO_VALUE_ID, ReturnChecker.PARAM_IMPLICIT);
|
||||
macro.setValue(Boolean.TRUE);
|
||||
loadCodeAndRunCpp(getAboveComment());
|
||||
checkNoErrors();
|
||||
|
|
|
@ -13,7 +13,6 @@ package org.eclipse.cdt.codan.core.internal.checkers;
|
|||
import org.eclipse.cdt.codan.core.test.CheckerTestCase;
|
||||
|
||||
public class ReturnStyleCheckerTest extends CheckerTestCase {
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
|
|
@ -151,9 +151,7 @@ public class StatementHasNoEffectCheckerTest extends CheckerTestCase {
|
|||
// }
|
||||
@SuppressWarnings("restriction")
|
||||
public void testInMacro() {
|
||||
IProblemPreference macro = getPreference(
|
||||
StatementHasNoEffectChecker.ER_ID,
|
||||
StatementHasNoEffectChecker.PARAM_MACRO_ID);
|
||||
IProblemPreference macro = getPreference(StatementHasNoEffectChecker.ER_ID, StatementHasNoEffectChecker.PARAM_MACRO_ID);
|
||||
macro.setValue(Boolean.TRUE);
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLine(4);
|
||||
|
@ -177,9 +175,7 @@ public class StatementHasNoEffectCheckerTest extends CheckerTestCase {
|
|||
// }
|
||||
@SuppressWarnings("restriction")
|
||||
public void testInMacroParamOff() {
|
||||
IProblemPreference macro = getPreference(
|
||||
StatementHasNoEffectChecker.ER_ID,
|
||||
StatementHasNoEffectChecker.PARAM_MACRO_ID);
|
||||
IProblemPreference macro = getPreference(StatementHasNoEffectChecker.ER_ID, StatementHasNoEffectChecker.PARAM_MACRO_ID);
|
||||
macro.setValue(Boolean.FALSE);
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkNoErrors();
|
||||
|
|
|
@ -24,9 +24,7 @@ public class SuggestedParenthesisCheckerTest extends CheckerTestCase {
|
|||
// if (!a<10) b=4; // error here on line 3
|
||||
// }
|
||||
public void test1() {
|
||||
IProblemPreference macro = getPreference(
|
||||
SuggestedParenthesisChecker.ER_ID,
|
||||
SuggestedParenthesisChecker.PARAM_NOT);
|
||||
IProblemPreference macro = getPreference(SuggestedParenthesisChecker.ER_ID, SuggestedParenthesisChecker.PARAM_NOT);
|
||||
macro.setValue(Boolean.TRUE);
|
||||
loadCodeAndRun(getAboveComment());
|
||||
checkErrorLine(3);
|
||||
|
|
|
@ -67,9 +67,7 @@ public class CheckerTestCase extends CodanTestCase {
|
|||
m = markers[j];
|
||||
line = getLine(m);
|
||||
mfile = m.getResource().getName();
|
||||
if (line.equals(expectedLine)
|
||||
&& (problemId == null || problemId
|
||||
.equals(CodanProblemMarker.getProblemId(m)))) {
|
||||
if (line.equals(expectedLine) && (problemId == null || problemId.equals(CodanProblemMarker.getProblemId(m)))) {
|
||||
found = true;
|
||||
if (file != null && !file.getName().equals(mfile))
|
||||
found = false;
|
||||
|
@ -111,8 +109,7 @@ public class CheckerTestCase extends CodanTestCase {
|
|||
// all good
|
||||
} else {
|
||||
IMarker m = markers[0];
|
||||
fail("Found " + markers.length + " errors but should not. First "
|
||||
+ CodanProblemMarker.getProblemId(m) + " at line "
|
||||
fail("Found " + markers.length + " errors but should not. First " + CodanProblemMarker.getProblemId(m) + " at line "
|
||||
+ getLine(m));
|
||||
}
|
||||
}
|
||||
|
@ -143,16 +140,9 @@ public class CheckerTestCase extends CodanTestCase {
|
|||
*
|
||||
*/
|
||||
protected void runCodan() {
|
||||
CodanRuntime
|
||||
.getInstance()
|
||||
.getBuilder()
|
||||
.processResource(cproject.getProject(),
|
||||
new NullProgressMonitor());
|
||||
CodanRuntime.getInstance().getBuilder().processResource(cproject.getProject(), new NullProgressMonitor());
|
||||
try {
|
||||
markers = cproject.getProject()
|
||||
.findMarkers(
|
||||
IProblemReporter.GENERIC_CODE_ANALYSIS_MARKER_TYPE,
|
||||
true, 1);
|
||||
markers = cproject.getProject().findMarkers(IProblemReporter.GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, 1);
|
||||
} catch (CoreException e) {
|
||||
fail(e.getMessage());
|
||||
}
|
||||
|
@ -164,16 +154,13 @@ public class CheckerTestCase extends CodanTestCase {
|
|||
* @return
|
||||
*/
|
||||
protected IProblemPreference getPreference(String problemId, String paramId) {
|
||||
IProblem problem = CodanRuntime.getInstance().getCheckersRegistry()
|
||||
.getResourceProfile(cproject.getResource())
|
||||
IProblem problem = CodanRuntime.getInstance().getCheckersRegistry().getResourceProfile(cproject.getResource())
|
||||
.findProblem(problemId);
|
||||
IProblemPreference pref = ((MapProblemPreference) problem
|
||||
.getPreference()).getChildDescriptor(paramId);
|
||||
IProblemPreference pref = ((MapProblemPreference) problem.getPreference()).getChildDescriptor(paramId);
|
||||
return pref;
|
||||
}
|
||||
|
||||
protected IProblemPreference setPreferenceValue(String problemId,
|
||||
String paramId, Object value) {
|
||||
protected IProblemPreference setPreferenceValue(String problemId, String paramId, Object value) {
|
||||
IProblemPreference param = getPreference(problemId, paramId);
|
||||
param.setValue(value);
|
||||
return param;
|
||||
|
@ -196,8 +183,7 @@ public class CheckerTestCase extends CodanTestCase {
|
|||
}
|
||||
|
||||
protected void enableProblems(String... ids) {
|
||||
IProblemProfile profile = CodanRuntime.getInstance()
|
||||
.getCheckersRegistry().getWorkspaceProfile();
|
||||
IProblemProfile profile = CodanRuntime.getInstance().getCheckersRegistry().getWorkspaceProfile();
|
||||
IProblem[] problems = profile.getProblems();
|
||||
for (int i = 0; i < problems.length; i++) {
|
||||
IProblem p = problems[i];
|
||||
|
@ -210,8 +196,7 @@ public class CheckerTestCase extends CodanTestCase {
|
|||
}
|
||||
}
|
||||
}
|
||||
CodanRuntime.getInstance().getCheckersRegistry()
|
||||
.updateProfile(cproject.getProject(), profile);
|
||||
CodanRuntime.getInstance().getCheckersRegistry().updateProfile(cproject.getProject(), profile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.osgi.framework.BundleContext;
|
|||
public class CodanCoreTestActivator extends Plugin {
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "org.eclipse.cdt.codan.core.test"; //$NON-NLS-1$
|
||||
|
||||
// The shared instance
|
||||
private static CodanCoreTestActivator plugin;
|
||||
|
||||
|
@ -31,7 +30,9 @@ public class CodanCoreTestActivator extends Plugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
@Override
|
||||
public void start(BundleContext context) throws Exception {
|
||||
|
@ -41,7 +42,9 @@ public class CodanCoreTestActivator extends Plugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
|
@ -51,7 +54,7 @@ public class CodanCoreTestActivator extends Plugin {
|
|||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static CodanCoreTestActivator getDefault() {
|
||||
|
|
|
@ -57,9 +57,7 @@ public abstract class CodanFastCxxAstTestCase extends TestCase {
|
|||
protected StringBuffer[] getContents(int sections) {
|
||||
try {
|
||||
CodanCoreTestActivator plugin = CodanCoreTestActivator.getDefault();
|
||||
return TestSourceReader.getContentsForTest(plugin == null ? null
|
||||
: plugin.getBundle(), "src", getClass(), getName(),
|
||||
sections);
|
||||
return TestSourceReader.getContentsForTest(plugin == null ? null : plugin.getBundle(), "src", getClass(), getName(), sections);
|
||||
} catch (IOException e) {
|
||||
fail(e.getMessage());
|
||||
return null;
|
||||
|
@ -73,18 +71,16 @@ public abstract class CodanFastCxxAstTestCase extends TestCase {
|
|||
|
||||
/**
|
||||
* @return
|
||||
*
|
||||
*
|
||||
*/
|
||||
public IASTTranslationUnit parse(String code) {
|
||||
return parse(code, isCpp() ? ParserLanguage.CPP : ParserLanguage.C,
|
||||
true);
|
||||
return parse(code, isCpp() ? ParserLanguage.CPP : ParserLanguage.C, true);
|
||||
}
|
||||
|
||||
protected IASTTranslationUnit parse(String code, ParserLanguage lang, boolean gcc) {
|
||||
FileContent codeReader = FileContent.create("code.c", code.toCharArray());
|
||||
IScannerInfo scannerInfo = new ScannerInfo();
|
||||
IScanner scanner = AST2BaseTest.createScanner(codeReader, lang,
|
||||
ParserMode.COMPLETE_PARSE, scannerInfo);
|
||||
IScanner scanner = AST2BaseTest.createScanner(codeReader, lang, ParserMode.COMPLETE_PARSE, scannerInfo);
|
||||
ISourceCodeParser parser2 = null;
|
||||
if (lang == ParserLanguage.CPP) {
|
||||
ICPPParserExtensionConfiguration config = null;
|
||||
|
@ -92,8 +88,7 @@ public abstract class CodanFastCxxAstTestCase extends TestCase {
|
|||
config = new GPPParserExtensionConfiguration();
|
||||
else
|
||||
config = new ANSICPPParserExtensionConfiguration();
|
||||
parser2 = new GNUCPPSourceParser(scanner,
|
||||
ParserMode.COMPLETE_PARSE, NULL_LOG, config);
|
||||
parser2 = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config);
|
||||
} else {
|
||||
ICParserExtensionConfiguration config = null;
|
||||
if (gcc)
|
||||
|
@ -121,7 +116,7 @@ public abstract class CodanFastCxxAstTestCase extends TestCase {
|
|||
/**
|
||||
* Override if any of code that test tried to parse has errors, otherwise
|
||||
* parse method would assert
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected boolean hasCodeErrors() {
|
||||
|
@ -152,7 +147,7 @@ public abstract class CodanFastCxxAstTestCase extends TestCase {
|
|||
}
|
||||
|
||||
void runCodan(IASTTranslationUnit tu) {
|
||||
IProblemReporter problemReporter = CodanRuntime.getInstance() .getProblemReporter();
|
||||
IProblemReporter problemReporter = CodanRuntime.getInstance().getProblemReporter();
|
||||
CodanRuntime.getInstance().setProblemReporter(new IProblemReporter() {
|
||||
public void reportProblem(String problemId, IProblemLocation loc, Object... args) {
|
||||
codanproblems.add(new ProblemInstance(problemId, loc, args));
|
||||
|
|
|
@ -63,7 +63,7 @@ public class CodanTestCase extends BaseTestCase {
|
|||
|
||||
/**
|
||||
* Override for c++ (i.e. at least one c++ test)
|
||||
*
|
||||
*
|
||||
* @return is c++ tests
|
||||
*/
|
||||
public boolean isCpp() {
|
||||
|
@ -82,9 +82,7 @@ public class CodanTestCase extends BaseTestCase {
|
|||
public void tearDown() throws CoreException {
|
||||
if (cproject != null) {
|
||||
try {
|
||||
cproject.getProject().delete(
|
||||
IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT,
|
||||
new NullProgressMonitor());
|
||||
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
|
||||
} catch (CoreException e) {
|
||||
throw e;
|
||||
}
|
||||
|
@ -100,8 +98,7 @@ public class CodanTestCase extends BaseTestCase {
|
|||
for (int i = 0; i < projects.length; i++) {
|
||||
IProject p = projects[i];
|
||||
if (p.getName().startsWith("Codan")) {
|
||||
p.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT,
|
||||
new NullProgressMonitor());
|
||||
p.delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,10 +113,8 @@ public class CodanTestCase extends BaseTestCase {
|
|||
workspace.run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
// Create the cproject
|
||||
ICProject cproject = cpp ? CProjectHelper.createCCProject(
|
||||
projectName, null, IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(projectName, null,
|
||||
IPDOMManager.ID_NO_INDEXER);
|
||||
ICProject cproject = cpp ? CProjectHelper.createCCProject(projectName, null, IPDOMManager.ID_NO_INDEXER)
|
||||
: CProjectHelper.createCProject(projectName, null, IPDOMManager.ID_NO_INDEXER);
|
||||
cprojects[0] = cproject;
|
||||
}
|
||||
}, null);
|
||||
|
@ -138,8 +133,7 @@ public class CodanTestCase extends BaseTestCase {
|
|||
}
|
||||
}, null);
|
||||
// Index the cproject
|
||||
CCorePlugin.getIndexManager().setIndexerId(cproject,
|
||||
IPDOMManager.ID_FAST_INDEXER);
|
||||
CCorePlugin.getIndexManager().setIndexerId(cproject, IPDOMManager.ID_FAST_INDEXER);
|
||||
CCorePlugin.getIndexManager().reindex(cproject);
|
||||
// wait until the indexer is done
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(1000 * 60, // 1 min
|
||||
|
@ -178,8 +172,7 @@ public class CodanTestCase extends BaseTestCase {
|
|||
protected StringBuffer[] getContents(int sections) {
|
||||
try {
|
||||
CodanCoreTestActivator plugin = CodanCoreTestActivator.getDefault();
|
||||
return TestSourceReader.getContentsForTest(plugin.getBundle(),
|
||||
"src", getClass(), getName(), sections);
|
||||
return TestSourceReader.getContentsForTest(plugin.getBundle(), "src", getClass(), getName(), sections);
|
||||
} catch (IOException e) {
|
||||
fail(e.getMessage());
|
||||
return null;
|
||||
|
@ -194,8 +187,7 @@ public class CodanTestCase extends BaseTestCase {
|
|||
if (sep != -1) {
|
||||
String line = code.substring(0, sep);
|
||||
code = code.substring(sep + 1);
|
||||
String fileName = line.substring(indf + fileKey.length())
|
||||
.trim();
|
||||
String fileName = line.substring(indf + fileKey.length()).trim();
|
||||
return loadcode(code, new File(tmpDir, fileName));
|
||||
}
|
||||
}
|
||||
|
@ -218,8 +210,7 @@ public class CodanTestCase extends BaseTestCase {
|
|||
private File loadcode(String code, File testFile) {
|
||||
try {
|
||||
tempFiles.add(testFile);
|
||||
TestUtils.saveFile(
|
||||
new ByteArrayInputStream(code.trim().getBytes()), testFile);
|
||||
TestUtils.saveFile(new ByteArrayInputStream(code.trim().getBytes()), testFile);
|
||||
currentFile = testFile;
|
||||
try {
|
||||
cproject.getProject().refreshLocal(1, null);
|
||||
|
|
|
@ -24,8 +24,7 @@ import java.net.URL;
|
|||
*/
|
||||
@SuppressWarnings("nls")
|
||||
public class TestUtils {
|
||||
public static File saveFile(InputStream st, File testFile)
|
||||
throws FileNotFoundException, IOException {
|
||||
public static File saveFile(InputStream st, File testFile) throws FileNotFoundException, IOException {
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(st));
|
||||
String line;
|
||||
PrintStream wr = new PrintStream(testFile);
|
||||
|
|
|
@ -57,8 +57,7 @@ public abstract class QuickFixTestCase extends CheckerTestCase {
|
|||
|
||||
public static void closeWelcome() {
|
||||
try {
|
||||
IWorkbenchWindow window = PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow();
|
||||
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
|
||||
IWorkbenchPage activePage = window.getActivePage();
|
||||
IWorkbenchPart activePart = activePage.getActivePart();
|
||||
if (activePart.getTitle().equals("Welcome")) {
|
||||
|
@ -77,16 +76,14 @@ public abstract class QuickFixTestCase extends CheckerTestCase {
|
|||
quickFix = createQuickFix();
|
||||
display = PlatformUI.getWorkbench().getDisplay();
|
||||
closeWelcome();
|
||||
IPreferenceStore store = CodanUIActivator.getDefault()
|
||||
.getPreferenceStore(cproject.getProject());
|
||||
IPreferenceStore store = CodanUIActivator.getDefault().getPreferenceStore(cproject.getProject());
|
||||
// turn off editor reconsiler
|
||||
store.setValue(PreferenceConstants.P_RUN_IN_EDITOR, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws CoreException {
|
||||
IWorkbenchPage[] pages = PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow().getPages();
|
||||
IWorkbenchPage[] pages = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPages();
|
||||
for (IWorkbenchPage page : pages) {
|
||||
page.closeAllEditors(false);
|
||||
dispatch(200);
|
||||
|
@ -147,7 +144,6 @@ public abstract class QuickFixTestCase extends CheckerTestCase {
|
|||
* @param expected
|
||||
*/
|
||||
public void assertContainedIn(String expected, String result) {
|
||||
assertTrue(
|
||||
"Text <" + expected + "> not found in <" + result + ">", result.contains(expected)); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
assertTrue("Text <" + expected + "> not found in <" + result + ">", result.contains(expected)); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class CodanCorePlugin extends Plugin {
|
|||
* Logs the specified status with this plug-in's log.
|
||||
*
|
||||
* @param status
|
||||
* status to log
|
||||
* status to log
|
||||
*/
|
||||
public static void log(IStatus status) {
|
||||
getDefault().getLog().log(status);
|
||||
|
@ -85,7 +85,7 @@ public class CodanCorePlugin extends Plugin {
|
|||
* Logs an internal error with the specified throwable
|
||||
*
|
||||
* @param e
|
||||
* the exception to be logged
|
||||
* the exception to be logged
|
||||
*/
|
||||
public static void log(Throwable e) {
|
||||
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, "Internal Error", e)); //$NON-NLS-1$
|
||||
|
@ -95,7 +95,7 @@ public class CodanCorePlugin extends Plugin {
|
|||
* Logs an internal error with the specified message.
|
||||
*
|
||||
* @param message
|
||||
* the error message to log
|
||||
* the error message to log
|
||||
*/
|
||||
public static void log(String message) {
|
||||
log(new Status(IStatus.ERROR, PLUGIN_ID, 1, message, null));
|
||||
|
|
|
@ -56,10 +56,8 @@ public abstract class AbstractChecker implements IChecker {
|
|||
* it will be error message (not recommended because of
|
||||
* internationalization)
|
||||
*/
|
||||
public void reportProblem(String id, IFile file, int lineNumber,
|
||||
Object... args) {
|
||||
getProblemReporter().reportProblem(id,
|
||||
createProblemLocation(file, lineNumber), args);
|
||||
public void reportProblem(String id, IFile file, int lineNumber, Object... args) {
|
||||
getProblemReporter().reportProblem(id, createProblemLocation(file, lineNumber), args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -73,8 +71,7 @@ public abstract class AbstractChecker implements IChecker {
|
|||
* @return problem instance
|
||||
*/
|
||||
public IProblem getProblemById(String id, IResource file) {
|
||||
IProblem problem = CheckersRegistry.getInstance()
|
||||
.getResourceProfile(file).findProblem(id);
|
||||
IProblem problem = CheckersRegistry.getInstance().getResourceProfile(file).findProblem(id);
|
||||
if (problem == null)
|
||||
throw new IllegalArgumentException("Id is not registered"); //$NON-NLS-1$
|
||||
return problem;
|
||||
|
@ -92,8 +89,7 @@ public abstract class AbstractChecker implements IChecker {
|
|||
* - line
|
||||
*/
|
||||
public void reportProblem(String id, IFile file, int lineNumber) {
|
||||
getProblemReporter().reportProblem(id,
|
||||
createProblemLocation(file, lineNumber), new Object[] {});
|
||||
getProblemReporter().reportProblem(id, createProblemLocation(file, lineNumber), new Object[] {});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,8 +123,7 @@ public abstract class AbstractChecker implements IChecker {
|
|||
* @return instance of IProblemLocation
|
||||
*/
|
||||
protected IProblemLocation createProblemLocation(IFile file, int line) {
|
||||
return getRuntime().getProblemLocationFactory().createProblemLocation(
|
||||
file, line);
|
||||
return getRuntime().getProblemLocationFactory().createProblemLocation(file, line);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -143,10 +138,8 @@ public abstract class AbstractChecker implements IChecker {
|
|||
* exclusive.
|
||||
* @return instance of IProblemLocation
|
||||
*/
|
||||
protected IProblemLocation createProblemLocation(IFile file, int startChar,
|
||||
int endChar) {
|
||||
return getRuntime().getProblemLocationFactory().createProblemLocation(
|
||||
file, startChar, endChar);
|
||||
protected IProblemLocation createProblemLocation(IFile file, int startChar, int endChar) {
|
||||
return getRuntime().getProblemLocationFactory().createProblemLocation(file, startChar, endChar);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,8 +157,7 @@ public abstract class AbstractChecker implements IChecker {
|
|||
* @param loc - problem location
|
||||
* @param args - extra problem arguments
|
||||
*/
|
||||
public void reportProblem(String problemId, IProblemLocation loc,
|
||||
Object... args) {
|
||||
public void reportProblem(String problemId, IProblemLocation loc, Object... args) {
|
||||
getProblemReporter().reportProblem(problemId, loc, args);
|
||||
}
|
||||
|
||||
|
@ -196,23 +188,19 @@ public abstract class AbstractChecker implements IChecker {
|
|||
*/
|
||||
public boolean before(IResource resource) {
|
||||
IChecker checker = this;
|
||||
IProblemReporter problemReporter = CodanRuntime.getInstance()
|
||||
.getProblemReporter();
|
||||
IProblemReporter problemReporter = CodanRuntime.getInstance().getProblemReporter();
|
||||
IProblemReporter sessionReporter = problemReporter;
|
||||
if (problemReporter instanceof IProblemReporterSessionPersistent) {
|
||||
// create session problem reporter
|
||||
sessionReporter = ((IProblemReporterSessionPersistent) problemReporter)
|
||||
.createReporter(resource, checker);
|
||||
sessionReporter = ((IProblemReporterSessionPersistent) problemReporter).createReporter(resource, checker);
|
||||
((IProblemReporterSessionPersistent) sessionReporter).start();
|
||||
} else if (problemReporter instanceof IProblemReporterPersistent) {
|
||||
// delete markers if checker can possibly run on this
|
||||
// resource this way if checker is not enabled markers would be
|
||||
// deleted too
|
||||
((IProblemReporterPersistent) problemReporter).deleteProblems(
|
||||
resource, checker);
|
||||
((IProblemReporterPersistent) problemReporter).deleteProblems(resource, checker);
|
||||
}
|
||||
((AbstractChecker) checker).setContext(new CheckerInvocationContext(
|
||||
resource, sessionReporter));
|
||||
((AbstractChecker) checker).setContext(new CheckerInvocationContext(resource, sessionReporter));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -222,8 +210,7 @@ public abstract class AbstractChecker implements IChecker {
|
|||
public boolean after(IResource resource) {
|
||||
if (getContext().getProblemReporter() instanceof IProblemReporterSessionPersistent) {
|
||||
// delete general markers
|
||||
((IProblemReporterSessionPersistent) getContext()
|
||||
.getProblemReporter()).done();
|
||||
((IProblemReporterSessionPersistent) getContext().getProblemReporter()).done();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -29,8 +29,7 @@ import org.eclipse.core.runtime.IPath;
|
|||
* Checker can produce several problems, but preferences are per problem.
|
||||
* Sharing preferences between problems is not supported now.
|
||||
*/
|
||||
public abstract class AbstractCheckerWithProblemPreferences extends
|
||||
AbstractChecker implements ICheckerWithPreferences {
|
||||
public abstract class AbstractCheckerWithProblemPreferences extends AbstractChecker implements ICheckerWithPreferences {
|
||||
/**
|
||||
* Checker that actually has parameter must override this
|
||||
*/
|
||||
|
@ -47,8 +46,8 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* @return scope problem preference, null if not defined
|
||||
*/
|
||||
public FileScopeProblemPreference getScopePreference(IProblem problem) {
|
||||
FileScopeProblemPreference scope = (FileScopeProblemPreference) getTopLevelPreferenceMap(
|
||||
problem).getChildDescriptor(FileScopeProblemPreference.KEY);
|
||||
FileScopeProblemPreference scope = (FileScopeProblemPreference) getTopLevelPreferenceMap(problem).getChildDescriptor(
|
||||
FileScopeProblemPreference.KEY);
|
||||
return scope;
|
||||
}
|
||||
|
||||
|
@ -63,14 +62,10 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* @return true if checker should report problems, fails otherwise.
|
||||
*/
|
||||
public boolean shouldProduceProblems(IResource res) {
|
||||
Collection<IProblem> refProblems = getRuntime().getCheckersRegistry()
|
||||
.getRefProblems(this);
|
||||
for (Iterator<IProblem> iterator = refProblems.iterator(); iterator
|
||||
.hasNext();) {
|
||||
Collection<IProblem> refProblems = getRuntime().getCheckersRegistry().getRefProblems(this);
|
||||
for (Iterator<IProblem> iterator = refProblems.iterator(); iterator.hasNext();) {
|
||||
IProblem checkerProblem = iterator.next();
|
||||
if (shouldProduceProblem(
|
||||
getProblemById(checkerProblem.getId(), res),
|
||||
res.getLocation()))
|
||||
if (shouldProduceProblem(getProblemById(checkerProblem.getId(), res), res.getLocation()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -99,10 +94,8 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportProblem(String problemId, IProblemLocation loc,
|
||||
Object... args) {
|
||||
if (shouldProduceProblem(getProblemById(problemId, loc.getFile()), loc
|
||||
.getFile().getLocation()))
|
||||
public void reportProblem(String problemId, IProblemLocation loc, Object... args) {
|
||||
if (shouldProduceProblem(getProblemById(problemId, loc.getFile()), loc.getFile().getLocation()))
|
||||
super.reportProblem(problemId, loc, args);
|
||||
}
|
||||
|
||||
|
@ -119,11 +112,9 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* - parameter default value
|
||||
* @return - parameter info object
|
||||
*/
|
||||
public IProblemPreference addPreference(IProblemWorkingCopy problem,
|
||||
String key, String label, Object defaultValue) {
|
||||
public IProblemPreference addPreference(IProblemWorkingCopy problem, String key, String label, Object defaultValue) {
|
||||
MapProblemPreference map = getTopLevelPreferenceMap(problem);
|
||||
BasicProblemPreference info = new BasicProblemPreference(key, label,
|
||||
PreferenceType.typeOf(defaultValue));
|
||||
BasicProblemPreference info = new BasicProblemPreference(key, label, PreferenceType.typeOf(defaultValue));
|
||||
map.addChildDescriptor(info);
|
||||
setDefaultPreferenceValue(problem, key, defaultValue);
|
||||
return info;
|
||||
|
@ -144,12 +135,10 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* values or set different element type
|
||||
*
|
||||
*/
|
||||
public ListProblemPreference addListPreference(IProblemWorkingCopy problem,
|
||||
String key, String label, String itemLabel) {
|
||||
public ListProblemPreference addListPreference(IProblemWorkingCopy problem, String key, String label, String itemLabel) {
|
||||
MapProblemPreference map = getTopLevelPreferenceMap(problem);
|
||||
ListProblemPreference list = new ListProblemPreference(key, label);
|
||||
list.setChildDescriptor(new BasicProblemPreference(
|
||||
ListProblemPreference.COMMON_DESCRIPTOR_KEY, itemLabel,
|
||||
list.setChildDescriptor(new BasicProblemPreference(ListProblemPreference.COMMON_DESCRIPTOR_KEY, itemLabel,
|
||||
PreferenceType.TYPE_STRING));
|
||||
return (ListProblemPreference) map.addChildDescriptor(list);
|
||||
}
|
||||
|
@ -162,8 +151,7 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* @param defaultValue - default value of the preference
|
||||
* @return added preference
|
||||
*/
|
||||
public IProblemPreference addPreference(IProblemWorkingCopy problem,
|
||||
IProblemPreference pref, Object defaultValue) {
|
||||
public IProblemPreference addPreference(IProblemWorkingCopy problem, IProblemPreference pref, Object defaultValue) {
|
||||
MapProblemPreference map = getTopLevelPreferenceMap(problem);
|
||||
String key = pref.getKey();
|
||||
pref = map.addChildDescriptor(pref);
|
||||
|
@ -179,8 +167,7 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* @param key - preference key
|
||||
* @param defaultValue - value of preference to be set
|
||||
*/
|
||||
protected void setDefaultPreferenceValue(IProblemWorkingCopy problem,
|
||||
String key, Object defaultValue) {
|
||||
protected void setDefaultPreferenceValue(IProblemWorkingCopy problem, String key, Object defaultValue) {
|
||||
MapProblemPreference map = getTopLevelPreferenceMap(problem);
|
||||
if (map.getChildValue(key) == null)
|
||||
map.setChildValue(key, defaultValue);
|
||||
|
@ -197,8 +184,7 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* @return top level preference if it is a map
|
||||
*/
|
||||
protected MapProblemPreference getTopLevelPreferenceMap(IProblem problem) {
|
||||
MapProblemPreference map = (MapProblemPreference) problem
|
||||
.getPreference();
|
||||
MapProblemPreference map = (MapProblemPreference) problem.getPreference();
|
||||
if (map == null) {
|
||||
map = new MapProblemPreference(AbstractProblemPreference.PARAM, ""); //$NON-NLS-1$
|
||||
if (problem instanceof IProblemWorkingCopy) {
|
||||
|
@ -217,8 +203,7 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* @return value of the preference
|
||||
*/
|
||||
public Object getPreference(IProblem problem, String key) {
|
||||
return ((MapProblemPreference) problem.getPreference())
|
||||
.getChildValue(key);
|
||||
return ((MapProblemPreference) problem.getPreference()).getChildValue(key);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,8 +214,7 @@ public abstract class AbstractCheckerWithProblemPreferences extends
|
|||
* @return true if argument matches of the names in the exception list
|
||||
* @since 2.0
|
||||
*/
|
||||
public boolean isFilteredArg(String arg, IProblem problem,
|
||||
String exceptionListParamId) {
|
||||
public boolean isFilteredArg(String arg, IProblem problem, String exceptionListParamId) {
|
||||
Object[] arr = (Object[]) getPreference(problem, exceptionListParamId);
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
String str = (String) arr[i];
|
||||
|
|
|
@ -26,14 +26,12 @@ public abstract class AbstractProblemReporter implements IProblemReporter {
|
|||
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);
|
||||
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);
|
||||
ICodanProblemMarker codanProblemMarker = new CodanProblemMarker(problem, loc, args);
|
||||
reportProblem(codanProblemMarker);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,8 +59,7 @@ public interface ICheckersRegistry extends Iterable<IChecker> {
|
|||
* @param parentCategoryId
|
||||
* - parent category id
|
||||
*/
|
||||
public abstract void addCategory(IProblemCategory category,
|
||||
String parentCategoryId);
|
||||
public abstract void addCategory(IProblemCategory category, String parentCategoryId);
|
||||
|
||||
/**
|
||||
* Add problem reference to a checker, i.e. claim that checker can produce
|
||||
|
|
|
@ -20,20 +20,20 @@ import org.eclipse.cdt.codan.core.param.IProblemPreference;
|
|||
* determined by runtime. If it is the case - two Problems should be created
|
||||
* (i.e. one for error and one for warning). All of problem attributes are
|
||||
* defined in a checker extension point.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as part
|
||||
* of a work in progress. There is no guarantee that this API will work or that
|
||||
* it will remain the same.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IProblem extends IProblemElement {
|
||||
/**
|
||||
* Name of the problem - user visible "title", not the message
|
||||
*
|
||||
*
|
||||
* @return title of the problem
|
||||
*/
|
||||
String getName();
|
||||
|
@ -41,7 +41,7 @@ public interface IProblem extends IProblemElement {
|
|||
/**
|
||||
* Unique problem id. Should be qualified by plugin name to maintain
|
||||
* uniqueness.
|
||||
*
|
||||
*
|
||||
* @return unique problem id
|
||||
*/
|
||||
String getId();
|
||||
|
@ -49,21 +49,21 @@ public interface IProblem extends IProblemElement {
|
|||
/**
|
||||
* Returns <code>true</code> if the problem is enabled in current context
|
||||
* (usually within profile)
|
||||
*
|
||||
*
|
||||
* @return true if enabled
|
||||
*/
|
||||
boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Returns current severity
|
||||
*
|
||||
*
|
||||
* @return severity
|
||||
*/
|
||||
CodanSeverity getSeverity();
|
||||
|
||||
/**
|
||||
* Message pattern, java patter like 'Variable {0} is never used here'
|
||||
*
|
||||
*
|
||||
* @return pattern
|
||||
*/
|
||||
String getMessagePattern();
|
||||
|
@ -71,21 +71,21 @@ public interface IProblem extends IProblemElement {
|
|||
/**
|
||||
* Returns root preference descriptor or null if not defined (used by UI to
|
||||
* generate user controls for changing parameters)
|
||||
*
|
||||
*
|
||||
* @return root preference or null
|
||||
*/
|
||||
public IProblemPreference getPreference();
|
||||
|
||||
/**
|
||||
* Returns short description of a problem
|
||||
*
|
||||
*
|
||||
* @return description
|
||||
*/
|
||||
public String getDescription();
|
||||
|
||||
/**
|
||||
* Returns marker id for the problem
|
||||
*
|
||||
*
|
||||
* @return marker id
|
||||
*/
|
||||
public String getMarkerType();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
package org.eclipse.cdt.codan.core.model;
|
||||
|
||||
/**
|
||||
* Problem category {@link IProblemCategory} or problem {@link IProblem}
|
||||
* Problem category {@link IProblemCategory} or problem {@link IProblem}
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
|
@ -19,9 +19,11 @@ package org.eclipse.cdt.codan.core.model;
|
|||
public interface IProblemElement extends Cloneable {
|
||||
/**
|
||||
* clone method should be implemented to support problem cloning
|
||||
*
|
||||
* @see {@link Object#clone}
|
||||
* @return new object which is copy of this one
|
||||
* @throws CloneNotSupportedException - it is declared with this exception but it should NOT throw it
|
||||
* @throws CloneNotSupportedException - it is declared with this exception
|
||||
* but it should NOT throw it
|
||||
*/
|
||||
Object clone() throws CloneNotSupportedException;
|
||||
}
|
||||
|
|
|
@ -46,8 +46,7 @@ public interface IProblemLocationFactory {
|
|||
* exclusive.
|
||||
* @return instance of IProblemLocation
|
||||
*/
|
||||
public IProblemLocation createProblemLocation(IFile file, int startChar,
|
||||
int endChar);
|
||||
public IProblemLocation createProblemLocation(IFile file, int startChar, int endChar);
|
||||
|
||||
/**
|
||||
* Create and return instance of IProblemLocation
|
||||
|
@ -55,13 +54,13 @@ public interface IProblemLocationFactory {
|
|||
* @param astFile - file where problem is found
|
||||
* @param startChar - start char of the problem in the file, is
|
||||
* zero-relative
|
||||
* @param endChar - end char of the problem in the file, is zero-relative and
|
||||
* @param endChar - end char of the problem in the file, is zero-relative
|
||||
* and
|
||||
* exclusive.
|
||||
*
|
||||
* @param line
|
||||
* - start line number (for visualisation purposes)
|
||||
* @return instance of IProblemLocation
|
||||
*/
|
||||
public IProblemLocation createProblemLocation(IFile astFile,
|
||||
int startChar, int endChar, int line);
|
||||
public IProblemLocation createProblemLocation(IFile astFile, int startChar, int endChar, int line);
|
||||
}
|
|
@ -38,6 +38,5 @@ public interface IProblemReporter {
|
|||
* @param args - custom arguments, can be none, in this case default message
|
||||
* is reported
|
||||
*/
|
||||
public void reportProblem(String problemId, IProblemLocation loc,
|
||||
Object... args);
|
||||
public void reportProblem(String problemId, IProblemLocation loc, Object... args);
|
||||
}
|
|
@ -61,6 +61,5 @@ public interface IProblemReporterSessionPersistent extends IProblemReporter {
|
|||
* @return
|
||||
* @since 2.0
|
||||
*/
|
||||
public IProblemReporterSessionPersistent createReporter(IResource resource,
|
||||
IChecker checker);
|
||||
public IProblemReporterSessionPersistent createReporter(IResource resource, IChecker checker);
|
||||
}
|
|
@ -14,13 +14,13 @@ import org.eclipse.cdt.codan.core.param.IProblemPreference;
|
|||
|
||||
/**
|
||||
* Modifiable problem.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as part
|
||||
* of a work in progress. There is no guarantee that this API will work or that
|
||||
* it will remain the same.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
|
@ -28,14 +28,14 @@ public interface IProblemWorkingCopy extends IProblem {
|
|||
/**
|
||||
* Set severity for this this problem instance. Severity can only be changed
|
||||
* in profile not by checker when printing problems.
|
||||
*
|
||||
*
|
||||
* @param sev - codan severity
|
||||
*/
|
||||
void setSeverity(CodanSeverity sev);
|
||||
|
||||
/**
|
||||
* Sets checker enablement.
|
||||
*
|
||||
*
|
||||
* @param enabled - true if problem is enabled in profile
|
||||
*/
|
||||
void setEnabled(boolean enabled);
|
||||
|
@ -44,8 +44,9 @@ public interface IProblemWorkingCopy extends IProblem {
|
|||
* Sets default message pattern. UI would call this method if user does not
|
||||
* like default settings, checker should not use method, default message
|
||||
* pattern should be set in checker extension
|
||||
*
|
||||
* @param messagePattern - java style message patter, e.g. "Variable {0} is never used".
|
||||
*
|
||||
* @param messagePattern - java style message patter, e.g.
|
||||
* "Variable {0} is never used".
|
||||
*/
|
||||
void setMessagePattern(String messagePattern);
|
||||
|
||||
|
@ -53,15 +54,15 @@ public interface IProblemWorkingCopy extends IProblem {
|
|||
* Sets value for the checker parameter, checker may set value during
|
||||
* initialization only, which would the default. User control this values
|
||||
* through ui later.
|
||||
*
|
||||
*
|
||||
* @param pref - preference to set
|
||||
*
|
||||
*
|
||||
*/
|
||||
public void setPreference(IProblemPreference pref);
|
||||
|
||||
/**
|
||||
* Sets problem description
|
||||
*
|
||||
*
|
||||
* @param desc - problem description - short version, but longer than name
|
||||
*/
|
||||
public void setDescription(String desc);
|
||||
|
|
|
@ -16,8 +16,7 @@ package org.eclipse.cdt.codan.core.model.cfg;
|
|||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IBranchNode extends IBasicBlock, ISingleIncoming,
|
||||
ISingleOutgoing {
|
||||
public interface IBranchNode extends IBasicBlock, ISingleIncoming, ISingleOutgoing {
|
||||
/**
|
||||
* Then branch of "if" statement
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,5 @@ package org.eclipse.cdt.codan.core.model.cfg;
|
|||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IPlainNode extends IBasicBlock, ISingleOutgoing,
|
||||
ISingleIncoming {
|
||||
public interface IPlainNode extends IBasicBlock, ISingleOutgoing, ISingleIncoming {
|
||||
}
|
||||
|
|
|
@ -58,8 +58,7 @@ public abstract class AbstractProblemPreference implements IProblemPreference {
|
|||
if (isValidIdentifier(key))
|
||||
this.key = key;
|
||||
else
|
||||
throw new IllegalArgumentException(
|
||||
"Key must have java identifier syntax or number, i.e no dots and other funky stuff: " + key); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Key must have java identifier syntax or number, i.e no dots and other funky stuff: " + key); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
protected boolean isValidIdentifier(String id) {
|
||||
|
@ -128,8 +127,7 @@ public abstract class AbstractProblemPreference implements IProblemPreference {
|
|||
*/
|
||||
protected StreamTokenizer getImportTokenizer(String str) {
|
||||
ByteArrayInputStream st = new ByteArrayInputStream(str.getBytes());
|
||||
StreamTokenizer tokenizer = new StreamTokenizer(new InputStreamReader(
|
||||
st));
|
||||
StreamTokenizer tokenizer = new StreamTokenizer(new InputStreamReader(st));
|
||||
tokenizer.resetSyntax();
|
||||
tokenizer.quoteChar('"');
|
||||
tokenizer.wordChars('_', '_');
|
||||
|
@ -166,8 +164,7 @@ public abstract class AbstractProblemPreference implements IProblemPreference {
|
|||
* @param tokenizer
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void importValue(StreamTokenizer tokenizer)
|
||||
throws IOException;
|
||||
public abstract void importValue(StreamTokenizer tokenizer) throws IOException;
|
||||
|
||||
public void importValue(String str) {
|
||||
StreamTokenizer tokenizer = getImportTokenizer(str);
|
||||
|
|
|
@ -111,8 +111,7 @@ public class BasicProblemPreference extends AbstractProblemPreference {
|
|||
setValue(new File(str));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(getType()
|
||||
+ " is not supported for basic type"); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException(getType() + " is not supported for basic type"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,22 +148,19 @@ public class FileScopeProblemPreference extends AbstractProblemPreference {
|
|||
exclusion = exc.toArray(new IPath[exc.size()]);
|
||||
}
|
||||
|
||||
private void checkChar(StreamTokenizer tokenizer, char c)
|
||||
throws IOException {
|
||||
private void checkChar(StreamTokenizer tokenizer, char c) throws IOException {
|
||||
tokenizer.nextToken();
|
||||
if (tokenizer.ttype != c)
|
||||
throw new IllegalArgumentException("Expected " + c); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
private void checkKeyword(StreamTokenizer tokenizer, String keyword)
|
||||
throws IOException {
|
||||
private void checkKeyword(StreamTokenizer tokenizer, String keyword) throws IOException {
|
||||
tokenizer.nextToken();
|
||||
if (tokenizer.sval == null || !tokenizer.sval.equals(keyword))
|
||||
throw new IllegalArgumentException("Expected " + keyword); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
protected List<IPath> importPathList(StreamTokenizer tokenizer,
|
||||
String keyword) throws IOException {
|
||||
protected List<IPath> importPathList(StreamTokenizer tokenizer, String keyword) throws IOException {
|
||||
checkKeyword(tokenizer, keyword);
|
||||
checkChar(tokenizer, '=');
|
||||
checkChar(tokenizer, '>');
|
||||
|
@ -217,8 +214,7 @@ public class FileScopeProblemPreference extends AbstractProblemPreference {
|
|||
*/
|
||||
@Override
|
||||
public Object clone() {
|
||||
FileScopeProblemPreference scope = (FileScopeProblemPreference) super
|
||||
.clone();
|
||||
FileScopeProblemPreference scope = (FileScopeProblemPreference) super.clone();
|
||||
scope.setValue(this);
|
||||
return scope;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,5 @@ package org.eclipse.cdt.codan.core.param;
|
|||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IProblemPreference extends Cloneable, IProblemPreferenceValue,
|
||||
IProblemPreferenceDescriptor {
|
||||
public interface IProblemPreference extends Cloneable, IProblemPreferenceValue, IProblemPreferenceDescriptor {
|
||||
}
|
||||
|
|
|
@ -35,8 +35,7 @@ public class LaunchTypeProblemPreference extends MapProblemPreference {
|
|||
CheckerLaunchMode[] values = CheckerLaunchMode.values();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
CheckerLaunchMode checkerLaunchMode = values[i];
|
||||
BasicProblemPreference desc = new BasicProblemPreference(
|
||||
checkerLaunchMode.name(), checkerLaunchMode.name(),
|
||||
BasicProblemPreference desc = new BasicProblemPreference(checkerLaunchMode.name(), checkerLaunchMode.name(),
|
||||
PreferenceType.TYPE_BOOLEAN);
|
||||
IProblemPreference desc1 = addChildDescriptor(desc);
|
||||
if (checkerLaunchMode == CheckerLaunchMode.USE_PARENT)
|
||||
|
|
|
@ -21,8 +21,8 @@ import java.util.Iterator;
|
|||
*
|
||||
* @noextend This class is not intended to be extended by clients.
|
||||
*/
|
||||
public class ListProblemPreference extends AbstractProblemPreference implements
|
||||
IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor {
|
||||
public class ListProblemPreference extends AbstractProblemPreference implements IProblemPreferenceCompositeValue,
|
||||
IProblemPreferenceCompositeDescriptor {
|
||||
/**
|
||||
* Constant that represent a key for "shared" child preference (descriptor)
|
||||
* of all elements
|
||||
|
@ -57,8 +57,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
|
|||
childDescriptor = desc;
|
||||
if (desc != null) {
|
||||
childDescriptor.setValue(null);
|
||||
((AbstractProblemPreference) childDescriptor)
|
||||
.setKey(COMMON_DESCRIPTOR_KEY);
|
||||
((AbstractProblemPreference) childDescriptor).setKey(COMMON_DESCRIPTOR_KEY);
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
@ -95,8 +94,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
|
|||
*/
|
||||
public IProblemPreference getChildDescriptor(int i) {
|
||||
Object value = list.get(i);
|
||||
AbstractProblemPreference desc = (AbstractProblemPreference) childDescriptor
|
||||
.clone();
|
||||
AbstractProblemPreference desc = (AbstractProblemPreference) childDescriptor.clone();
|
||||
desc.setKey(String.valueOf(i));
|
||||
desc.setValue(value);
|
||||
return desc;
|
||||
|
@ -109,8 +107,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
|
|||
* @throws NumberFormatException
|
||||
* if key is not number
|
||||
*/
|
||||
public IProblemPreference getChildDescriptor(String key)
|
||||
throws NumberFormatException {
|
||||
public IProblemPreference getChildDescriptor(String key) throws NumberFormatException {
|
||||
if (key == null || key.equals(COMMON_DESCRIPTOR_KEY)) {
|
||||
// return common descriptor
|
||||
return getChildDescriptor();
|
||||
|
@ -118,8 +115,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
|
|||
Integer iv = Integer.valueOf(key);
|
||||
if (iv.intValue() >= list.size()) {
|
||||
// create one
|
||||
AbstractProblemPreference clone = (AbstractProblemPreference) childDescriptor
|
||||
.clone();
|
||||
AbstractProblemPreference clone = (AbstractProblemPreference) childDescriptor.clone();
|
||||
clone.setKey(key);
|
||||
return clone;
|
||||
}
|
||||
|
@ -193,8 +189,7 @@ public class ListProblemPreference extends AbstractProblemPreference implements
|
|||
public Object clone() {
|
||||
ListProblemPreference list1 = (ListProblemPreference) super.clone();
|
||||
list1.list = new ArrayList<Object>();
|
||||
list1.setChildDescriptor((IProblemPreference) getChildDescriptor()
|
||||
.clone());
|
||||
list1.setChildDescriptor((IProblemPreference) getChildDescriptor().clone());
|
||||
for (Iterator<Object> iterator = list.iterator(); iterator.hasNext();) {
|
||||
Object value = iterator.next();
|
||||
list1.addChildValue(value);
|
||||
|
|
|
@ -30,8 +30,8 @@ import org.eclipse.cdt.codan.core.model.AbstractCheckerWithProblemPreferences;
|
|||
*
|
||||
* @noextend This class is not intended to be extended by clients.
|
||||
*/
|
||||
public class MapProblemPreference extends AbstractProblemPreference implements
|
||||
IProblemPreferenceCompositeValue, IProblemPreferenceCompositeDescriptor {
|
||||
public class MapProblemPreference extends AbstractProblemPreference implements IProblemPreferenceCompositeValue,
|
||||
IProblemPreferenceCompositeDescriptor {
|
||||
protected LinkedHashMap<String, IProblemPreference> hash = new LinkedHashMap<String, IProblemPreference>();
|
||||
|
||||
/**
|
||||
|
@ -84,8 +84,7 @@ public class MapProblemPreference extends AbstractProblemPreference implements
|
|||
* values.
|
||||
*/
|
||||
public IProblemPreference[] getChildDescriptors() {
|
||||
return hash.values().toArray(
|
||||
new IProblemPreference[hash.values().size()]);
|
||||
return hash.values().toArray(new IProblemPreference[hash.values().size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -119,8 +118,7 @@ public class MapProblemPreference extends AbstractProblemPreference implements
|
|||
public Object clone() {
|
||||
MapProblemPreference map = (MapProblemPreference) super.clone();
|
||||
map.hash = new LinkedHashMap<String, IProblemPreference>();
|
||||
for (Iterator<String> iterator = hash.keySet().iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<String> iterator = hash.keySet().iterator(); iterator.hasNext();) {
|
||||
String key = iterator.next();
|
||||
map.hash.put(key, (IProblemPreference) hash.get(key).clone());
|
||||
}
|
||||
|
@ -129,8 +127,7 @@ public class MapProblemPreference extends AbstractProblemPreference implements
|
|||
|
||||
public String exportValue() {
|
||||
StringBuffer buf = new StringBuffer("{"); //$NON-NLS-1$
|
||||
for (Iterator<String> iterator = hash.keySet().iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<String> iterator = hash.keySet().iterator(); iterator.hasNext();) {
|
||||
String key = iterator.next();
|
||||
IProblemPreference d = hash.get(key);
|
||||
buf.append(key + "=>" + d.exportValue()); //$NON-NLS-1$
|
||||
|
@ -166,12 +163,10 @@ public class MapProblemPreference extends AbstractProblemPreference implements
|
|||
String key = tokenizer.sval;
|
||||
token = tokenizer.nextToken();
|
||||
if (token != '=')
|
||||
throw new IllegalArgumentException(
|
||||
String.valueOf((char) token));
|
||||
throw new IllegalArgumentException(String.valueOf((char) token));
|
||||
token = tokenizer.nextToken();
|
||||
if (token != '>')
|
||||
throw new IllegalArgumentException(
|
||||
String.valueOf((char) token));
|
||||
throw new IllegalArgumentException(String.valueOf((char) token));
|
||||
IProblemPreference desc = getChildDescriptor(key);
|
||||
if (desc == null && LaunchTypeProblemPreference.KEY.equals(key)) {
|
||||
desc = new LaunchTypeProblemPreference();
|
||||
|
@ -185,8 +180,7 @@ public class MapProblemPreference extends AbstractProblemPreference implements
|
|||
if (token == '}')
|
||||
break;
|
||||
if (token != ',')
|
||||
throw new IllegalArgumentException(
|
||||
String.valueOf((char) token));
|
||||
throw new IllegalArgumentException(String.valueOf((char) token));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
|
@ -227,8 +221,7 @@ public class MapProblemPreference extends AbstractProblemPreference implements
|
|||
@Override
|
||||
public Object getValue() {
|
||||
LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
for (Iterator<IProblemPreference> iterator = hash.values().iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<IProblemPreference> iterator = hash.values().iterator(); iterator.hasNext();) {
|
||||
IProblemPreference pref = iterator.next();
|
||||
map.put(pref.getKey(), pref.getValue());
|
||||
}
|
||||
|
@ -247,11 +240,9 @@ public class MapProblemPreference extends AbstractProblemPreference implements
|
|||
@Override
|
||||
public void setValue(Object value) {
|
||||
Map<String, Object> map = (Map<String, Object>) value;
|
||||
LinkedHashMap<String, IProblemPreference> hash2 = (LinkedHashMap<String, IProblemPreference>) hash
|
||||
.clone();
|
||||
LinkedHashMap<String, IProblemPreference> hash2 = (LinkedHashMap<String, IProblemPreference>) hash.clone();
|
||||
hash.clear();
|
||||
for (Iterator<String> iterator = map.keySet().iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<String> iterator = map.keySet().iterator(); iterator.hasNext();) {
|
||||
String key = iterator.next();
|
||||
Object value2 = map.get(key);
|
||||
if (value2 instanceof IProblemPreference) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,8 +25,7 @@ public class CheckerInvocationContext implements ICheckerInvocationContext {
|
|||
* @param resource
|
||||
* @param sessionReporter
|
||||
*/
|
||||
public CheckerInvocationContext(IResource resource,
|
||||
IProblemReporter sessionReporter) {
|
||||
public CheckerInvocationContext(IResource resource, IProblemReporter sessionReporter) {
|
||||
this.resource = resource;
|
||||
this.sessionReporter = sessionReporter;
|
||||
}
|
||||
|
|
|
@ -65,8 +65,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
}
|
||||
|
||||
private void readCheckersRegistry() {
|
||||
IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(
|
||||
CodanCorePlugin.PLUGIN_ID, EXTENSION_POINT_NAME);
|
||||
IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(CodanCorePlugin.PLUGIN_ID, EXTENSION_POINT_NAME);
|
||||
if (ep == null)
|
||||
return;
|
||||
IConfigurationElement[] elements = ep.getConfigurationElements();
|
||||
|
@ -117,8 +116,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
if (name == null)
|
||||
return;
|
||||
CodanProblemCategory cat = new CodanProblemCategory(id, name);
|
||||
String category = getAtt(configurationElement,
|
||||
"parentCategory", false); //$NON-NLS-1$
|
||||
String category = getAtt(configurationElement, "parentCategory", false); //$NON-NLS-1$
|
||||
addCategory(cat, category);
|
||||
}
|
||||
}
|
||||
|
@ -145,8 +143,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
return;
|
||||
}
|
||||
boolean hasRef = false;
|
||||
IConfigurationElement[] children2 =
|
||||
configurationElement.getChildren(PROBLEM_ELEMENT);
|
||||
IConfigurationElement[] children2 = configurationElement.getChildren(PROBLEM_ELEMENT);
|
||||
if (children2 != null) {
|
||||
for (IConfigurationElement ref : children2) {
|
||||
IProblem p = processProblem(ref);
|
||||
|
@ -154,8 +151,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
hasRef = true;
|
||||
}
|
||||
}
|
||||
IConfigurationElement[] children1 =
|
||||
configurationElement.getChildren("problemRef"); //$NON-NLS-1$
|
||||
IConfigurationElement[] children1 = configurationElement.getChildren("problemRef"); //$NON-NLS-1$
|
||||
if (children1 != null) {
|
||||
for (IConfigurationElement ref : children1) {
|
||||
hasRef = true;
|
||||
|
@ -216,13 +212,11 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static String getAtt(IConfigurationElement configurationElement,
|
||||
String name) {
|
||||
private static String getAtt(IConfigurationElement configurationElement, String name) {
|
||||
return getAtt(configurationElement, name, true);
|
||||
}
|
||||
|
||||
private static String getAtt(IConfigurationElement configurationElement,
|
||||
String name, boolean req) {
|
||||
private static String getAtt(IConfigurationElement configurationElement, String name, boolean req) {
|
||||
String elementValue = configurationElement.getAttribute(name);
|
||||
if (elementValue == null && req)
|
||||
CodanCorePlugin.log("Extension " //$NON-NLS-1$
|
||||
|
@ -234,7 +228,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.ICheckersRegistry#iterator()
|
||||
*/
|
||||
public Iterator<IChecker> iterator() {
|
||||
|
@ -252,7 +246,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.ICheckersRegistry#addChecker(org.eclipse
|
||||
* .cdt.codan.core.model.IChecker)
|
||||
|
@ -263,7 +257,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.ICheckersRegistry#addProblem(org.eclipse
|
||||
* .cdt.codan.core.model.IProblem, java.lang.String)
|
||||
|
@ -277,7 +271,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.ICheckersRegistry#addCategory(org.eclipse
|
||||
* .cdt.codan.core.model.IProblemCategory, java.lang.String)
|
||||
|
@ -291,7 +285,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.ICheckersRegistry#addRefProblem(org.
|
||||
* eclipse.cdt.codan.core.model.IChecker,
|
||||
|
@ -308,7 +302,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/**
|
||||
* Returns list of problems registered for given checker
|
||||
*
|
||||
*
|
||||
* @return collection of problems or null
|
||||
*/
|
||||
public Collection<IProblem> getRefProblems(IChecker checker) {
|
||||
|
@ -317,7 +311,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.ICheckersRegistry#getDefaultProfile()
|
||||
*/
|
||||
|
@ -327,7 +321,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.ICheckersRegistry#getWorkspaceProfile()
|
||||
*/
|
||||
|
@ -358,7 +352,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.ICheckersRegistry#getResourceProfile
|
||||
* (org.eclipse.core.resources.IResource)
|
||||
|
@ -371,10 +365,8 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
prof = (IProblemProfile) getWorkspaceProfile().clone();
|
||||
// load default values
|
||||
CodanPreferencesLoader loader = new CodanPreferencesLoader(prof);
|
||||
Preferences projectNode =
|
||||
CodanPreferencesLoader.getProjectNode((IProject) element);
|
||||
boolean useWorkspace = projectNode.getBoolean(PreferenceConstants.P_USE_PARENT,
|
||||
false);
|
||||
Preferences projectNode = CodanPreferencesLoader.getProjectNode((IProject) element);
|
||||
boolean useWorkspace = projectNode.getBoolean(PreferenceConstants.P_USE_PARENT, false);
|
||||
if (!useWorkspace) {
|
||||
loader.load(projectNode);
|
||||
}
|
||||
|
@ -394,7 +386,7 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @seeorg.eclipse.cdt.codan.core.model.ICheckersRegistry#
|
||||
* getResourceProfileWorkingCopy(org.eclipse.core.resources.IResource)
|
||||
*/
|
||||
|
@ -409,9 +401,10 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
}
|
||||
|
||||
/**
|
||||
* Tests if a checker is enabled (needs to be run) or not. Checker is enabled
|
||||
* Tests if a checker is enabled (needs to be run) or not. Checker is
|
||||
* enabled
|
||||
* if at least one problem it reports is enabled.
|
||||
*
|
||||
*
|
||||
* @param checker
|
||||
* @param resource
|
||||
* @return <code>true</code> if the checker is enabled
|
||||
|
@ -434,19 +427,17 @@ public class CheckersRegistry implements Iterable<IChecker>, ICheckersRegistry {
|
|||
|
||||
/**
|
||||
* Tests if a checker needs to run in a specific launch mode.
|
||||
*
|
||||
*
|
||||
* @param checker
|
||||
* @param resource
|
||||
* @param mode
|
||||
* @return <code>true</code> if the checker should run.
|
||||
*/
|
||||
public boolean isCheckerEnabledForLaunchMode(IChecker checker, IResource resource,
|
||||
CheckerLaunchMode mode) {
|
||||
public boolean isCheckerEnabledForLaunchMode(IChecker checker, IResource resource, CheckerLaunchMode mode) {
|
||||
IProblemProfile resourceProfile = getResourceProfile(resource);
|
||||
Collection<IProblem> refProblems = getRefProblems(checker);
|
||||
boolean enabled = false;
|
||||
for (Iterator<IProblem> iterator = refProblems.iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<IProblem> iterator = refProblems.iterator(); iterator.hasNext();) {
|
||||
IProblem p = iterator.next();
|
||||
// we need to check problem enablement in particular profile
|
||||
IProblem problem = resourceProfile.findProblem(p.getId());
|
||||
|
|
|
@ -38,8 +38,7 @@ public class CodanApplication implements IApplication {
|
|||
private boolean all = false;
|
||||
|
||||
public Object start(IApplicationContext context) throws Exception {
|
||||
String[] args = (String[]) context.getArguments().get(
|
||||
"application.args"); //$NON-NLS-1$
|
||||
String[] args = (String[]) context.getArguments().get("application.args"); //$NON-NLS-1$
|
||||
if (args == null || args.length == 0) {
|
||||
help();
|
||||
return EXIT_OK;
|
||||
|
@ -51,8 +50,7 @@ public class CodanApplication implements IApplication {
|
|||
@Override
|
||||
protected void reportProblem(ICodanProblemMarker pm) {
|
||||
IResource file = pm.getResource();
|
||||
System.out.println(file.getLocation()
|
||||
+ ":" + pm.getLocation().getLineNumber() + ": " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
System.out.println(file.getLocation() + ":" + pm.getLocation().getLineNumber() + ": " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ pm.createMessage());
|
||||
}
|
||||
});
|
||||
|
@ -65,15 +63,11 @@ public class CodanApplication implements IApplication {
|
|||
log(Messages.CodanApplication_LogRunProject + project);
|
||||
IProject wProject = root.getProject(project);
|
||||
if (!wProject.exists()) {
|
||||
System.err
|
||||
.println( //
|
||||
NLS.bind(
|
||||
Messages.CodanApplication_Error_ProjectDoesNotExists,
|
||||
project));
|
||||
System.err.println( //
|
||||
NLS.bind(Messages.CodanApplication_Error_ProjectDoesNotExists, project));
|
||||
continue;
|
||||
}
|
||||
codanBuilder.processResource(wProject,
|
||||
new NullProgressMonitor());
|
||||
codanBuilder.processResource(wProject, new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
return EXIT_OK;
|
||||
|
|
|
@ -31,8 +31,7 @@ import org.eclipse.core.runtime.SubProgressMonitor;
|
|||
/**
|
||||
* Implementation of {@link ICodanBuilder}
|
||||
*/
|
||||
public class CodanBuilder extends IncrementalProjectBuilder implements
|
||||
ICodanBuilder {
|
||||
public class CodanBuilder extends IncrementalProjectBuilder implements ICodanBuilder {
|
||||
/**
|
||||
* codan builder id
|
||||
*/
|
||||
|
@ -76,8 +75,7 @@ public class CodanBuilder extends IncrementalProjectBuilder implements
|
|||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
protected IProject[] build(int kind, Map args, IProgressMonitor monitor)
|
||||
throws CoreException {
|
||||
protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
|
||||
if (kind == FULL_BUILD) {
|
||||
fullBuild(monitor);
|
||||
} else {
|
||||
|
@ -92,19 +90,14 @@ public class CodanBuilder extends IncrementalProjectBuilder implements
|
|||
}
|
||||
|
||||
public void processResource(IResource resource, IProgressMonitor monitor) {
|
||||
processResource(resource, monitor, null,
|
||||
CheckerLaunchMode.RUN_ON_FULL_BUILD);
|
||||
processResource(resource, monitor, null, CheckerLaunchMode.RUN_ON_FULL_BUILD);
|
||||
}
|
||||
|
||||
public void processResourceDelta(IResource resource,
|
||||
IProgressMonitor monitor) {
|
||||
processResource(resource, monitor, null,
|
||||
CheckerLaunchMode.RUN_ON_INC_BUILD);
|
||||
public void processResourceDelta(IResource resource, IProgressMonitor monitor) {
|
||||
processResource(resource, monitor, null, CheckerLaunchMode.RUN_ON_INC_BUILD);
|
||||
}
|
||||
|
||||
protected void processResource(IResource resource,
|
||||
IProgressMonitor monitor, Object model,
|
||||
CheckerLaunchMode checkerLaunchMode) {
|
||||
protected void processResource(IResource resource, IProgressMonitor monitor, Object model, CheckerLaunchMode checkerLaunchMode) {
|
||||
CheckersRegistry chegistry = CheckersRegistry.getInstance();
|
||||
int checkers = chegistry.getCheckersSize();
|
||||
int memsize = 0;
|
||||
|
@ -118,27 +111,21 @@ public class CodanBuilder extends IncrementalProjectBuilder implements
|
|||
}
|
||||
int tick = 1000;
|
||||
// System.err.println("processing " + resource);
|
||||
monitor.beginTask(Messages.CodanBuilder_Code_Analysis_On + resource,
|
||||
checkers + memsize * tick);
|
||||
monitor.beginTask(Messages.CodanBuilder_Code_Analysis_On + resource, checkers + memsize * tick);
|
||||
try {
|
||||
for (IChecker checker : chegistry) {
|
||||
try {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
if (checker.enabledInContext(resource)
|
||||
&& chegistry.isCheckerEnabledForLaunchMode(checker,
|
||||
resource, checkerLaunchMode)) {
|
||||
if (checker.enabledInContext(resource) && chegistry.isCheckerEnabledForLaunchMode(checker, resource, checkerLaunchMode)) {
|
||||
synchronized (checker) {
|
||||
try {
|
||||
checker.before(resource);
|
||||
if (chegistry.isCheckerEnabled(checker,
|
||||
resource)) {
|
||||
if (chegistry.isCheckerEnabled(checker, resource)) {
|
||||
//long time = System.currentTimeMillis();
|
||||
if (checkerLaunchMode == CheckerLaunchMode.RUN_AS_YOU_TYPE) {
|
||||
if (checker.runInEditor()
|
||||
&& checker instanceof IRunnableInEditorChecker) {
|
||||
((IRunnableInEditorChecker) checker)
|
||||
.processModel(model);
|
||||
if (checker.runInEditor() && checker instanceof IRunnableInEditorChecker) {
|
||||
((IRunnableInEditorChecker) checker).processModel(model);
|
||||
}
|
||||
} else {
|
||||
checker.processResource(resource);
|
||||
|
@ -160,16 +147,14 @@ public class CodanBuilder extends IncrementalProjectBuilder implements
|
|||
CodanCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
if (resource instanceof IContainer
|
||||
&& (checkerLaunchMode == CheckerLaunchMode.RUN_ON_FULL_BUILD)) {
|
||||
if (resource instanceof IContainer && (checkerLaunchMode == CheckerLaunchMode.RUN_ON_FULL_BUILD)) {
|
||||
try {
|
||||
IResource[] members = ((IContainer) resource).members();
|
||||
for (int i = 0; i < members.length; i++) {
|
||||
if (monitor.isCanceled())
|
||||
return;
|
||||
IResource member = members[i];
|
||||
processResource(member, new SubProgressMonitor(monitor,
|
||||
tick));
|
||||
processResource(member, new SubProgressMonitor(monitor, tick));
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CodanCorePlugin.log(e);
|
||||
|
@ -189,13 +174,11 @@ public class CodanBuilder extends IncrementalProjectBuilder implements
|
|||
return true;
|
||||
}
|
||||
|
||||
protected void fullBuild(final IProgressMonitor monitor)
|
||||
throws CoreException {
|
||||
protected void fullBuild(final IProgressMonitor monitor) throws CoreException {
|
||||
processResource(getProject(), monitor);
|
||||
}
|
||||
|
||||
protected void incrementalBuild(IResourceDelta delta,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
protected void incrementalBuild(IResourceDelta delta, IProgressMonitor monitor) throws CoreException {
|
||||
// the visitor does the work.
|
||||
delta.accept(new CodanDeltaVisitor(monitor));
|
||||
}
|
||||
|
@ -207,11 +190,9 @@ public class CodanBuilder extends IncrementalProjectBuilder implements
|
|||
* @param resource - resource to process
|
||||
* @param monitor - progress monitor
|
||||
*/
|
||||
public void runInEditor(Object model, IResource resource,
|
||||
IProgressMonitor monitor) {
|
||||
public void runInEditor(Object model, IResource resource, IProgressMonitor monitor) {
|
||||
if (model == null)
|
||||
return;
|
||||
processResource(resource, monitor, model,
|
||||
CheckerLaunchMode.RUN_AS_YOU_TYPE);
|
||||
processResource(resource, monitor, model, CheckerLaunchMode.RUN_AS_YOU_TYPE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,8 +135,7 @@ public class CodanPreferencesLoader {
|
|||
* @param problemId
|
||||
* @param storePreferences
|
||||
*/
|
||||
private void setProblemPreferenceValues(String problemId,
|
||||
Preferences storePreferences) {
|
||||
private void setProblemPreferenceValues(String problemId, Preferences storePreferences) {
|
||||
IProblem prob = baseModel.findProblem(problemId);
|
||||
String prefKey = getPreferencesKey(problemId);
|
||||
if (prefKey == null)
|
||||
|
@ -161,8 +160,7 @@ public class CodanPreferencesLoader {
|
|||
public static Preferences getProjectNode(IProject project) {
|
||||
if (!project.exists())
|
||||
return null;
|
||||
Preferences prefNode = new ProjectScope(project)
|
||||
.getNode(CodanCorePlugin.PLUGIN_ID);
|
||||
Preferences prefNode = new ProjectScope(project).getNode(CodanCorePlugin.PLUGIN_ID);
|
||||
if (prefNode == null)
|
||||
return null;
|
||||
return prefNode;
|
||||
|
@ -174,8 +172,7 @@ public class CodanPreferencesLoader {
|
|||
* @return project preferences node
|
||||
*/
|
||||
public static Preferences getWorkspaceNode() {
|
||||
Preferences prefNode = new InstanceScope()
|
||||
.getNode(CodanCorePlugin.PLUGIN_ID);
|
||||
Preferences prefNode = new InstanceScope().getNode(CodanCorePlugin.PLUGIN_ID);
|
||||
if (prefNode == null)
|
||||
return null;
|
||||
return prefNode;
|
||||
|
|
|
@ -50,8 +50,7 @@ public class CodeAnlysisNature implements IProjectNature {
|
|||
if (commands[i].getBuilderName().equals(CodanBuilder.BUILDER_ID)) {
|
||||
ICommand[] newCommands = new ICommand[commands.length - 1];
|
||||
System.arraycopy(commands, 0, newCommands, 0, i);
|
||||
System.arraycopy(commands, i + 1, newCommands, i,
|
||||
commands.length - i - 1);
|
||||
System.arraycopy(commands, i + 1, newCommands, i, commands.length - i - 1);
|
||||
description.setBuildSpec(newCommands);
|
||||
project.setDescription(description, null);
|
||||
return;
|
||||
|
|
|
@ -17,8 +17,7 @@ import org.eclipse.cdt.codan.core.model.cfg.ISingleIncoming;
|
|||
* Abstract node with one incoming arc (node)
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock
|
||||
implements ISingleIncoming {
|
||||
public abstract class AbstractSingleIncomingNode extends AbstractBasicBlock implements ISingleIncoming {
|
||||
private IBasicBlock prev;
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,8 +17,7 @@ import org.eclipse.cdt.codan.core.model.cfg.ISingleOutgoing;
|
|||
* Abstract implementation of basic block with single outgoing arc (node)
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock
|
||||
implements ISingleOutgoing {
|
||||
public abstract class AbstractSingleOutgoingNode extends AbstractBasicBlock implements ISingleOutgoing {
|
||||
private IBasicBlock next;
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,8 +19,7 @@ import org.eclipse.cdt.codan.core.model.cfg.IJumpNode;
|
|||
/**
|
||||
* TODO: add description
|
||||
*/
|
||||
public class ConnectorNode extends AbstractSingleOutgoingNode implements
|
||||
IConnectorNode {
|
||||
public class ConnectorNode extends AbstractSingleOutgoingNode implements IConnectorNode {
|
||||
protected ArrayList<IBasicBlock> incoming = new ArrayList<IBasicBlock>(2);
|
||||
|
||||
protected ConnectorNode() {
|
||||
|
|
|
@ -49,15 +49,12 @@ public class ControlFlowGraph implements IControlFlowGraph {
|
|||
|
||||
public void setExitNodes(Collection<IExitNode> exitNodes) {
|
||||
if (this.exitNodes != null)
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
this.exitNodes = Collections.unmodifiableList(new ArrayList<IExitNode>(
|
||||
exitNodes));
|
||||
throw new IllegalArgumentException("Cannot modify already exiting connector"); //$NON-NLS-1$
|
||||
this.exitNodes = Collections.unmodifiableList(new ArrayList<IExitNode>(exitNodes));
|
||||
}
|
||||
|
||||
public void setUnconnectedNodes(Collection<IBasicBlock> nodes) {
|
||||
this.deadNodes = Collections
|
||||
.unmodifiableList(new ArrayList<IBasicBlock>(nodes));
|
||||
this.deadNodes = Collections.unmodifiableList(new ArrayList<IBasicBlock>(nodes));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -122,8 +119,7 @@ public class ControlFlowGraph implements IControlFlowGraph {
|
|||
public Collection<IBasicBlock> getNodes() {
|
||||
Collection<IBasicBlock> result = new LinkedHashSet<IBasicBlock>();
|
||||
getNodes(getStartNode(), result);
|
||||
for (Iterator<IBasicBlock> iterator = deadNodes.iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<IBasicBlock> iterator = deadNodes.iterator(); iterator.hasNext();) {
|
||||
IBasicBlock d = iterator.next();
|
||||
getNodes(d, result);
|
||||
}
|
||||
|
|
|
@ -21,8 +21,7 @@ import org.eclipse.cdt.codan.core.model.cfg.IDecisionNode;
|
|||
/**
|
||||
* @see {@link IDecisionNode}
|
||||
*/
|
||||
public class DecisionNode extends AbstractSingleIncomingNode implements
|
||||
IDecisionNode {
|
||||
public class DecisionNode extends AbstractSingleIncomingNode implements IDecisionNode {
|
||||
private List<IBasicBlock> next = new ArrayList<IBasicBlock>(2);
|
||||
private IConnectorNode conn;
|
||||
|
||||
|
|
|
@ -54,8 +54,7 @@ public class JumpNode extends AbstractSingleIncomingNode implements IJumpNode {
|
|||
|
||||
public void setJump(IConnectorNode jump, boolean backward) {
|
||||
if (this.jump != null && this.jump != jump)
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot modify exiting connector"); //$NON-NLS-1$
|
||||
throw new IllegalArgumentException("Cannot modify exiting connector"); //$NON-NLS-1$
|
||||
this.jump = jump;
|
||||
this.backward = backward;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
/**
|
||||
* Problem reported that created eclipse markers
|
||||
*/
|
||||
public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
||||
implements IProblemReporterPersistent,
|
||||
public class CodanMarkerProblemReporter extends AbstractProblemReporter implements IProblemReporterPersistent,
|
||||
IProblemReporterSessionPersistent {
|
||||
private IResource resource;
|
||||
private IChecker checker;
|
||||
|
@ -92,8 +91,7 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
|
||||
public void deleteProblems(IResource file) {
|
||||
try {
|
||||
file.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true,
|
||||
IResource.DEPTH_ZERO);
|
||||
file.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_ZERO);
|
||||
} catch (CoreException ce) {
|
||||
ce.printStackTrace();
|
||||
}
|
||||
|
@ -101,11 +99,7 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
|
||||
public void deleteAllProblems() {
|
||||
try {
|
||||
ResourcesPlugin
|
||||
.getWorkspace()
|
||||
.getRoot()
|
||||
.deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true,
|
||||
IResource.DEPTH_INFINITE);
|
||||
ResourcesPlugin.getWorkspace().getRoot().deleteMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_INFINITE);
|
||||
} catch (CoreException e) {
|
||||
CodanCorePlugin.log(e);
|
||||
}
|
||||
|
@ -115,10 +109,8 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
try {
|
||||
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
Collection<IMarker> markers = findResourceMarkers(file,
|
||||
checker);
|
||||
for (Iterator<IMarker> iterator = markers.iterator(); iterator
|
||||
.hasNext();) {
|
||||
Collection<IMarker> markers = findResourceMarkers(file, checker);
|
||||
for (Iterator<IMarker> iterator = markers.iterator(); iterator.hasNext();) {
|
||||
IMarker iMarker = iterator.next();
|
||||
iMarker.delete();
|
||||
}
|
||||
|
@ -129,29 +121,23 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
}
|
||||
}
|
||||
|
||||
protected Collection<IMarker> findResourceMarkers(IResource resource,
|
||||
IChecker checker) throws CoreException {
|
||||
protected Collection<IMarker> findResourceMarkers(IResource resource, IChecker checker) throws CoreException {
|
||||
Collection<IMarker> res = new ArrayList<IMarker>();
|
||||
IMarker[] markers;
|
||||
if (resource.exists()) {
|
||||
markers = resource.findMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE,
|
||||
true, IResource.DEPTH_INFINITE);
|
||||
markers = resource.findMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_INFINITE);
|
||||
} else {
|
||||
if (resource.getProject() == null || !resource.getProject().isAccessible())
|
||||
return res;
|
||||
// non resource markers attached to a project itself
|
||||
markers = resource.getProject().findMarkers(
|
||||
GENERIC_CODE_ANALYSIS_MARKER_TYPE, true,
|
||||
IResource.DEPTH_ZERO);
|
||||
markers = resource.getProject().findMarkers(GENERIC_CODE_ANALYSIS_MARKER_TYPE, true, IResource.DEPTH_ZERO);
|
||||
}
|
||||
ICheckersRegistry reg = CodanRuntime.getInstance()
|
||||
.getCheckersRegistry();
|
||||
ICheckersRegistry reg = CodanRuntime.getInstance().getCheckersRegistry();
|
||||
Collection<IProblem> problems = reg.getRefProblems(checker);
|
||||
for (int i = 0; i < markers.length; i++) {
|
||||
IMarker m = markers[i];
|
||||
String id = m.getAttribute(ICodanProblemMarker.ID, ""); //$NON-NLS-1$
|
||||
for (Iterator<IProblem> iterator = problems.iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<IProblem> iterator = problems.iterator(); iterator.hasNext();) {
|
||||
IProblem iProblem = iterator.next();
|
||||
if (iProblem.getId().equals(id)) {
|
||||
res.add(m);
|
||||
|
@ -167,8 +153,7 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
* @return session aware problem reporter
|
||||
* @since 1.1
|
||||
*/
|
||||
public IProblemReporterSessionPersistent createReporter(IResource resource,
|
||||
IChecker checker) {
|
||||
public IProblemReporterSessionPersistent createReporter(IResource resource, IChecker checker) {
|
||||
return new CodanMarkerProblemReporter(resource, checker);
|
||||
}
|
||||
|
||||
|
@ -191,10 +176,8 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
try {
|
||||
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
Collection<IMarker> markers = findResourceMarkers(resource,
|
||||
checker);
|
||||
for (Iterator<IMarker> iterator = markers.iterator(); iterator
|
||||
.hasNext();) {
|
||||
Collection<IMarker> markers = findResourceMarkers(resource, checker);
|
||||
for (Iterator<IMarker> iterator = markers.iterator(); iterator.hasNext();) {
|
||||
IMarker m = iterator.next();
|
||||
ICodanProblemMarker cm = similarMarker(m);
|
||||
if (cm == null) {
|
||||
|
@ -204,8 +187,7 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
toAdd.remove(cm);
|
||||
}
|
||||
}
|
||||
for (Iterator<ICodanProblemMarker> iterator = toAdd
|
||||
.iterator(); iterator.hasNext();) {
|
||||
for (Iterator<ICodanProblemMarker> iterator = toAdd.iterator(); iterator.hasNext();) {
|
||||
ICodanProblemMarker cm = iterator.next();
|
||||
cm.createMarker();
|
||||
}
|
||||
|
@ -244,11 +226,9 @@ public class CodanMarkerProblemReporter extends AbstractProblemReporter
|
|||
* @return
|
||||
*/
|
||||
protected ICodanProblemMarker similarMarker(IMarker m) {
|
||||
ICodanProblemMarker mcm = CodanProblemMarker
|
||||
.createCodanProblemMarkerFromResourceMarker(m);
|
||||
ICodanProblemMarker mcm = CodanProblemMarker.createCodanProblemMarkerFromResourceMarker(m);
|
||||
ArrayList<ICodanProblemMarker> cand = new ArrayList<ICodanProblemMarker>();
|
||||
for (Iterator<ICodanProblemMarker> iterator = toAdd.iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<ICodanProblemMarker> iterator = toAdd.iterator(); iterator.hasNext();) {
|
||||
ICodanProblemMarker cm = iterator.next();
|
||||
if (mcm.equals(cm))
|
||||
return cm;
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.eclipse.cdt.codan.core.param.IProblemPreference;
|
|||
* A type of problems reported by Codan.
|
||||
*/
|
||||
public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
||||
|
||||
private String id;
|
||||
private String name;
|
||||
private String messagePattern;
|
||||
|
@ -73,7 +72,7 @@ public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see java.lang.Object#clone()
|
||||
*/
|
||||
@Override
|
||||
|
@ -100,7 +99,7 @@ public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.IProblem#getMessagePattern()
|
||||
*/
|
||||
public String getMessagePattern() {
|
||||
|
@ -113,7 +112,7 @@ public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
|||
|
||||
/**
|
||||
* @param messagePattern
|
||||
* the message to set
|
||||
* the message to set
|
||||
*/
|
||||
public void setMessagePattern(String messagePattern) {
|
||||
checkSet();
|
||||
|
@ -127,7 +126,7 @@ public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.IProblem#getDescription()
|
||||
*/
|
||||
public String getDescription() {
|
||||
|
@ -136,7 +135,7 @@ public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.cdt.codan.core.model.IProblemWorkingCopy#setDescription(java
|
||||
* .lang.String)
|
||||
|
@ -147,7 +146,7 @@ public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
*
|
||||
* @see org.eclipse.cdt.codan.core.model.IProblem#getMarkerType()
|
||||
*/
|
||||
public String getMarkerType() {
|
||||
|
@ -156,7 +155,7 @@ public class CodanProblem implements IProblemWorkingCopy, Cloneable {
|
|||
|
||||
/**
|
||||
* Sets the marker id for the problem.
|
||||
|
||||
*
|
||||
* @param markerType
|
||||
*/
|
||||
public void setMarkerType(String markerType) {
|
||||
|
|
|
@ -73,8 +73,7 @@ public class CodanProblemCategory implements IProblemCategory, Cloneable {
|
|||
* @param id - problem id
|
||||
* @return list of categories
|
||||
*/
|
||||
public static IProblemCategory[] findProblemCategories(IProblemCategory c,
|
||||
String id) {
|
||||
public static IProblemCategory[] findProblemCategories(IProblemCategory c, String id) {
|
||||
ArrayList<IProblemCategory> list = new ArrayList<IProblemCategory>();
|
||||
Object[] children = c.getChildren();
|
||||
for (Object object : children) {
|
||||
|
@ -119,8 +118,7 @@ public class CodanProblemCategory implements IProblemCategory, Cloneable {
|
|||
try {
|
||||
CodanProblemCategory clone = (CodanProblemCategory) super.clone();
|
||||
clone.list = new ArrayList<IProblemElement>();
|
||||
for (Iterator<IProblemElement> iterator = this.list.iterator(); iterator
|
||||
.hasNext();) {
|
||||
for (Iterator<IProblemElement> iterator = this.list.iterator(); iterator.hasNext();) {
|
||||
IProblemElement child = iterator.next();
|
||||
clone.list.add((IProblemElement) child.clone());
|
||||
}
|
||||
|
|
|
@ -25,8 +25,7 @@ public class CodanProblemLocation extends AbstractProblemLocation {
|
|||
* @param endChar - end char, absolute file offset, exclusive
|
||||
* @param line - line number
|
||||
*/
|
||||
public CodanProblemLocation(IResource file, int startChar, int endChar,
|
||||
int line) {
|
||||
public CodanProblemLocation(IResource file, int startChar, int endChar, int line) {
|
||||
super(file, startChar, endChar);
|
||||
this.line = line;
|
||||
}
|
||||
|
|
|
@ -49,8 +49,7 @@ public class CodanProblemMarker implements ICodanProblemMarker {
|
|||
* @param loc
|
||||
* @param args
|
||||
*/
|
||||
public CodanProblemMarker(IProblem problem, IProblemLocation loc,
|
||||
Object[] args) {
|
||||
public CodanProblemMarker(IProblem problem, IProblemLocation loc, Object[] args) {
|
||||
this.problem = problem;
|
||||
this.loc = loc;
|
||||
this.args = args;
|
||||
|
@ -102,8 +101,7 @@ public class CodanProblemMarker implements ICodanProblemMarker {
|
|||
marker.setAttribute(IMarker.CHAR_START, loc.getStartingChar());
|
||||
String propArgs = serializeArgs(args);
|
||||
marker.setAttribute(PROBLEM_ARGS, propArgs);
|
||||
IProblemCategory[] cats = CodanProblemCategory.findProblemCategories(
|
||||
getProfile(file).getRoot(), problem.getId());
|
||||
IProblemCategory[] cats = CodanProblemCategory.findProblemCategories(getProfile(file).getRoot(), problem.getId());
|
||||
String cat = cats.length > 0 ? cats[0].getId() : ""; //$NON-NLS-1$
|
||||
marker.setAttribute(CATEGORY, cat);
|
||||
return marker;
|
||||
|
@ -227,8 +225,7 @@ public class CodanProblemMarker implements ICodanProblemMarker {
|
|||
* @return new instanceof of ICodanProblemMarker or null if marker is not
|
||||
* codan marker
|
||||
*/
|
||||
public static ICodanProblemMarker createCodanProblemMarkerFromResourceMarker(
|
||||
IMarker marker) {
|
||||
public static ICodanProblemMarker createCodanProblemMarkerFromResourceMarker(IMarker marker) {
|
||||
CodanProblem problem = getProblem(marker);
|
||||
if (problem == null)
|
||||
return null;
|
||||
|
@ -246,8 +243,7 @@ public class CodanProblemMarker implements ICodanProblemMarker {
|
|||
return null;
|
||||
IResource resource = marker.getResource();
|
||||
IProblemProfile profile = getProfile(resource);
|
||||
CodanProblem problem = (CodanProblem) ((CodanProblem) profile
|
||||
.findProblem(id)).clone();
|
||||
CodanProblem problem = (CodanProblem) ((CodanProblem) profile.findProblem(id)).clone();
|
||||
CodanSeverity sev = getSeverity(marker);
|
||||
problem.setSeverity(sev);
|
||||
return problem;
|
||||
|
@ -258,8 +254,7 @@ public class CodanProblemMarker implements ICodanProblemMarker {
|
|||
* @return
|
||||
*/
|
||||
public static IProblemProfile getProfile(IResource resource) {
|
||||
IProblemProfile profile = CheckersRegistry.getInstance()
|
||||
.getResourceProfile(resource);
|
||||
IProblemProfile profile = CheckersRegistry.getInstance().getResourceProfile(resource);
|
||||
return profile;
|
||||
}
|
||||
|
||||
|
@ -271,8 +266,7 @@ public class CodanProblemMarker implements ICodanProblemMarker {
|
|||
int line = marker.getAttribute(IMarker.LINE_NUMBER, -1);
|
||||
int charend = marker.getAttribute(IMarker.CHAR_END, -1);
|
||||
int charstart = marker.getAttribute(IMarker.CHAR_START, -1);
|
||||
CodanProblemLocation loc = new CodanProblemLocation(
|
||||
marker.getResource(), charstart, charend, line);
|
||||
CodanProblemLocation loc = new CodanProblemLocation(marker.getResource(), charstart, charend, line);
|
||||
return loc;
|
||||
}
|
||||
|
||||
|
@ -281,8 +275,7 @@ public class CodanProblemMarker implements ICodanProblemMarker {
|
|||
* @param res
|
||||
* @throws CoreException
|
||||
*/
|
||||
public static void setProblemArguments(IMarker marker, String[] args)
|
||||
throws CoreException {
|
||||
public static void setProblemArguments(IMarker marker, String[] args) throws CoreException {
|
||||
String propArgs = serializeArgs(args);
|
||||
marker.setAttribute(PROBLEM_ARGS, propArgs);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,7 @@ public class ProblemLocationFactory implements IProblemLocationFactory {
|
|||
* @seeorg.eclipse.cdt.codan.core.model.IProblemLocationFactory#
|
||||
* createProblemLocation(org.eclipse.core.resources.IFile, int, int)
|
||||
*/
|
||||
public IProblemLocation createProblemLocation(IFile file, int startChar,
|
||||
int endChar) {
|
||||
public IProblemLocation createProblemLocation(IFile file, int startChar, int endChar) {
|
||||
return new CodanProblemLocation(file, startChar, endChar);
|
||||
}
|
||||
|
||||
|
@ -46,8 +45,7 @@ public class ProblemLocationFactory implements IProblemLocationFactory {
|
|||
* @seeorg.eclipse.cdt.codan.core.model.IProblemLocationFactory#
|
||||
* createProblemLocation(org.eclipse.core.resources.IFile, int, int, int)
|
||||
*/
|
||||
public IProblemLocation createProblemLocation(IFile file, int startChar,
|
||||
int endChar, int line) {
|
||||
public IProblemLocation createProblemLocation(IFile file, int startChar, int endChar, int line) {
|
||||
return new CodanProblemLocation(file, startChar, endChar, line);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,8 @@ public class ProblemProfile implements IProblemProfile, Cloneable {
|
|||
}
|
||||
|
||||
public void addProblem(IProblem p, IProblemCategory cat) {
|
||||
if (cat == null) cat = getRoot();
|
||||
if (cat == null)
|
||||
cat = getRoot();
|
||||
((CodanProblemCategory) cat).addChild(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ import org.osgi.framework.BundleContext;
|
|||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class Activator extends Plugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "org.eclipse.cdt.codan.examples"; //$NON-NLS-1$
|
||||
|
||||
// The shared instance
|
||||
private static Activator plugin;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
|
@ -32,7 +30,9 @@ public class Activator extends Plugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
|
@ -41,7 +41,9 @@ public class Activator extends Plugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
|
@ -50,11 +52,10 @@ public class Activator extends Plugin {
|
|||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static Activator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,16 +46,13 @@ public class GrepChecker extends AbstractCheckerWithProblemPreferences {
|
|||
}
|
||||
|
||||
void processFile(IFile file) {
|
||||
Collection<IProblem> refProblems = getRuntime().getCheckersRegistry()
|
||||
.getRefProblems(this);
|
||||
for (Iterator<IProblem> iterator = refProblems.iterator(); iterator
|
||||
.hasNext();) {
|
||||
Collection<IProblem> refProblems = getRuntime().getCheckersRegistry().getRefProblems(this);
|
||||
for (Iterator<IProblem> iterator = refProblems.iterator(); iterator.hasNext();) {
|
||||
IProblem checkerProblem = iterator.next();
|
||||
IProblem problem = getProblemById(checkerProblem.getId(), file);
|
||||
if (shouldProduceProblem(problem, file.getLocation())) {
|
||||
// do something
|
||||
Object[] values = (Object[]) getPreference(problem,
|
||||
PARAM_STRING_LIST);
|
||||
Object[] values = (Object[]) getPreference(problem, PARAM_STRING_LIST);
|
||||
if (values.length == 0)
|
||||
continue; // nothing to do
|
||||
externalRun(file, values, problem);
|
||||
|
@ -81,8 +78,7 @@ public class GrepChecker extends AbstractCheckerWithProblemPreferences {
|
|||
for (int i = 0; i < values.length; i++) {
|
||||
String str = (String) values[i];
|
||||
if (line.contains(str)) {
|
||||
reportProblem(problem.getId(), file, iline, "Found "
|
||||
+ str);
|
||||
reportProblem(problem.getId(), file, iline, "Found " + str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +100,6 @@ public class GrepChecker extends AbstractCheckerWithProblemPreferences {
|
|||
@Override
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
addListPreference(problem, PARAM_STRING_LIST, "Search strings",
|
||||
"Search string");
|
||||
addListPreference(problem, PARAM_STRING_LIST, "Search strings", "Search string");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
|
|||
* @author Alena
|
||||
*
|
||||
*/
|
||||
public class NamingConventionFunctionIIndexChecker extends
|
||||
AbstractCIndexChecker implements ICheckerWithPreferences {
|
||||
public class NamingConventionFunctionIIndexChecker extends AbstractCIndexChecker implements ICheckerWithPreferences {
|
||||
private static final String DEFAULT_PATTERN = "^[a-z]"; // name starts with english lowercase letter //$NON-NLS-1$
|
||||
public static final String PARAM_KEY = "pattern"; //$NON-NLS-1$
|
||||
private static final String ER_ID = "org.eclipse.cdt.codan.examples.checkers.NamingConventionFunctionProblem"; //$NON-NLS-1$
|
||||
|
@ -47,8 +46,7 @@ public class NamingConventionFunctionIIndexChecker extends
|
|||
unit.accept(new ICElementVisitor() {
|
||||
public boolean visit(ICElement element) {
|
||||
if (element.getElementType() == ICElement.C_FUNCTION) {
|
||||
String parameter = (String) pt.getPreference()
|
||||
.getValue();
|
||||
String parameter = (String) pt.getPreference().getValue();
|
||||
Pattern pattern = Pattern.compile(parameter);
|
||||
String name = element.getElementName();
|
||||
if (!pattern.matcher(name).find()) {
|
||||
|
@ -74,8 +72,7 @@ public class NamingConventionFunctionIIndexChecker extends
|
|||
*/
|
||||
public void initPreferences(IProblemWorkingCopy problem) {
|
||||
super.initPreferences(problem);
|
||||
IProblemPreference info = new BasicProblemPreference(PARAM_KEY,
|
||||
"Name Pattern");
|
||||
IProblemPreference info = new BasicProblemPreference(PARAM_KEY, "Name Pattern");
|
||||
addPreference(problem, info, DEFAULT_PATTERN);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,4 @@ public class FlexlintHelpLink extends AbstractCodanProblemDetailsProvider {
|
|||
String url = "http://www.gimpel-online.com/MsgRef.html#" + helpId;
|
||||
return "<a href=\"" + url + "\">" + url + "</a>";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -10,13 +10,11 @@ import org.osgi.framework.BundleContext;
|
|||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class ControlFlowGraphPlugin extends AbstractUIPlugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "org.eclipse.cdt.codan.ui.cfgview"; //$NON-NLS-1$
|
||||
|
||||
// The shared instance
|
||||
private static ControlFlowGraphPlugin plugin;
|
||||
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
|
@ -25,7 +23,10 @@ public class ControlFlowGraphPlugin extends AbstractUIPlugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
|
||||
* )
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
|
@ -34,7 +35,10 @@ public class ControlFlowGraphPlugin extends AbstractUIPlugin {
|
|||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
|
||||
*
|
||||
* @see
|
||||
* org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
|
||||
* )
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
|
@ -43,7 +47,7 @@ public class ControlFlowGraphPlugin extends AbstractUIPlugin {
|
|||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static ControlFlowGraphPlugin getDefault() {
|
||||
|
@ -53,7 +57,7 @@ public class ControlFlowGraphPlugin extends AbstractUIPlugin {
|
|||
/**
|
||||
* Returns an image descriptor for the image file at the given
|
||||
* plug-in relative path
|
||||
*
|
||||
*
|
||||
* @param path the path
|
||||
* @return the image descriptor
|
||||
*/
|
||||
|
@ -61,22 +65,20 @@ public class ControlFlowGraphPlugin extends AbstractUIPlugin {
|
|||
ImageRegistry registry = getImageRegistry();
|
||||
ImageDescriptor descriptor = registry.getDescriptor(key);
|
||||
if (descriptor == null) {
|
||||
descriptor = imageDescriptorFromPlugin(PLUGIN_ID,key);
|
||||
descriptor = imageDescriptorFromPlugin(PLUGIN_ID, key);
|
||||
registry.put(key, descriptor);
|
||||
}
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
public Image getImage(String key) {
|
||||
ImageRegistry registry = getImageRegistry();
|
||||
Image image = registry.get(key);
|
||||
if (image == null) {
|
||||
ImageDescriptor descriptor = imageDescriptorFromPlugin(PLUGIN_ID,key);
|
||||
ImageDescriptor descriptor = imageDescriptorFromPlugin(PLUGIN_ID, key);
|
||||
registry.put(key, descriptor);
|
||||
image = registry.get(key);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -96,9 +96,10 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
private Action action1;
|
||||
private Action doubleClickAction;
|
||||
|
||||
class DeadNodes extends ArrayList<IBasicBlock> {}
|
||||
class ViewContentProvider implements IStructuredContentProvider,
|
||||
ITreeContentProvider {
|
||||
class DeadNodes extends ArrayList<IBasicBlock> {
|
||||
}
|
||||
|
||||
class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider {
|
||||
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
|
||||
}
|
||||
|
||||
|
@ -117,32 +118,29 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
if (parent instanceof Collection) {
|
||||
return ((Collection) parent).toArray();
|
||||
} else if (parent instanceof IControlFlowGraph) {
|
||||
Collection<IBasicBlock> blocks = getFlat(
|
||||
((IControlFlowGraph) parent).getStartNode(),
|
||||
new ArrayList<IBasicBlock>());
|
||||
Collection<IBasicBlock> blocks = getFlat(((IControlFlowGraph) parent).getStartNode(), new ArrayList<IBasicBlock>());
|
||||
DeadNodes dead = new DeadNodes();
|
||||
Iterator<IBasicBlock> iter = ((IControlFlowGraph) parent).getUnconnectedNodeIterator();
|
||||
for (; iter.hasNext();) {
|
||||
IBasicBlock iBasicBlock = (IBasicBlock) iter.next();
|
||||
dead.add(iBasicBlock);
|
||||
dead.add(iBasicBlock);
|
||||
}
|
||||
ArrayList all = new ArrayList();
|
||||
all.addAll(blocks);
|
||||
if (dead.size()>0) all.add(dead);
|
||||
if (dead.size() > 0)
|
||||
all.add(dead);
|
||||
return all.toArray();
|
||||
} else if (parent instanceof IDecisionNode) {
|
||||
ArrayList blocks = new ArrayList();
|
||||
IBasicBlock[] outgoingNodes = ((IDecisionNode) parent)
|
||||
.getOutgoingNodes();
|
||||
IBasicBlock[] outgoingNodes = ((IDecisionNode) parent).getOutgoingNodes();
|
||||
for (int i = 0; i < outgoingNodes.length; i++) {
|
||||
IBasicBlock arc= outgoingNodes[i];
|
||||
IBasicBlock arc = outgoingNodes[i];
|
||||
blocks.add(arc);
|
||||
}
|
||||
blocks.add(((IDecisionNode) parent).getMergeNode());
|
||||
return blocks.toArray();
|
||||
} else if (parent instanceof IBranchNode) {
|
||||
Collection<IBasicBlock> blocks = getFlat(((IBranchNode) parent)
|
||||
.getOutgoing(), new ArrayList<IBasicBlock>());
|
||||
Collection<IBasicBlock> blocks = getFlat(((IBranchNode) parent).getOutgoing(), new ArrayList<IBasicBlock>());
|
||||
return blocks.toArray();
|
||||
}
|
||||
return new Object[0];
|
||||
|
@ -157,16 +155,14 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
* @param startNode
|
||||
* @return
|
||||
*/
|
||||
public Collection<IBasicBlock> getFlat(IBasicBlock node,
|
||||
Collection<IBasicBlock> list) {
|
||||
public Collection<IBasicBlock> getFlat(IBasicBlock node, Collection<IBasicBlock> list) {
|
||||
list.add(node);
|
||||
if (node instanceof IJumpNode)
|
||||
return list;
|
||||
if (node instanceof ISingleOutgoing) {
|
||||
getFlat(((ISingleOutgoing) node).getOutgoing(), list);
|
||||
} else if (node instanceof IDecisionNode) {
|
||||
getFlat(((IDecisionNode) node).getMergeNode().getOutgoing(),
|
||||
list);
|
||||
getFlat(((IDecisionNode) node).getMergeNode().getOutgoing(), list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
@ -181,9 +177,9 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
strdata = ((AbstractBasicBlock) obj).toStringData();
|
||||
}
|
||||
if (obj instanceof IConnectorNode) {
|
||||
strdata = blockHexLabel(obj) ;
|
||||
strdata = blockHexLabel(obj);
|
||||
} else if (obj instanceof IJumpNode) {
|
||||
strdata = "jump to "+blockHexLabel(((IJumpNode) obj).getJumpNode());
|
||||
strdata = "jump to " + blockHexLabel(((IJumpNode) obj).getJumpNode());
|
||||
}
|
||||
return obj.getClass().getSimpleName() + ": " + strdata;
|
||||
}
|
||||
|
@ -198,8 +194,7 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
|
||||
public Image getImage(Object obj) {
|
||||
String imageKey = "task.png";
|
||||
if (obj instanceof IDecisionNode
|
||||
|| obj instanceof IControlFlowGraph)
|
||||
if (obj instanceof IDecisionNode || obj instanceof IControlFlowGraph)
|
||||
imageKey = "decision.png";
|
||||
else if (obj instanceof IExitNode)
|
||||
imageKey = "exit.png";
|
||||
|
@ -211,8 +206,7 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
imageKey = "labeled.png";
|
||||
else if (obj instanceof IConnectorNode)
|
||||
imageKey = "connector.png";
|
||||
return ControlFlowGraphPlugin.getDefault().getImage(
|
||||
"icons/" + imageKey);
|
||||
return ControlFlowGraphPlugin.getDefault().getImage("icons/" + imageKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,15 +273,11 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
private void makeActions() {
|
||||
action1 = new Action() {
|
||||
public void run() {
|
||||
IEditorPart e = PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow().getActivePage()
|
||||
.getActiveEditor();
|
||||
ITranslationUnit tu = (ITranslationUnit) CDTUITools
|
||||
.getEditorInputCElement(e.getEditorInput());
|
||||
IEditorPart e = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
|
||||
ITranslationUnit tu = (ITranslationUnit) CDTUITools.getEditorInputCElement(e.getEditorInput());
|
||||
Job job = new SharedASTJob("Job Name", tu) {
|
||||
@Override
|
||||
public IStatus runOnAST(ILanguage lang,
|
||||
IASTTranslationUnit ast) throws CoreException {
|
||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
|
||||
processAst(ast);
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
@ -297,13 +287,11 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
};
|
||||
action1.setText("Synchronize");
|
||||
action1.setToolTipText("Synchronize");
|
||||
action1.setImageDescriptor(ControlFlowGraphPlugin.getDefault()
|
||||
.getImageDescriptor("icons/refresh_view.gif"));
|
||||
action1.setImageDescriptor(ControlFlowGraphPlugin.getDefault().getImageDescriptor("icons/refresh_view.gif"));
|
||||
doubleClickAction = new Action() {
|
||||
public void run() {
|
||||
ISelection selection = viewer.getSelection();
|
||||
Object obj = ((IStructuredSelection) selection)
|
||||
.getFirstElement();
|
||||
Object obj = ((IStructuredSelection) selection).getFirstElement();
|
||||
showMessage("Double-click detected on " + obj.toString());
|
||||
}
|
||||
};
|
||||
|
@ -318,8 +306,7 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
}
|
||||
|
||||
private void showMessage(String message) {
|
||||
MessageDialog.openInformation(viewer.getControl().getShell(),
|
||||
"Control Flow Graph", message);
|
||||
MessageDialog.openInformation(viewer.getControl().getShell(), "Control Flow Graph", message);
|
||||
}
|
||||
|
||||
protected void processAst(IASTTranslationUnit ast) {
|
||||
|
@ -331,8 +318,7 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
|
||||
public int visit(IASTDeclaration decl) {
|
||||
if (decl instanceof IASTFunctionDefinition) {
|
||||
CxxControlFlowGraph graph = new ControlFlowGraphBuilder()
|
||||
.build((IASTFunctionDefinition) decl);
|
||||
CxxControlFlowGraph graph = new ControlFlowGraphBuilder().build((IASTFunctionDefinition) decl);
|
||||
functions.add(graph);
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
|
@ -367,11 +353,9 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
this.aPart = part;
|
||||
}
|
||||
|
||||
protected boolean open(String filename) throws PartInitException,
|
||||
CModelException {
|
||||
protected boolean open(String filename) throws PartInitException, CModelException {
|
||||
IPath path = new Path(filename);
|
||||
IFile f = ResourcesPlugin.getWorkspace().getRoot()
|
||||
.getFileForLocation(path);
|
||||
IFile f = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
|
||||
if (f != null) {
|
||||
EditorUtility.openInEditor(f);
|
||||
return true;
|
||||
|
@ -415,13 +399,10 @@ public class ControlFlowGraphView extends ViewPart {
|
|||
// }
|
||||
}
|
||||
if (aPart instanceof AbstractTextEditor) {
|
||||
((AbstractTextEditor) aPart).selectAndReveal(loc
|
||||
.getNodeOffset(), loc.getNodeLength());
|
||||
((AbstractTextEditor) aPart).selectAndReveal(loc.getNodeOffset(), loc.getNodeLength());
|
||||
} else
|
||||
System.out.println(A_PART_INSTANCEOF
|
||||
+ aPart.getClass().getName());
|
||||
aPart.getSite().getPage().activate(
|
||||
aPart.getSite().getPage().findView(ID));
|
||||
System.out.println(A_PART_INSTANCEOF + aPart.getClass().getName());
|
||||
aPart.getSite().getPage().activate(aPart.getSite().getPage().findView(ID));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue