mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-07 00:05:53 +02:00
Bug 278337.
This commit is contained in:
parent
aecdc9e38c
commit
75560d52b8
9 changed files with 240 additions and 141 deletions
|
@ -48,6 +48,17 @@ public interface IProblemBinding extends IBinding, IScope, IType {
|
||||||
*/
|
*/
|
||||||
public int getLineNumber();
|
public int getLineNumber();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns bindings that were considered when resolving the node corresponding
|
||||||
|
* to this problem binding, but rejected for some reason.
|
||||||
|
* @return an array of candidate bindings.
|
||||||
|
*
|
||||||
|
* This method is experimental. Clients calling this method should expect
|
||||||
|
* possible changes.
|
||||||
|
* @since 5.1 experimental
|
||||||
|
*/
|
||||||
|
public IBinding[] getCandidateBindings();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parser Semantic Problems
|
* Parser Semantic Problems
|
||||||
* All Semantic problems take a char[] as an argument
|
* All Semantic problems take a char[] as an argument
|
||||||
|
|
|
@ -40,16 +40,26 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
||||||
protected final int id;
|
protected final int id;
|
||||||
protected char[] arg;
|
protected char[] arg;
|
||||||
protected IASTNode node;
|
protected IASTNode node;
|
||||||
private String message = null;
|
private final String message = null;
|
||||||
|
private final IBinding[] candidateBindings;
|
||||||
|
|
||||||
public ProblemBinding(IASTName name, int id) {
|
public ProblemBinding(IASTName name, int id) {
|
||||||
this(name, id, null);
|
this(name, id, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProblemBinding(IASTName name, int id, IBinding[] candidateBindings) {
|
||||||
|
this(name, id, null, candidateBindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProblemBinding(IASTNode node, int id, char[] arg) {
|
public ProblemBinding(IASTNode node, int id, char[] arg) {
|
||||||
|
this(node, id, arg, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProblemBinding(IASTNode node, int id, char[] arg, IBinding[] candidateBindings) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.arg = arg;
|
this.arg = arg;
|
||||||
this.node = node;
|
this.node = node;
|
||||||
|
this.candidateBindings = candidateBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EScopeKind getKind() {
|
public EScopeKind getKind() {
|
||||||
|
@ -60,6 +70,10 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IBinding[] getCandidateBindings() {
|
||||||
|
return candidateBindings != null ? candidateBindings : IBinding.EMPTY_BINDING_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
protected static final String[] errorMessages;
|
protected static final String[] errorMessages;
|
||||||
static {
|
static {
|
||||||
errorMessages = new String[IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS];
|
errorMessages = new String[IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS];
|
||||||
|
@ -134,6 +148,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
|
||||||
return getASTNode();
|
return getASTNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
// Don't clone problems
|
// Don't clone problems
|
||||||
|
|
|
@ -839,7 +839,8 @@ public class CVisitor extends ASTQueries {
|
||||||
try {
|
try {
|
||||||
IBinding binding = lookup(scope, ((IASTIdExpression) node).getName());
|
IBinding binding = lookup(scope, ((IASTIdExpression) node).getName());
|
||||||
if (binding instanceof IType && !(binding instanceof IProblemBinding) ) {
|
if (binding instanceof IType && !(binding instanceof IProblemBinding) ) {
|
||||||
return new ProblemBinding(node, IProblemBinding.SEMANTIC_INVALID_TYPE, binding.getNameCharArray());
|
return new ProblemBinding(node, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
|
binding.getNameCharArray(), new IBinding[] { binding });
|
||||||
}
|
}
|
||||||
return binding;
|
return binding;
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
|
@ -854,7 +855,8 @@ public class CVisitor extends ASTQueries {
|
||||||
return new ProblemBinding(node, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray());
|
return new ProblemBinding(node, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, name.toCharArray());
|
||||||
if (binding instanceof IType)
|
if (binding instanceof IType)
|
||||||
return binding;
|
return binding;
|
||||||
return new ProblemBinding(node, IProblemBinding.SEMANTIC_INVALID_TYPE, binding.getNameCharArray());
|
return new ProblemBinding(node, IProblemBinding.SEMANTIC_INVALID_TYPE, binding.getNameCharArray(),
|
||||||
|
new IBinding[] { binding });
|
||||||
} catch (DOMException e) {
|
} catch (DOMException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -885,10 +887,12 @@ public class CVisitor extends ASTQueries {
|
||||||
}
|
}
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
IBinding binding = name.resolveBinding();
|
IBinding binding = name.resolveBinding();
|
||||||
if (binding instanceof IType)
|
if (binding instanceof IType) {
|
||||||
return binding;
|
return binding;
|
||||||
else if (binding != null)
|
} else if (binding != null) {
|
||||||
return new ProblemBinding(node, IProblemBinding.SEMANTIC_INVALID_TYPE, binding.getNameCharArray());
|
return new ProblemBinding(node, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
|
binding.getNameCharArray(), new IBinding[] { binding });
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else if (node instanceof ICASTFieldDesignator) {
|
} else if (node instanceof ICASTFieldDesignator) {
|
||||||
|
|
|
@ -201,7 +201,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
if (owner instanceof ICPPClassType) {
|
if (owner instanceof ICPPClassType) {
|
||||||
return (ICPPClassType) owner;
|
return (ICPPClassType) owner;
|
||||||
}
|
}
|
||||||
return new ProblemBinding(this, IProblemBinding.SEMANTIC_BAD_SCOPE, binding.getName().toCharArray());
|
return new ProblemBinding(this, IProblemBinding.SEMANTIC_BAD_SCOPE,
|
||||||
|
binding.getName().toCharArray());
|
||||||
} else if (binding instanceof IFunction) {
|
} else if (binding instanceof IFunction) {
|
||||||
t = ((IFunction) binding).getType();
|
t = ((IFunction) binding).getType();
|
||||||
} else if (binding instanceof IVariable) {
|
} else if (binding instanceof IVariable) {
|
||||||
|
|
|
@ -329,7 +329,8 @@ public class CPPSemantics {
|
||||||
node= node.getParent();
|
node= node.getParent();
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE);
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -414,11 +415,13 @@ public class CPPSemantics {
|
||||||
if (parent instanceof IASTTypeId && parent.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) {
|
if (parent instanceof IASTTypeId && parent.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) {
|
||||||
if (!(binding instanceof IType)) {
|
if (!(binding instanceof IType)) {
|
||||||
// a type id needs to hold a type
|
// a type id needs to hold a type
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE);
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
// don't create a problem here
|
// don't create a problem here
|
||||||
} else {
|
} else {
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE);
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (namePropertyInParent == IASTIdExpression.ID_NAME) {
|
} else if (namePropertyInParent == IASTIdExpression.ID_NAME) {
|
||||||
|
@ -430,7 +433,8 @@ public class CPPSemantics {
|
||||||
(binding instanceof ICPPUnknownType || binding instanceof ITypedef || binding instanceof IEnumeration)) {
|
(binding instanceof ICPPUnknownType || binding instanceof ITypedef || binding instanceof IEnumeration)) {
|
||||||
// constructor or simple-type constructor
|
// constructor or simple-type constructor
|
||||||
} else {
|
} else {
|
||||||
binding= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE);
|
binding= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,10 +453,13 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
// If we're still null...
|
// If we're still null...
|
||||||
if (binding == null) {
|
if (binding == null) {
|
||||||
if (name instanceof ICPPASTQualifiedName && data.forFunctionDeclaration())
|
if (name instanceof ICPPASTQualifiedName && data.forFunctionDeclaration()) {
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND);
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND,
|
||||||
else
|
data.getFoundBindings());
|
||||||
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
|
} else {
|
||||||
|
binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND,
|
||||||
|
data.getFoundBindings());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
@ -1060,7 +1067,8 @@ public class CPPSemantics {
|
||||||
Object temp = lookupInParents(data, classScope, overallScope, fileSet);
|
Object temp = lookupInParents(data, classScope, overallScope, fileSet);
|
||||||
if (!isEmpty) {
|
if (!isEmpty) {
|
||||||
inherited = mergePrefixResults(null, inCurrentScope, true);
|
inherited = mergePrefixResults(null, inCurrentScope, true);
|
||||||
inherited = mergePrefixResults((CharArrayObjectMap)inherited, (CharArrayObjectMap)temp, true);
|
inherited = mergePrefixResults((CharArrayObjectMap) inherited,
|
||||||
|
(CharArrayObjectMap) temp, true);
|
||||||
} else {
|
} else {
|
||||||
inherited= temp;
|
inherited= temp;
|
||||||
}
|
}
|
||||||
|
@ -1071,7 +1079,8 @@ public class CPPSemantics {
|
||||||
visitVirtualBaseClasses(data, cls);
|
visitVirtualBaseClasses(data, cls);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, cls.getNameCharArray());
|
data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE,
|
||||||
|
cls.getNameCharArray(), data.getFoundBindings());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1085,14 +1094,14 @@ public class CPPSemantics {
|
||||||
for (int j = 0; j < r.length && r[j] != null; j++) {
|
for (int j = 0; j < r.length && r[j] != null; j++) {
|
||||||
if (checkForAmbiguity(data, r[j], inherited)) {
|
if (checkForAmbiguity(data, r[j], inherited)) {
|
||||||
data.problem = new ProblemBinding(data.astName,
|
data.problem = new ProblemBinding(data.astName,
|
||||||
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (checkForAmbiguity(data, result, inherited)) {
|
if (checkForAmbiguity(data, result, inherited)) {
|
||||||
data.problem = new ProblemBinding(data.astName,
|
data.problem = new ProblemBinding(data.astName,
|
||||||
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1852,7 +1861,8 @@ public class CPPSemantics {
|
||||||
type= temp;
|
type= temp;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1866,7 +1876,8 @@ public class CPPSemantics {
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
obj= temp;
|
obj= temp;
|
||||||
} else if (c == 0) {
|
} else if (c == 0) {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1874,7 +1885,10 @@ public class CPPSemantics {
|
||||||
if (data.forUsingDeclaration()) {
|
if (data.forUsingDeclaration()) {
|
||||||
IBinding[] bindings = null;
|
IBinding[] bindings = null;
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
if (fns.size() > 0) return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
if (fns.size() > 0) {
|
||||||
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||||
|
data.getFoundBindings());
|
||||||
|
}
|
||||||
// if (type == null) return obj;
|
// if (type == null) return obj;
|
||||||
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, obj);
|
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, obj);
|
||||||
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
|
bindings = (IBinding[]) ArrayUtil.append(IBinding.class, bindings, type);
|
||||||
|
@ -1898,8 +1912,10 @@ public class CPPSemantics {
|
||||||
|
|
||||||
int numFns = fns.size();
|
int numFns = fns.size();
|
||||||
if (numFns > 0) {
|
if (numFns > 0) {
|
||||||
if (obj != null)
|
if (obj != null) {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||||
|
data.getFoundBindings());
|
||||||
|
}
|
||||||
return resolveFunction(data, fns.keyArray(IFunction.class), true);
|
return resolveFunction(data, fns.keyArray(IFunction.class), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2169,13 +2185,15 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (ambiguous || bestFnCost.hasAmbiguousUserDefinedConversion()) {
|
if (ambiguous || bestFnCost.hasAmbiguousUserDefinedConversion()) {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestFnCost.getFunction();
|
return bestFnCost.getFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FunctionCost costForFunctionCall(IFunction fn, IType[] argTypes, IASTExpression[] args, boolean allowUDC, LookupData data) throws DOMException {
|
private static FunctionCost costForFunctionCall(IFunction fn, IType[] argTypes, IASTExpression[] args,
|
||||||
|
boolean allowUDC, LookupData data) throws DOMException {
|
||||||
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
|
final ICPPFunctionType ftype= (ICPPFunctionType) fn.getType();
|
||||||
if (ftype == null)
|
if (ftype == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -2270,7 +2288,7 @@ public class CPPSemantics {
|
||||||
ICPPASTConversionName astName= (ICPPASTConversionName) data.astName;
|
ICPPASTConversionName astName= (ICPPASTConversionName) data.astName;
|
||||||
IType t= CPPVisitor.createType(astName.getTypeId());
|
IType t= CPPVisitor.createType(astName.getTypeId());
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_INVALID_TYPE);
|
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings());
|
||||||
}
|
}
|
||||||
if (!data.forFunctionDeclaration() || data.forExplicitFunctionSpecialization()) {
|
if (!data.forFunctionDeclaration() || data.forExplicitFunctionSpecialization()) {
|
||||||
CPPTemplates.instantiateConversionTemplates(fns, t);
|
CPPTemplates.instantiateConversionTemplates(fns, t);
|
||||||
|
@ -2293,7 +2311,7 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
if (unknown != null)
|
if (unknown != null)
|
||||||
return unknown;
|
return unknown;
|
||||||
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
|
return new ProblemBinding(astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.getFoundBindings());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2337,8 +2355,10 @@ public class CPPSemantics {
|
||||||
|
|
||||||
while (type != null) {
|
while (type != null) {
|
||||||
type = getUltimateType(type, false);
|
type = getUltimateType(type, false);
|
||||||
if (type == null || !(type instanceof IFunctionType))
|
if (type == null || !(type instanceof IFunctionType)) {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||||
|
data.getFoundBindings());
|
||||||
|
}
|
||||||
|
|
||||||
for (IBinding fn2 : fns) {
|
for (IBinding fn2 : fns) {
|
||||||
IFunction fn = (IFunction) fn2;
|
IFunction fn = (IFunction) fn2;
|
||||||
|
@ -2356,13 +2376,9 @@ public class CPPSemantics {
|
||||||
if (c < 0) {
|
if (c < 0) {
|
||||||
result= fn;
|
result= fn;
|
||||||
} else if (c == 0) {
|
} else if (c == 0) {
|
||||||
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP,
|
||||||
|
data.getFoundBindings());
|
||||||
}
|
}
|
||||||
// boolean fromIndex= isFromIndex(fn);
|
|
||||||
// if (isFromIndex(result) == fromIndex)
|
|
||||||
// return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
|
||||||
// if (!fromIndex)
|
|
||||||
// result= fn;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2374,7 +2390,8 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result != null ? result : new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
|
return result != null ? result :
|
||||||
|
new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object getTargetType(LookupData data) {
|
private static Object getTargetType(LookupData data) {
|
||||||
|
|
|
@ -631,8 +631,8 @@ public class CPPVisitor extends ASTQueries {
|
||||||
ASTInternal.addDeclaration(binding, name);
|
ASTInternal.addDeclaration(binding, name);
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
} catch (DOMException e1) {
|
} catch (DOMException e) {
|
||||||
return e1.getProblem();
|
return e.getProblem();
|
||||||
}
|
}
|
||||||
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
|
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,30 +18,7 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.*;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||||
|
@ -66,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||||
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||||
|
@ -641,4 +619,23 @@ public class LookupData {
|
||||||
public boolean hasArgumentTypes() {
|
public boolean hasArgumentTypes() {
|
||||||
return functionArgTypes != null || functionArgs != null;
|
return functionArgTypes != null || functionArgs != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IBinding[] getFoundBindings() {
|
||||||
|
if (foundItems instanceof Object[]) {
|
||||||
|
Object[] items = (Object[]) foundItems;
|
||||||
|
if (items.length != 0) {
|
||||||
|
IBinding[] bindings = new IBinding[items.length];
|
||||||
|
int k = 0;
|
||||||
|
for (Object item : items) {
|
||||||
|
if (item instanceof IBinding) {
|
||||||
|
bindings[k++] = (IBinding) item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (k != 0) {
|
||||||
|
return ArrayUtil.trimAt(IBinding.class, bindings, k - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return IBinding.EMPTY_BINDING_ARRAY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,11 @@ import org.eclipse.cdt.internal.ui.editor.ASTProvider;
|
||||||
import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction;
|
import org.eclipse.cdt.internal.ui.search.actions.OpenDeclarationsAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It is required to test the selection performance independent of the indexer to make sure that the DOM is functioning properly.
|
* It is required to test the selection performance independent of the indexer to make sure that the DOM
|
||||||
|
* is functioning properly.
|
||||||
*
|
*
|
||||||
* Indexer bugs can drastically influence the correctness of these tests so the indexer has to be off when performing them.
|
* Indexer bugs can drastically influence the correctness of these tests so the indexer has to be off when
|
||||||
|
* performing them.
|
||||||
*
|
*
|
||||||
* @author dsteffle
|
* @author dsteffle
|
||||||
*/
|
*/
|
||||||
|
@ -281,6 +283,10 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertContents(String code, int offset, String expected) {
|
||||||
|
assertEquals(expected, code.substring(offset, offset + expected.length()));
|
||||||
|
}
|
||||||
|
|
||||||
public void testBug93281() throws Exception {
|
public void testBug93281() throws Exception {
|
||||||
StringBuffer buffer = new StringBuffer();
|
StringBuffer buffer = new StringBuffer();
|
||||||
buffer.append("class Point{ \n"); //$NON-NLS-1$
|
buffer.append("class Point{ \n"); //$NON-NLS-1$
|
||||||
|
@ -1048,4 +1054,41 @@ public class CPPSelectionTestsNoIndexer extends BaseUITestCase {
|
||||||
assertEquals("myFunc", name.toString());
|
assertEquals("myFunc", name.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// struct A {
|
||||||
|
// void method(int p) {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// void test(A* a) {
|
||||||
|
// a->method();
|
||||||
|
// a.method(0);
|
||||||
|
// }
|
||||||
|
// void A::method(int a, int b) {}
|
||||||
|
// void B::method(int b) {}
|
||||||
|
public void testUnresolvedMethod_278337() throws Exception {
|
||||||
|
String code= getContentsForTest(1)[0].toString();
|
||||||
|
IFile file = importFile("testBug278337.cpp", code);
|
||||||
|
IASTNode node= testF3(file, code.indexOf("method();"));
|
||||||
|
assertContents(code, node.getFileLocation().getNodeOffset(), "method(int p)");
|
||||||
|
node= testF3(file, code.indexOf("method(0);"));
|
||||||
|
assertNull(node);
|
||||||
|
node= testF3(file, code.indexOf("method(int a, int b)"));
|
||||||
|
assertContents(code, node.getFileLocation().getNodeOffset(), "method(int p)");
|
||||||
|
node= testF3(file, code.indexOf("method(int b)"));
|
||||||
|
// Should not navigate away since there is no good candidate.
|
||||||
|
assertContents(code, node.getFileLocation().getNodeOffset(), "method(int b)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// class A {
|
||||||
|
// class B {};
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// B b;
|
||||||
|
public void testUnresolvedType() throws Exception {
|
||||||
|
String code= getContentsForTest(1)[0].toString();
|
||||||
|
IFile file = importFile("testUndefinedType.cpp", code);
|
||||||
|
int offset= code.indexOf("B b;");
|
||||||
|
IASTNode node= testF3(file, offset);
|
||||||
|
assertNull(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,9 @@ import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
|
||||||
import org.eclipse.cdt.internal.ui.text.CWordFinder;
|
import org.eclipse.cdt.internal.ui.text.CWordFinder;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
|
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to the definition of a name, or to the declaration if invoked on the definition.
|
||||||
|
*/
|
||||||
public class OpenDeclarationsAction extends SelectionParseAction implements ASTRunnable {
|
public class OpenDeclarationsAction extends SelectionParseAction implements ASTRunnable {
|
||||||
public static boolean sIsJUnitTest = false;
|
public static boolean sIsJUnitTest = false;
|
||||||
|
|
||||||
|
@ -185,15 +188,22 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
|
||||||
openInclude(((IASTPreprocessorIncludeStatement) parent));
|
openInclude(((IASTPreprocessorIncludeStatement) parent));
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
IBinding binding = sourceName.resolveBinding();
|
|
||||||
NameKind kind = getNameKind(sourceName);
|
NameKind kind = getNameKind(sourceName);
|
||||||
if (binding != null && !(binding instanceof IProblemBinding)) {
|
IBinding b = sourceName.resolveBinding();
|
||||||
if (kind == NameKind.DEFINITION && binding instanceof IType) {
|
IBinding[] bindings = new IBinding[] { b };
|
||||||
|
if (b instanceof IProblemBinding) {
|
||||||
|
IBinding[] candidateBindings = ((IProblemBinding) b).getCandidateBindings();
|
||||||
|
if (candidateBindings.length != 0) {
|
||||||
|
bindings = candidateBindings;
|
||||||
|
}
|
||||||
|
} else if (kind == NameKind.DEFINITION && b instanceof IType) {
|
||||||
// Don't navigate away from a type definition.
|
// Don't navigate away from a type definition.
|
||||||
// Select the name at the current location instead.
|
// Select the name at the current location instead.
|
||||||
navigateToName(sourceName);
|
navigateToName(sourceName);
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
|
for (IBinding binding : bindings) {
|
||||||
|
if (binding != null && !(binding instanceof IProblemBinding)) {
|
||||||
IName[] declNames = findDeclNames(ast, kind, binding);
|
IName[] declNames = findDeclNames(ast, kind, binding);
|
||||||
// Exclude the current location.
|
// Exclude the current location.
|
||||||
for (int i = 0; i < declNames.length; i++) {
|
for (int i = 0; i < declNames.length; i++) {
|
||||||
|
@ -219,6 +229,7 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
|
||||||
found = navigateOneLocation(declNames);
|
found = navigateOneLocation(declNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!found && !navigationFallBack(ast, sourceName, kind)) {
|
if (!found && !navigationFallBack(ast, sourceName, kind)) {
|
||||||
reportSymbolLookupFailure(new String(sourceName.toCharArray()));
|
reportSymbolLookupFailure(new String(sourceName.toCharArray()));
|
||||||
}
|
}
|
||||||
|
@ -372,10 +383,10 @@ public class OpenDeclarationsAction extends SelectionParseAction implements ASTR
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
IName[] names = findNames(fIndex, ast, kind, binding);
|
IName[] names = findNames(fIndex, ast, kind, binding);
|
||||||
// Exclude the current location.
|
// Exclude names of the same kind.
|
||||||
for (int i = 0; i < names.length; i++) {
|
for (int i = 0; i < names.length; i++) {
|
||||||
if (getNameKind(names[i]) == kind) {
|
if (getNameKind(names[i]) == kind) {
|
||||||
names[i] = null; // Don' navigate to a name of the same kind.
|
names[i] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
names = (IName[]) ArrayUtil.removeNulls(IName.class, names);
|
names = (IName[]) ArrayUtil.removeNulls(IName.class, names);
|
||||||
|
|
Loading…
Add table
Reference in a new issue