mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-09 19:43:27 +02:00
Refactored common function to utility class
This commit is contained in:
parent
4f2aa8c7db
commit
94cb067beb
2 changed files with 71 additions and 22 deletions
|
@ -11,37 +11,41 @@
|
||||||
package org.eclipse.cdt.codan.internal.checkers;
|
package org.eclipse.cdt.codan.internal.checkers;
|
||||||
|
|
||||||
import org.eclipse.cdt.codan.checkers.CodanCheckersActivator;
|
import org.eclipse.cdt.codan.checkers.CodanCheckersActivator;
|
||||||
|
import org.eclipse.cdt.codan.core.cxx.CxxAstUtils;
|
||||||
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointer;
|
import org.eclipse.cdt.core.dom.ast.IASTPointer;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTryBlockStatement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Catching by reference is recommended by C++ experts, for example Herb Sutter/Andrei Alexandresscu "C++ Coding Standards", Rule 73 "Throw by value, catch by reference".
|
* Catching by reference is recommended by C++ experts, for example Herb
|
||||||
|
* Sutter/Andrei Alexandresscu "C++ Coding Standards", Rule 73
|
||||||
|
* "Throw by value, catch by reference".
|
||||||
* For one thing, this avoids copying and potentially slicing the exception.
|
* For one thing, this avoids copying and potentially slicing the exception.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CatchByReference extends AbstractIndexAstChecker {
|
public class CatchByReference extends AbstractIndexAstChecker {
|
||||||
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.CatchByReference";
|
public static final String ER_ID = "org.eclipse.cdt.codan.internal.checkers.CatchByReference"; //$NON-NLS-1$
|
||||||
|
|
||||||
public void processAst(IASTTranslationUnit ast) {
|
public void processAst(IASTTranslationUnit ast) {
|
||||||
// traverse the ast using the visitor pattern.
|
// traverse the ast using the visitor pattern.
|
||||||
ast.accept(new OnCatch());
|
ast.accept(new OnCatch());
|
||||||
}
|
}
|
||||||
|
|
||||||
class OnCatch extends ASTVisitor {
|
class OnCatch extends ASTVisitor {
|
||||||
OnCatch() {
|
OnCatch() {
|
||||||
shouldVisitStatements = true;
|
shouldVisitStatements = true;
|
||||||
|
@ -51,26 +55,26 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
||||||
if (stmt instanceof ICPPASTTryBlockStatement) {
|
if (stmt instanceof ICPPASTTryBlockStatement) {
|
||||||
try {
|
try {
|
||||||
ICPPASTTryBlockStatement tblock = (ICPPASTTryBlockStatement) stmt;
|
ICPPASTTryBlockStatement tblock = (ICPPASTTryBlockStatement) stmt;
|
||||||
ICPPASTCatchHandler[] catchHandlers = tblock.getCatchHandlers();
|
ICPPASTCatchHandler[] catchHandlers = tblock
|
||||||
next: for (int i = 0; i < catchHandlers.length; i++) {
|
.getCatchHandlers();
|
||||||
|
for (int i = 0; i < catchHandlers.length; i++) {
|
||||||
ICPPASTCatchHandler catchHandler = catchHandlers[i];
|
ICPPASTCatchHandler catchHandler = catchHandlers[i];
|
||||||
IASTDeclaration decl = catchHandler.getDeclaration();
|
IASTDeclaration decl = catchHandler.getDeclaration();
|
||||||
if (decl instanceof IASTSimpleDeclaration) {
|
if (decl instanceof IASTSimpleDeclaration) {
|
||||||
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl;
|
IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl;
|
||||||
IASTDeclSpecifier spec = sdecl.getDeclSpecifier();
|
IASTDeclSpecifier spec = sdecl.getDeclSpecifier();
|
||||||
if (!usesReference(catchHandler)) {
|
if (!usesReference(catchHandler)) {
|
||||||
if (spec instanceof ICPPASTNamedTypeSpecifier) {
|
if (spec instanceof IASTNamedTypeSpecifier) {
|
||||||
IBinding typeName = ((ICPPASTNamedTypeSpecifier) spec).getName().getBinding();
|
IASTName tname = ((IASTNamedTypeSpecifier) spec)
|
||||||
// unwind typedef chain
|
.getName();
|
||||||
while (typeName instanceof ITypedef) {
|
IType typeName = (IType) tname
|
||||||
IType t = ((ITypedef) typeName).getType();
|
.resolveBinding();
|
||||||
if (t instanceof IBasicType)
|
typeName = CxxAstUtils.getInstance()
|
||||||
continue next;
|
.unwindTypedef(typeName);
|
||||||
if (t instanceof IBinding)
|
if (typeName instanceof IBasicType
|
||||||
typeName = (IBinding) t;
|
|| typeName instanceof IPointerType
|
||||||
else
|
|| typeName == null)
|
||||||
break;
|
continue;
|
||||||
}
|
|
||||||
reportProblem(ER_ID, decl);
|
reportProblem(ER_ID, decl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,16 +90,19 @@ public class CatchByReference extends AbstractIndexAstChecker {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If it uses reference or ponter
|
* If it uses reference or ponter
|
||||||
|
*
|
||||||
* @param catchHandler
|
* @param catchHandler
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean usesReference(ICPPASTCatchHandler catchHandler) {
|
private boolean usesReference(ICPPASTCatchHandler catchHandler) {
|
||||||
IASTDeclaration declaration = catchHandler.getDeclaration();
|
IASTDeclaration declaration = catchHandler.getDeclaration();
|
||||||
if (declaration instanceof IASTSimpleDeclaration) {
|
if (declaration instanceof IASTSimpleDeclaration) {
|
||||||
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) declaration).getDeclarators();
|
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) declaration)
|
||||||
|
.getDeclarators();
|
||||||
for (int i = 0; i < declarators.length; i++) {
|
for (int i = 0; i < declarators.length; i++) {
|
||||||
IASTDeclarator d = declarators[i];
|
IASTDeclarator d = declarators[i];
|
||||||
IASTPointerOperator[] pointerOperators = d.getPointerOperators();
|
IASTPointerOperator[] pointerOperators = d
|
||||||
|
.getPointerOperators();
|
||||||
for (int j = 0; j < pointerOperators.length; j++) {
|
for (int j = 0; j < pointerOperators.length; j++) {
|
||||||
IASTPointerOperator po = pointerOperators[j];
|
IASTPointerOperator po = pointerOperators[j];
|
||||||
if (po instanceof ICPPASTReferenceOperator) {
|
if (po instanceof ICPPASTReferenceOperator) {
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009,2010 Alena Laskavaia
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Alena Laskavaia - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.codan.core.cxx;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Useful functions for doing code analysis on c/c++ AST
|
||||||
|
*/
|
||||||
|
public final class CxxAstUtils {
|
||||||
|
private static CxxAstUtils instance;
|
||||||
|
private CxxAstUtils(){
|
||||||
|
// private constructor
|
||||||
|
}
|
||||||
|
public synchronized static CxxAstUtils getInstance(){
|
||||||
|
if (instance==null) instance = new CxxAstUtils();
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
public IType unwindTypedef(IType type) {
|
||||||
|
if (!(type instanceof IBinding)) return type;
|
||||||
|
IBinding typeName = (IBinding) type;
|
||||||
|
// unwind typedef chain
|
||||||
|
while (typeName instanceof ITypedef) {
|
||||||
|
IType t = ((ITypedef) typeName).getType();
|
||||||
|
if (t instanceof IBinding)
|
||||||
|
typeName = (IBinding) t;
|
||||||
|
else
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
return (IType)typeName;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue