1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-10 09:45:39 +02:00

Bug 175646 - applying patch for slow inClass context calculation

This commit is contained in:
Alena Laskavaia 2010-08-05 11:43:04 +00:00
parent e4c1d89d1a
commit 24639ea848

View file

@ -16,6 +16,7 @@ import org.eclipse.cdt.codan.core.cxx.model.AbstractIndexAstChecker;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
@ -32,9 +33,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
public class ProblemBindingChecker extends AbstractIndexAstChecker { public class ProblemBindingChecker extends AbstractIndexAstChecker {
public static String ERR_ID_OverloadProblem = "org.eclipse.cdt.codan.internal.checkers.OverloadProblem"; //$NON-NLS-1$ public static String ERR_ID_OverloadProblem = "org.eclipse.cdt.codan.internal.checkers.OverloadProblem"; //$NON-NLS-1$
public static String ERR_ID_AmbiguousProblem = "org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem"; //$NON-NLS-1$ public static String ERR_ID_AmbiguousProblem = "org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem"; //$NON-NLS-1$
public static String ERR_ID_CircularReferenceProblem = "org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem"; //$NON-NLS-1$ public static String ERR_ID_CircularReferenceProblem = "org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem"; //$NON-NLS-1$
@ -50,14 +52,13 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
public static String ERR_ID_FieldResolutionProblem = "org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem"; //$NON-NLS-1$ public static String ERR_ID_FieldResolutionProblem = "org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem"; //$NON-NLS-1$
public static String ERR_ID_VariableResolutionProblem = "org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem"; //$NON-NLS-1$ public static String ERR_ID_VariableResolutionProblem = "org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem"; //$NON-NLS-1$
public static String ERR_ID_Candidates = "org.eclipse.cdt.codan.internal.checkers.Candidates"; //$NON-NLS-1$ public static String ERR_ID_Candidates = "org.eclipse.cdt.codan.internal.checkers.Candidates"; //$NON-NLS-1$
@Override @Override
public boolean runInEditor() { public boolean runInEditor() {
return true; return true;
} }
public void processAst(IASTTranslationUnit ast) { public void processAst(IASTTranslationUnit ast) {
try { try {
ast.accept(new ASTVisitor() { ast.accept(new ASTVisitor() {
{ {
@ -70,85 +71,97 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
if (binding instanceof IProblemBinding) { if (binding instanceof IProblemBinding) {
IASTNode parentNode = name.getParent(); IASTNode parentNode = name.getParent();
// Don't report multiple problems with qualified names // Don't report multiple problems with qualified names
if(parentNode instanceof ICPPASTQualifiedName) { if (parentNode instanceof ICPPASTQualifiedName) {
if(((ICPPASTQualifiedName)parentNode).resolveBinding() instanceof IProblemBinding) if (((ICPPASTQualifiedName) parentNode)
return PROCESS_CONTINUE; .resolveBinding() instanceof IProblemBinding)
return PROCESS_CONTINUE;
} }
String contextFlagsString = createContextFlagsString(name); String contextFlagsString = createContextFlagsString(name);
IProblemBinding problemBinding = (IProblemBinding) binding; IProblemBinding problemBinding = (IProblemBinding) binding;
int id = problemBinding.getID(); int id = problemBinding.getID();
if (id == IProblemBinding.SEMANTIC_INVALID_OVERLOAD) {
if(id == IProblemBinding.SEMANTIC_INVALID_OVERLOAD) { reportProblem(ERR_ID_OverloadProblem, name,
reportProblem(ERR_ID_OverloadProblem, name, name.getRawSignature(), contextFlagsString); name.getRawSignature(),
contextFlagsString);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if (id == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) {
if(id == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) {
String candidatesString = getCandidatesString(problemBinding); 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; return PROCESS_CONTINUE;
} }
if (id == IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE) {
if(id == IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE) {
String typeString; String typeString;
IASTNode problemNode; IASTNode problemNode;
if(parentNode instanceof IASTFieldReference) { if (parentNode instanceof IASTFieldReference) {
IASTExpression ownerExpression = ((IASTFieldReference)parentNode).getFieldOwner(); IASTExpression ownerExpression = ((IASTFieldReference) parentNode)
typeString = ASTTypeUtil.getType(ownerExpression.getExpressionType()); .getFieldOwner();
typeString = ASTTypeUtil
.getType(ownerExpression
.getExpressionType());
problemNode = ownerExpression; problemNode = ownerExpression;
} else { } else {
problemNode = name; problemNode = name;
typeString = name.getRawSignature(); typeString = name.getRawSignature();
} }
reportProblem(ERR_ID_CircularReferenceProblem, problemNode, typeString, contextFlagsString); reportProblem(ERR_ID_CircularReferenceProblem,
problemNode, typeString,
contextFlagsString);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if (id == IProblemBinding.SEMANTIC_INVALID_REDECLARATION) {
if(id == IProblemBinding.SEMANTIC_INVALID_REDECLARATION) { reportProblem(ERR_ID_RedeclarationProblem,
reportProblem(ERR_ID_RedeclarationProblem, name, name.getRawSignature(), contextFlagsString); name, name.getRawSignature(),
contextFlagsString);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if (id == IProblemBinding.SEMANTIC_INVALID_REDEFINITION) {
if(id == IProblemBinding.SEMANTIC_INVALID_REDEFINITION) { reportProblem(ERR_ID_RedefinitionProblem, name,
reportProblem(ERR_ID_RedefinitionProblem, name, name.getRawSignature(), contextFlagsString); name.getRawSignature(),
contextFlagsString);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if (id == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) {
if(id == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) { reportProblem(
reportProblem(ERR_ID_MemberDeclarationNotFoundProblem, name, contextFlagsString); ERR_ID_MemberDeclarationNotFoundProblem,
name, contextFlagsString);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if (id == IProblemBinding.SEMANTIC_LABEL_STATEMENT_NOT_FOUND) {
if(id == IProblemBinding.SEMANTIC_LABEL_STATEMENT_NOT_FOUND) { reportProblem(
reportProblem(ERR_ID_LabelStatementNotFoundProblem, name, name.getRawSignature(), contextFlagsString); ERR_ID_LabelStatementNotFoundProblem,
name, name.getRawSignature(),
contextFlagsString);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if (id == IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS) {
if(id == IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS) {
// We use the templateName since we don't want the whole // 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. // argument list to be underlined. That way we can see which argument is invalid.
IASTNode templateName = getTemplateName(name); IASTNode templateName = getTemplateName(name);
reportProblem(ERR_ID_InvalidTemplateArgumentsProblem, templateName, contextFlagsString); reportProblem(
ERR_ID_InvalidTemplateArgumentsProblem,
templateName, contextFlagsString);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
// From this point, we'll deal only with NAME_NOT_FOUND problems. // From this point, we'll deal only with NAME_NOT_FOUND problems.
// If it's something else continue because we don't want to give bad messages // If it's something else continue because we don't want to give bad messages
if(id != IProblemBinding.SEMANTIC_NAME_NOT_FOUND) { if (id != IProblemBinding.SEMANTIC_NAME_NOT_FOUND) {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
if (isFunctionCall(parentNode)) {
if(isFunctionCall(parentNode)) { handleFunctionProblem(name, problemBinding,
handleFunctionProblem(name, problemBinding, contextFlagsString); contextFlagsString);
} else if (parentNode instanceof IASTFieldReference) { } else if (parentNode instanceof IASTFieldReference) {
handleMemberProblem(name, parentNode, problemBinding, contextFlagsString); handleMemberProblem(name, parentNode,
problemBinding, contextFlagsString);
} else if (parentNode instanceof IASTNamedTypeSpecifier) { } else if (parentNode instanceof IASTNamedTypeSpecifier) {
reportProblem(ERR_ID_TypeResolutionProblem, name, name.getRawSignature(), contextFlagsString); reportProblem(ERR_ID_TypeResolutionProblem,
} name, name.getRawSignature(),
contextFlagsString);
}
// Probably a variable // Probably a variable
else { else {
handleVariableProblem(name, contextFlagsString); handleVariableProblem(name, contextFlagsString);
@ -157,17 +170,14 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
} catch (DOMException e) { } catch (DOMException e) {
e.printStackTrace(); e.printStackTrace();
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
}); });
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
protected String createContextFlagsString(IASTName name) { protected String createContextFlagsString(IASTName name) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
if (isInClassContext(name)) { if (isInClassContext(name)) {
@ -178,57 +188,77 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
} }
return buf.toString(); return buf.toString();
} }
private boolean isInClassContext(IASTName name) { private boolean isInClassContext(IASTName name) {
CxxAstUtils utils = CxxAstUtils.getInstance(); CxxAstUtils utils = CxxAstUtils.getInstance();
if (utils.getEnclosingCompositeTypeSpecifier(name) != null) { if (utils.getEnclosingCompositeTypeSpecifier(name) != null) {
return true; return true;
} }
return false; IASTFunctionDefinition function = utils.getEnclosingFunction(name);
if (function == null) {
return false;
}
@SuppressWarnings("restriction")
IASTDeclarator innermostDeclarator = ASTQueries
.findInnermostDeclarator(function.getDeclarator());
IBinding binding = innermostDeclarator.getName().resolveBinding();
return (binding instanceof ICPPMethod);
} }
private boolean isInFunctionContext(IASTName name) { private boolean isInFunctionContext(IASTName name) {
CxxAstUtils utils = CxxAstUtils.getInstance(); CxxAstUtils utils = CxxAstUtils.getInstance();
IASTFunctionDefinition function = utils.getEnclosingFunction(name); IASTFunctionDefinition function = utils.getEnclosingFunction(name);
return (function != null); return (function != null);
} }
private void handleFunctionProblem(IASTName name, IProblemBinding problemBinding, String contextFlagsString) private void handleFunctionProblem(IASTName name,
IProblemBinding problemBinding, String contextFlagsString)
throws DOMException { throws DOMException {
if(problemBinding.getCandidateBindings().length == 0) { if (problemBinding.getCandidateBindings().length == 0) {
reportProblem(ERR_ID_FunctionResolutionProblem, name.getLastName(), name.getRawSignature(), contextFlagsString); reportProblem(ERR_ID_FunctionResolutionProblem, name.getLastName(),
name.getRawSignature(), contextFlagsString);
} else { } else {
String candidatesString = getCandidatesString(problemBinding); 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, private void handleMemberProblem(IASTName name, IASTNode parentNode,
IProblemBinding problemBinding, String contextFlagsString) throws DOMException { IProblemBinding problemBinding, String contextFlagsString)
throws DOMException {
IASTNode parentParentNode = parentNode.getParent(); IASTNode parentParentNode = parentNode.getParent();
if(parentParentNode instanceof IASTFunctionCallExpression) { if (parentParentNode instanceof IASTFunctionCallExpression) {
if(problemBinding.getCandidateBindings().length == 0) { if (problemBinding.getCandidateBindings().length == 0) {
reportProblem(ERR_ID_MethodResolutionProblem, name.getLastName(), name.getRawSignature(), contextFlagsString); reportProblem(ERR_ID_MethodResolutionProblem,
name.getLastName(), name.getRawSignature(),
contextFlagsString);
} else { } else {
String candidatesString = getCandidatesString(problemBinding); String candidatesString = getCandidatesString(problemBinding);
reportProblem(ERR_ID_InvalidArguments, name.getLastName(), candidatesString, contextFlagsString); reportProblem(ERR_ID_InvalidArguments, name.getLastName(),
candidatesString, contextFlagsString);
} }
} else { } 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) { 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) { private boolean isFunctionCall(IASTNode parentNode) {
if(parentNode instanceof IASTIdExpression) { if (parentNode instanceof IASTIdExpression) {
IASTIdExpression expression = (IASTIdExpression)parentNode; IASTIdExpression expression = (IASTIdExpression) parentNode;
IASTNode parentParentNode = expression.getParent(); IASTNode parentParentNode = expression.getParent();
if(parentParentNode instanceof IASTFunctionCallExpression && if (parentParentNode instanceof IASTFunctionCallExpression
expression.getPropertyInParent().getName().equals(IASTFunctionCallExpression.FUNCTION_NAME.getName())) { && expression
.getPropertyInParent()
.getName()
.equals(IASTFunctionCallExpression.FUNCTION_NAME
.getName())) {
return true; return true;
} }
} }
@ -237,10 +267,9 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
protected IASTNode getTemplateName(IASTName name) { protected IASTNode getTemplateName(IASTName name) {
IASTName nameToGetTempate = name.getLastName(); IASTName nameToGetTempate = name.getLastName();
if(nameToGetTempate instanceof ICPPASTTemplateId) { if (nameToGetTempate instanceof ICPPASTTemplateId) {
return ((ICPPASTTemplateId)nameToGetTempate).getTemplateName(); return ((ICPPASTTemplateId) nameToGetTempate).getTemplateName();
} }
return nameToGetTempate; return nameToGetTempate;
} }
@ -251,45 +280,48 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
* @return A string of the candidates, one per line * @return A string of the candidates, one per line
* @throws DOMException * @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 candidatesString = "\n" + CheckersMessages.ProblemBindingChecker_Candidates + "\n"; //$NON-NLS-1$ //$NON-NLS-2$
String lastSignature = ""; //$NON-NLS-1$ String lastSignature = ""; //$NON-NLS-1$
for(IBinding candidateBinding : problemBinding.getCandidateBindings()) { for (IBinding candidateBinding : problemBinding.getCandidateBindings()) {
if(candidateBinding instanceof ICPPFunction) { if (candidateBinding instanceof ICPPFunction) {
ICPPFunction functionBinding = (ICPPFunction)candidateBinding; ICPPFunction functionBinding = (ICPPFunction) candidateBinding;
String signature = getFunctionSignature(functionBinding); String signature = getFunctionSignature(functionBinding);
if(!signature.equals(lastSignature)) { if (!signature.equals(lastSignature)) {
candidatesString += signature + "\n"; //$NON-NLS-1$ candidatesString += signature + "\n"; //$NON-NLS-1$
lastSignature = signature; lastSignature = signature;
} }
} else if(candidateBinding instanceof ICPPClassType) { } else if (candidateBinding instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType)candidateBinding; ICPPClassType classType = (ICPPClassType) candidateBinding;
for(ICPPFunction constructor : classType.getConstructors()) { for (ICPPFunction constructor : classType.getConstructors()) {
String signature = getFunctionSignature(constructor); String signature = getFunctionSignature(constructor);
if(!signature.equals(lastSignature)) { if (!signature.equals(lastSignature)) {
candidatesString += signature + "\n"; //$NON-NLS-1$ candidatesString += signature + "\n"; //$NON-NLS-1$
lastSignature = signature; lastSignature = signature;
} }
} }
} }
}
}
return candidatesString; return candidatesString;
} }
/** /**
* Returns a string of the function signature : returntype + function + parameters * Returns a string of the function signature : returntype + function +
* parameters
* *
* @param functionBinding The function to get the signature * @param functionBinding The function to get the signature
* @return A string of the function signature * @return A string of the function signature
* @throws DOMException * @throws DOMException
*/ */
private String getFunctionSignature(ICPPFunction functionBinding) throws DOMException { private String getFunctionSignature(ICPPFunction functionBinding)
throws DOMException {
IFunctionType functionType = functionBinding.getType(); 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 functionName = functionBinding.getName();
String parameterTypeString = ASTTypeUtil.getParameterTypeString(functionType); String parameterTypeString = ASTTypeUtil
.getParameterTypeString(functionType);
return returnTypeString + functionName + parameterTypeString; return returnTypeString + functionName + parameterTypeString;
} }
} }