mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 23:05:47 +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:
parent
61bc81d157
commit
0e196ca5f2
8 changed files with 92 additions and 12 deletions
|
@ -61,6 +61,38 @@ public class ASTUtil {
|
||||||
return cProject.getProject();
|
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:
|
// NOTE: This expression allows embedded line terminators (?s) for cases where the code looks like:
|
||||||
// QObject::connect( &a, SIGNAL(
|
// QObject::connect( &a, SIGNAL(
|
||||||
// sig1(
|
// sig1(
|
||||||
|
|
|
@ -160,7 +160,7 @@ public class QtMethodReference extends ASTNameReference {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char[] toCharArray() {
|
public char[] getSimpleID() {
|
||||||
return expansionParam.toCharArray();
|
return expansionParam.toCharArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.internal.qt.core.pdom.QtPDOMProperty;
|
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 List<IQEnum> enums;
|
||||||
private final Map<String, String> classInfos;
|
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 {
|
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;
|
this.pdomQObject = pdomQObject;
|
||||||
|
|
||||||
List<IQMethod> baseSlots = new ArrayList<IQMethod>();
|
List<IQMethod> baseSlots = new ArrayList<IQMethod>();
|
||||||
|
|
|
@ -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.IIndex;
|
||||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
import org.eclipse.cdt.core.index.IndexFilter;
|
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.AbstractQtPDOMClass;
|
||||||
import org.eclipse.cdt.internal.qt.core.pdom.QtPDOMQObject;
|
import org.eclipse.cdt.internal.qt.core.pdom.QtPDOMQObject;
|
||||||
import org.eclipse.cdt.qt.core.index.IQGadget;
|
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 class QObjectImplAccessor implements CDTIndex.Accessor<IQObject> {
|
||||||
|
|
||||||
private final char[][] name;
|
private final char[] name;
|
||||||
|
|
||||||
public QObjectImplAccessor(String[] qualName) {
|
public QObjectImplAccessor(String[] qualName) {
|
||||||
name = new char[qualName.length][];
|
// QObjects are stored in the Qt linkage using their fully qualified name.
|
||||||
for(int i = 0; i < name.length; ++i)
|
name = ASTUtil.getFullyQualifiedName(qualName).toCharArray();
|
||||||
name[i] = qualName[i].toCharArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -149,18 +149,18 @@ public abstract class ASTDelegatedName implements IASTName {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char[] toCharArray() {
|
public char[] getSimpleID() {
|
||||||
return delegate.toCharArray();
|
return delegate.getSimpleID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char[] getSimpleID() {
|
public char[] toCharArray() {
|
||||||
return toCharArray();
|
return getSimpleID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public char[] getLookupKey() {
|
public char[] getLookupKey() {
|
||||||
return toCharArray();
|
return getSimpleID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
|
import org.eclipse.cdt.internal.qt.core.ASTUtil;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,11 +23,19 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
*/
|
*/
|
||||||
public class QObjectName extends AbstractQClassName {
|
public class QObjectName extends AbstractQClassName {
|
||||||
|
|
||||||
|
private final char[] fullyQualifiedName;
|
||||||
private final List<QtPropertyName> properties = new ArrayList<QtPropertyName>();
|
private final List<QtPropertyName> properties = new ArrayList<QtPropertyName>();
|
||||||
private final Map<String, String> classInfos = new LinkedHashMap<String, String>();
|
private final Map<String, String> classInfos = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
public QObjectName(ICPPASTCompositeTypeSpecifier spec) {
|
public QObjectName(ICPPASTCompositeTypeSpecifier spec) {
|
||||||
super(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() {
|
public List<QtPropertyName> getProperties() {
|
||||||
|
|
|
@ -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();
|
public String getName();
|
||||||
|
|
||||||
|
|
|
@ -452,6 +452,37 @@ public class QObjectTests extends BaseQtTestCase {
|
||||||
assertFalse(i.hasNext());
|
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 {
|
private static void assert_checkQMethod(IQMethod method, IQObject expectedOwner, String expectedName, IQMethod.Kind expectedKind, Long expectedRevision) throws Exception {
|
||||||
assertEquals(expectedKind, method.getKind());
|
assertEquals(expectedKind, method.getKind());
|
||||||
assertEquals(expectedName, method.getName());
|
assertEquals(expectedName, method.getName());
|
||||||
|
|
Loading…
Add table
Reference in a new issue