1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

Bug 425002 QObjects cannot be found within namespaces

This changes the Qt PDOM so that QObject's are stored using their fully
qualified name (including leading ::).  IQObject's API has been changed
to return the fully qualified name.  Leading :: is stripped from the
IQObject name so there is no change from the previous implementation for
names that are not inside a namspace.

This includes a new test case to check this fix.

Change-Id: I1786151463e9029cdf1f2c213466adc8c3aa3618
Signed-off-by: Andrew Eidsness <eclipse@jfront.com>
Reviewed-on: https://git.eclipse.org/r/20328
Tested-by: Hudson CI
Reviewed-by: Doug Schaefer <dschaefer@qnx.com>
IP-Clean: Doug Schaefer <dschaefer@qnx.com>
This commit is contained in:
Andrew Eidsness 2014-01-07 07:09:17 -05:00 committed by Doug Schaefer
parent 61bc81d157
commit 0e196ca5f2
8 changed files with 92 additions and 12 deletions

View file

@ -61,6 +61,38 @@ public class ASTUtil {
return cProject.getProject();
}
/**
* Return the fully qualified name of the binding for the given name. Returns null
* if the name has no binding. Tries to resolve the binding if needed.
*/
public static String getFullyQualifiedName(IASTName name) {
return getFullyQualifiedName(name.resolveBinding());
}
/**
* Return the fully qualified name of the given binding. Returns null if there
* is no binding.
*/
public static String getFullyQualifiedName(IBinding binding) {
if (binding == null)
return null;
String ownerName = getFullyQualifiedName(binding.getOwner());
return (ownerName == null ? "" : ownerName) + "::" + binding.getName();
}
/**
* Create and return a string representation of the fully qualified name in the
* input array's elements.
*/
public static String getFullyQualifiedName(String[] qualName) {
String fullyQualifiedName = "";
for(int i = 0; i < qualName.length; ++i) {
fullyQualifiedName += "::" + qualName[i];
}
return fullyQualifiedName;
}
// NOTE: This expression allows embedded line terminators (?s) for cases where the code looks like:
// QObject::connect( &a, SIGNAL(
// sig1(

View file

@ -160,7 +160,7 @@ public class QtMethodReference extends ASTNameReference {
}
@Override
public char[] toCharArray() {
public char[] getSimpleID() {
return expansionParam.toCharArray();
}

View file

@ -11,6 +11,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.internal.qt.core.pdom.QtPDOMProperty;
@ -35,8 +36,15 @@ public class QObject implements IQObject {
private final List<IQEnum> enums;
private final Map<String, String> classInfos;
/**
* QObjects are stored in the QtLinkage using their fully qualified name. The API
* for IQObject does not expect the leading ::, so they are stripped when the
* object is read from the PDOM.
*/
private static Pattern StripLeadingQual_Regex = Pattern.compile("^::(.*)$");
public QObject(QtIndexImpl qtIndex, CDTIndex cdtIndex, QtPDOMQObject pdomQObject) throws CoreException {
this.name = pdomQObject.getName();
this.name = StripLeadingQual_Regex.matcher(pdomQObject.getName()).replaceAll("$1");
this.pdomQObject = pdomQObject;
List<IQMethod> baseSlots = new ArrayList<IQMethod>();

View file

@ -12,6 +12,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.internal.qt.core.ASTUtil;
import org.eclipse.cdt.internal.qt.core.pdom.AbstractQtPDOMClass;
import org.eclipse.cdt.internal.qt.core.pdom.QtPDOMQObject;
import org.eclipse.cdt.qt.core.index.IQGadget;
@ -51,12 +52,11 @@ public class QtIndexImpl extends QtIndex {
private class QObjectImplAccessor implements CDTIndex.Accessor<IQObject> {
private final char[][] name;
private final char[] name;
public QObjectImplAccessor(String[] qualName) {
name = new char[qualName.length][];
for(int i = 0; i < name.length; ++i)
name[i] = qualName[i].toCharArray();
// QObjects are stored in the Qt linkage using their fully qualified name.
name = ASTUtil.getFullyQualifiedName(qualName).toCharArray();
}
@Override

View file

@ -149,18 +149,18 @@ public abstract class ASTDelegatedName implements IASTName {
}
@Override
public char[] toCharArray() {
return delegate.toCharArray();
public char[] getSimpleID() {
return delegate.getSimpleID();
}
@Override
public char[] getSimpleID() {
return toCharArray();
public char[] toCharArray() {
return getSimpleID();
}
@Override
public char[] getLookupKey() {
return toCharArray();
return getSimpleID();
}
@Override

View file

@ -14,6 +14,7 @@ import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.qt.core.ASTUtil;
import org.eclipse.core.runtime.CoreException;
/**
@ -22,11 +23,19 @@ import org.eclipse.core.runtime.CoreException;
*/
public class QObjectName extends AbstractQClassName {
private final char[] fullyQualifiedName;
private final List<QtPropertyName> properties = new ArrayList<QtPropertyName>();
private final Map<String, String> classInfos = new LinkedHashMap<String, String>();
public QObjectName(ICPPASTCompositeTypeSpecifier spec) {
super(spec);
fullyQualifiedName = ASTUtil.getFullyQualifiedName(spec.getName()).toCharArray();
}
@Override
public char[] getSimpleID() {
// The Qt linkage uses the full qualified name when storing QObjects into the index.
return fullyQualifiedName;
}
public List<QtPropertyName> getProperties() {

View file

@ -65,7 +65,7 @@ public interface IQObject extends IQElement {
}
/**
* Returns the name of the class.
* Returns the fully qualified name of the class.
*/
public String getName();

View file

@ -452,6 +452,37 @@ public class QObjectTests extends BaseQtTestCase {
assertFalse(i.hasNext());
}
// #include "junit-QObject.hh"
// namespace N {
// class Q : public QObject
// {
// Q_OBJECT
// Q_SIGNAL void aSignal();
// };
// }
public void testQObjectInNamespace() throws Exception {
loadComment("namespace_qobj.hh");
QtIndex qtIndex = QtIndex.getIndex(fProject);
assertNotNull(qtIndex);
IQObject qobj = qtIndex.findQObject(new String[]{ "N", "Q" });
if (!isIndexOk("N::Q", qobj))
return;
assertNotNull(qobj);
IQObject.IMembers<IQMethod> signals = qobj.getSignals();
assertNotNull(signals);
Collection<IQMethod> locals = signals.locals();
assertNotNull(locals);
Iterator<IQMethod> i = locals.iterator();
assertTrue(i.hasNext());
assert_checkQMethod(i.next(), qobj, "aSignal", IQMethod.Kind.Signal, null);
assertFalse(i.hasNext());
}
private static void assert_checkQMethod(IQMethod method, IQObject expectedOwner, String expectedName, IQMethod.Kind expectedKind, Long expectedRevision) throws Exception {
assertEquals(expectedKind, method.getKind());
assertEquals(expectedName, method.getName());