diff --git a/core/org.eclipse.cdt.core.tests/build.properties b/core/org.eclipse.cdt.core.tests/build.properties index 66aa1631b59..e8b64d477d9 100644 --- a/core/org.eclipse.cdt.core.tests/build.properties +++ b/core/org.eclipse.cdt.core.tests/build.properties @@ -13,7 +13,8 @@ bin.includes = plugin.xml,\ cdtcoretests.jar,\ test.xml,\ resources/,\ - META-INF/ + META-INF/,\ + parser/org/eclipse/cdt/internal/index/tests/ output.cdtcoretests.jar = bin/ source.cdtcoretests.jar = failures/,\ diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java new file mode 100644 index 00000000000..e14c50d695f --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2006 Wind River Systems, Inc. and others. + * 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: + * Markus Schorn - initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.index.tests; + +import java.io.IOException; +import java.util.regex.Pattern; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IName; +import org.eclipse.cdt.core.dom.IPDOMIndexer; +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +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.IIndexFile; +import org.eclipse.cdt.core.index.IIndexName; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.CTestPlugin; +import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.cdt.core.testplugin.util.TestSourceReader; +import org.eclipse.cdt.internal.core.CCoreInternals; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; + +public class IndexBugsTests extends BaseTestCase { + private static final IProgressMonitor NPM = new NullProgressMonitor(); + private ICProject fCProject; + protected IIndex fIndex; + + public IndexBugsTests(String name) { + super(name); + } + + public static TestSuite suite() { + return suite(IndexBugsTests.class); + } + + protected void setUp() throws CoreException { + fCProject= CProjectHelper.createCCProject("__bugsTest__", "bin", IPDOMManager.ID_FAST_INDEXER); + IPDOMIndexer indexer = CCoreInternals.getPDOMManager().getIndexer(fCProject); + indexer.reindex(); + fIndex= CCorePlugin.getIndexManager().getIndex(fCProject); + } + + protected void tearDown() throws CoreException { + if (fCProject != null) { + CProjectHelper.delete(fCProject); + } + } + + protected IProject getProject() { + return fCProject.getProject(); + } + + protected String readTaggedComment(final String tag) throws IOException { + return TestSourceReader.readTaggedComment(CTestPlugin.getDefault().getBundle(), "parser", getClass(), tag); + } + + protected IFile createFile(IContainer container, String fileName, String contents, int waitMillis) throws Exception { + long now= System.currentTimeMillis(); + IFile result= TestSourceReader.createFile(container, new Path(fileName), contents); + if (waitMillis >= 0) { + long endTime= now + waitMillis; + int timeLeft= (int) (endTime-now); + while (timeLeft >= 0) { + assertTrue(CCorePlugin.getIndexManager().joinIndexer(timeLeft, NPM)); + fIndex.acquireReadLock(); + try { + IIndexFile pfile= fIndex.getFile(result.getLocation()); + if (pfile != null && pfile.getTimestamp() >= now) { + return result; + } + } + finally { + fIndex.releaseReadLock(); + } + Thread.sleep(50); + timeLeft= (int) (endTime - System.currentTimeMillis()); + } + throw new Exception("Indexer did not complete in time!"); + } + return result; + } + + protected Pattern[] getPattern(String qname) { + String[] parts= qname.split("::"); + Pattern[] result= new Pattern[parts.length]; + for (int i = 0; i < result.length; i++) { + result[i]= Pattern.compile(parts[i]); + } + return result; + } + + // {bug162011} + // namespace ns162011 { + // class Class162011 { + // friend void function162011(Class162011); + // }; + // void function162011(Class162011 x){}; + // } + public void testBug162011() throws Exception { + String content = readTaggedComment("bug162011"); + String fileName = "bug162011.cpp"; + String funcName = "function162011"; + String nsName = "ns162011"; + + int indexOfDecl = content.indexOf(funcName); + int indexOfDef = content.indexOf(funcName, indexOfDecl+1); + createFile(getProject(), fileName, content, 1000); + + // make sure the ast is correct + ITranslationUnit tu= (ITranslationUnit) fCProject.findElement(new Path(fileName)); + IASTTranslationUnit ast= tu.getAST(); + IASTName name= (IASTName) ast.selectNodeForLocation(tu.getLocation().toOSString(), indexOfDecl, funcName.length()); + IBinding astBinding= name.resolveBinding(); + + IName[] astDecls= ast.getDeclarations(astBinding); + assertEquals(2, astDecls.length); + int i1= astDecls[0].getFileLocation().getNodeOffset(); + int i2= astDecls[1].getFileLocation().getNodeOffset(); + assertEquals(indexOfDecl, Math.min(i1, i2)); + assertEquals(indexOfDef, Math.max(i1, i2)); + + fIndex.acquireReadLock(); + try { + IIndexBinding[] bindings= fIndex.findBindings(getPattern("ns162011::function162011"), true, IndexFilter.ALL, NPM); + assertEquals(1, bindings.length); + + IIndexBinding binding= bindings[0]; + + // check if we have the declaration + IIndexName[] decls= fIndex.findNames(binding, IIndex.FIND_DECLARATIONS); + assertEquals(1, decls.length); + assertEquals(indexOfDecl, decls[0].getNodeOffset()); + + // check if we have the definition + decls= fIndex.findNames(binding, IIndex.FIND_DEFINITIONS); + assertEquals(1, decls.length); + assertEquals(indexOfDef, decls[0].getNodeOffset()); + } + finally { + fIndex.releaseReadLock(); + } + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexListenerTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexListenerTest.java index 623e1717916..00e88f01d8f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexListenerTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexListenerTest.java @@ -69,7 +69,7 @@ public class IndexListenerTest extends BaseTestCase { TestSourceReader.createFile(fProject1.getProject(), "test.cpp", "int a;"); Thread.sleep(200); - assertTrue(im.joinIndexer(4000, new NullProgressMonitor())); + assertTrue(im.joinIndexer(10000, new NullProgressMonitor())); Thread.sleep(200); assertEquals(1, state[0]); assertEquals(1, state[1]); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java index a2ee8d6237f..85ffcb2ae57 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexSearchTest.java @@ -161,17 +161,7 @@ public class IndexSearchTest extends IndexTestBase { checkIsNamespace(bindings[0]); } - public void testClassInUnnamedNamespace1() throws CoreException { - Pattern pcl= Pattern.compile("CInUnnamed160913"); - - IIndexBinding[] bindings; - - bindings= fIndex.findBindings(pcl, false, INDEX_FILTER, NPM); - assertEquals(1, bindings.length); - checkIsClass(bindings[0]); - } - - public void _testClassInUnnamedNamespace2() throws CoreException { + public void testClassInUnnamedNamespace() throws CoreException { Pattern pcl= Pattern.compile("CInUnnamed160913"); IIndexBinding[] bindings; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java index fc1270bb43b..486dd054ff0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java @@ -23,6 +23,7 @@ public class IndexTests extends TestSuite { suite.addTest(IndexListenerTest.suite()); suite.addTest(IndexSearchTest.suite()); suite.addTest(IndexIncludeTest.suite()); + suite.addTest(IndexBugsTests.suite()); return suite; } diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java index 3de7cc69bb7..a75dbb0a4de 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/TestSourceReader.java @@ -62,8 +62,8 @@ public class TestSourceReader { * is started with '// {tag}' and ends with the first line not started by '//' * @since 4.0 */ - public static String readTaggedComment(Bundle bundle, Class clazz, final String tag) throws IOException { - IPath filePath= new Path("ui/" + clazz.getName().replace('.', '/') + ".java"); + public static String readTaggedComment(Bundle bundle, String srcRoot, Class clazz, final String tag) throws IOException { + IPath filePath= new Path(srcRoot + '/' + clazz.getName().replace('.', '/') + ".java"); InputStream in= FileLocator.openStream(bundle, filePath, false); LineNumberReader reader= new LineNumberReader(new InputStreamReader(in)); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 16477e2f8b1..c67add19bf5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -453,10 +453,11 @@ class PDOMCPPLinkage extends PDOMLinkage { if (type instanceof ICPPBasicType) { return new PDOMCPPBasicType(pdom, parent, (ICPPBasicType)type); } else if (type instanceof ICPPClassType) { - FindEquivalentBinding feb = new FindEquivalentBinding(this,(ICPPClassType)type); - getIndex().accept(feb); - if(feb.getResult()!=null) { - return feb.getResult(); + // aftodo: please review, the binding may be nested in a namespace bug 162011 + // it might be necessary to create the binding for the class here. + PDOMBinding binding= adaptBinding((ICPPClassType) type); + if (binding != null) { + return binding; } } return super.addType(parent, type); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java index 03b60be5c31..d74b8779593 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java @@ -48,7 +48,7 @@ public class BaseUITestCase extends BaseTestCase { * @since 4.0 */ protected String readTaggedComment(final String tag) throws IOException { - return TestSourceReader.readTaggedComment(CTestPlugin.getDefault().getBundle(), getClass(), tag); + return TestSourceReader.readTaggedComment(CTestPlugin.getDefault().getBundle(), "ui", getClass(), tag); } protected IFile createFile(IContainer container, String fileName, String contents) throws Exception {