diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IndexListenerTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexListenerTest.java similarity index 96% rename from core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IndexListenerTest.java rename to core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexListenerTest.java index 4c32595b702..f7fe6cef59b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/IndexListenerTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexListenerTest.java @@ -9,7 +9,7 @@ * Markus Schorn - initial API and implementation *******************************************************************************/ -package org.eclipse.cdt.internal.pdom.tests; +package org.eclipse.cdt.internal.indexer.tests; import java.util.ArrayList; import java.util.List; @@ -71,7 +71,7 @@ public class IndexListenerTest extends BaseTestCase { TestSourceReader.createFile(fProject1.getProject(), "test.cpp", "int a;"); Thread.sleep(200); - assertTrue(im.joinIndexer(2000, new NullProgressMonitor())); + assertTrue(im.joinIndexer(4000, new NullProgressMonitor())); Thread.sleep(200); assertEquals(1, state[0]); assertEquals(1, state[1]); @@ -102,6 +102,5 @@ public class IndexListenerTest extends BaseTestCase { assertTrue(projects.contains(fProject1)); assertTrue(projects.contains(fProject2)); projects.clear(); - } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexSearchTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexSearchTest.java new file mode 100644 index 00000000000..71bc36b61df --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexSearchTest.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * 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.indexer.tests; + +import java.util.LinkedList; +import java.util.regex.Pattern; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.dom.IPDOMNode; +import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +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.core.model.ICProject; +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.internal.core.index.CIndex; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; + +public class IndexSearchTest extends BaseTestCase { + + private static final IndexFilter INDEX_FILTER = new IndexFilter(); + private static final IProgressMonitor NPM= new NullProgressMonitor(); + + public static TestSuite suite() { + TestSuite suite= suite(IndexSearchTest.class, "_"); + suite.addTest(new IndexSearchTest("deleteProject")); + return suite; + } + + private ICProject fProject= null; + private IIndex fIndex= null; + + public IndexSearchTest(String name) { + super(name); + } + + public void setUp() throws Exception { + super.setUp(); + if (fProject == null) { + createProject(); + } + fIndex= CCorePlugin.getIndexManager().getIndex(fProject); + } + + public void tearDown() throws Exception { + fIndex.releaseReadLock(); + super.tearDown(); + } + + + private void createProject() throws CoreException { + // Create the project + final IWorkspace workspace = ResourcesPlugin.getWorkspace(); + workspace.run(new IWorkspaceRunnable() { + public void run(IProgressMonitor monitor) throws CoreException { + fProject= CProjectHelper.createCProject("IndexSearchTest_" + System.currentTimeMillis(), null); + + CCorePlugin.getPDOMManager().setIndexerId(fProject, IPDOMManager.ID_NO_INDEXER); + CProjectHelper.importSourcesFromPlugin(fProject, CTestPlugin.getDefault().getBundle(), "resources/indexTests/search"); + CCorePlugin.getPDOMManager().setIndexerId(fProject, IPDOMManager.ID_FAST_INDEXER); + + // wait until the indexer is done + assertTrue(CCorePlugin.getIndexManager().joinIndexer(5000, new NullProgressMonitor())); + } + }, null); + } + + public void deleteProject() { + if (fProject != null) { + CProjectHelper.delete(fProject); + } + } + + private void checkIsClass(IIndexBinding binding) { + assertTrue(binding instanceof ICPPClassType); + } + + private void checkIsNamespace(IIndexBinding binding) { + assertTrue(binding instanceof ICPPNamespace); + } + + private void checkIsEnumerator(IIndexBinding binding) { + assertTrue(binding instanceof IEnumerator); + } + + private void checkIsEnumeration(IIndexBinding binding) { + assertTrue(binding instanceof IEnumeration); + } + + public void testFindClassInNamespace() throws CoreException { + Pattern pcl= Pattern.compile("C160913"); + Pattern pns= Pattern.compile("ns160913"); + + IIndexBinding[] bindings; + + bindings= fIndex.findBindings(pcl, true, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsClass(bindings[0]); + + bindings= fIndex.findBindings(pcl, false, INDEX_FILTER, NPM); + assertEquals(3, bindings.length); + checkIsClass(bindings[0]); + checkIsClass(bindings[1]); + checkIsClass(bindings[2]); + + bindings= fIndex.findBindings(new Pattern[]{pns, pcl}, true, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsClass(bindings[0]); + + bindings= fIndex.findBindings(new Pattern[]{pns, pcl}, false, INDEX_FILTER, NPM); + assertEquals(2, bindings.length); + checkIsClass(bindings[0]); + checkIsClass(bindings[1]); + + bindings= fIndex.findBindings(new Pattern[]{pns, pns, pcl}, true, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsClass(bindings[0]); + + bindings= fIndex.findBindings(new Pattern[]{pns, pns, pcl}, false, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsClass(bindings[0]); + + // same with namespace + bindings= fIndex.findBindings(pns, true, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsNamespace(bindings[0]); + + bindings= fIndex.findBindings(pns, false, INDEX_FILTER, NPM); + assertEquals(2, bindings.length); + checkIsNamespace(bindings[0]); + checkIsNamespace(bindings[1]); + + bindings= fIndex.findBindings(new Pattern[]{pns, pns}, true, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsNamespace(bindings[0]); + + bindings= fIndex.findBindings(new Pattern[]{pns, pns}, false, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsNamespace(bindings[0]); + } + + public void testFindEnumerator() throws CoreException { + Pattern pEnumeration= Pattern.compile("E20061017"); + Pattern pEnumerator= Pattern.compile("e20061017"); + + IIndexBinding[] bindings; + + // enumerators are found in global scope + bindings= fIndex.findBindings(pEnumerator, true, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsEnumerator(bindings[0]); + + bindings= fIndex.findBindings(pEnumerator, false, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsEnumerator(bindings[0]); + + bindings= fIndex.findBindings(new Pattern[]{pEnumeration, pEnumerator}, true, INDEX_FILTER, NPM); + assertEquals(0, bindings.length); + + bindings= fIndex.findBindings(new Pattern[]{pEnumeration, pEnumerator}, false, INDEX_FILTER, NPM); + assertEquals(0, bindings.length); + + bindings= fIndex.findBindings(pEnumeration, true, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsEnumeration(bindings[0]); + + bindings= fIndex.findBindings(pEnumeration, false, INDEX_FILTER, NPM); + assertEquals(1, bindings.length); + checkIsEnumeration(bindings[0]); + } + + public void testSanityOfMayHaveChildren() throws CoreException { + PDOM pdom= (PDOM) ((CIndex) fIndex).getPrimaryFragments()[0]; + pdom.accept(new IPDOMVisitor() { + LinkedList stack= new LinkedList(); + public boolean visit(IPDOMNode node) throws CoreException { + if (!stack.isEmpty()) { + Object last= stack.getLast(); + if (last instanceof PDOMBinding) { + assertTrue(((PDOMBinding) last).mayHaveChildren()); + } + } + stack.add(node); + return true; + } + public void leave(IPDOMNode node) throws CoreException { + assertEquals(stack.removeLast(), node); + } + }); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexerTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexerTests.java new file mode 100644 index 00000000000..ccb3c9fcd61 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/indexer/tests/IndexerTests.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * 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.indexer.tests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test suite for the indexer tests + */ +public class IndexerTests extends TestSuite { + + public static Test suite() { + TestSuite suite = new IndexerTests(); + suite.addTest(IndexListenerTest.suite()); + return suite; + } + +} diff --git a/core/org.eclipse.cdt.core.tests/resources/indexTests/search/enumerator.cpp b/core/org.eclipse.cdt.core.tests/resources/indexTests/search/enumerator.cpp new file mode 100644 index 00000000000..711e162057e --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/indexTests/search/enumerator.cpp @@ -0,0 +1,3 @@ +enum E20061017 { + e20061017 +}; \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/resources/indexTests/search/nested.cpp b/core/org.eclipse.cdt.core.tests/resources/indexTests/search/nested.cpp new file mode 100644 index 00000000000..552105faaac --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/indexTests/search/nested.cpp @@ -0,0 +1,9 @@ +class C160913{}; + +namespace ns160913 { + class C160913{}; + + namespace ns160913 { + class C160913{}; + } +}; diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java index 4d6b4bac9c9..86f22c4e341 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.parser.failedTests.ASTFailedTests; import org.eclipse.cdt.core.parser.failedTests.FailedCompleteParseASTTest; import org.eclipse.cdt.core.parser.failedTests.STLFailedTests; import org.eclipse.cdt.core.parser.tests.ParserTestSuite; +import org.eclipse.cdt.internal.indexer.tests.IndexerTests; import org.eclipse.cdt.internal.pdom.tests.PDOMTests; /** @@ -79,6 +80,7 @@ public class AutomatedIntegrationSuite extends TestSuite { // Add in PDOM tests suite.addTest(PDOMTests.suite()); + suite.addTest(IndexerTests.suite()); // Add all failed tests suite.addTestSuite(ASTFailedTests.class); diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java index 14c3dd86ee8..0bc1ae6d505 100644 --- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/CProjectHelper.java @@ -9,6 +9,7 @@ * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.core.testplugin; +import java.io.File; import java.lang.reflect.InvocationTargetException; import java.util.zip.ZipFile; @@ -37,17 +38,29 @@ import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; import org.eclipse.ui.wizards.datatransfer.ImportOperation; import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider; +import org.osgi.framework.Bundle; /** * Helper methods to set up a ICProject. */ public class CProjectHelper { + private final static IOverwriteQuery OVERWRITE_QUERY= new IOverwriteQuery() { + public String queryOverwrite(String file) { + return ALL; + } + }; + /** * Creates a ICProject. */ @@ -279,17 +292,25 @@ public class CProjectHelper { ZipFileStructureProvider structureProvider = new ZipFileStructureProvider(srcZipFile); try { ImportOperation op = new ImportOperation(destPath, structureProvider.getRoot(), structureProvider, - new ImportOverwriteQuery()); + OVERWRITE_QUERY); op.run(monitor); } catch (InterruptedException e) { // should not happen } } - private static class ImportOverwriteQuery implements IOverwriteQuery { - - public String queryOverwrite(String file) { - return ALL; + + public static void importSourcesFromPlugin(ICProject project, Bundle bundle, String sources) throws CoreException { + try { + String baseDir= FileLocator.toFileURL(FileLocator.find(bundle, new Path(sources), null)).getFile(); + ImportOperation importOp = new ImportOperation(project.getProject().getFullPath(), + new File(baseDir), FileSystemStructureProvider.INSTANCE, OVERWRITE_QUERY); + importOp.setCreateContainerStructure(false); + importOp.run(new NullProgressMonitor()); + } + catch (Exception e) { + throw new CoreException(new Status(IStatus.ERROR, CTestPlugin.PLUGIN_ID, 0, "Import Interrupted", e)); } } + } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index 68b4a7849b8..e02ed908915 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -42,7 +42,6 @@ import org.eclipse.cdt.internal.core.index.IIndexProxyBinding; import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory; -import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile; import org.eclipse.cdt.internal.core.pdom.dom.PDOMInclude; @@ -254,8 +253,8 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { if (monitor.isCanceled()) throw new CoreException(Status.OK_STATUS); - if (node instanceof IBinding) { - IBinding binding = (IBinding)node; + if (node instanceof PDOMBinding) { + PDOMBinding binding = (PDOMBinding)node; String name = binding.getName(); // check if we have a complete match. @@ -265,7 +264,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { } // check if we have a partial match - if (binding instanceof IPDOMMemberOwner) { + if (binding.mayHaveChildren()) { boolean visitNextLevel= false; BitSet updatedMatchesUpToLevel= new BitSet(); if (!isFullyQualified) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java index 81f043f5c1e..aca99ecd6ed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java @@ -138,7 +138,7 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IIndexFragmen } catch (CoreException e) { CCorePlugin.log(e); } - return ""; + return ""; //$NON-NLS-1$ } public char[] getNameCharArray() { @@ -166,4 +166,8 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IIndexFragmen public IIndexFragment getFragment() { return pdom; } + + public boolean mayHaveChildren() { + return false; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java index 03e470d815e..1d02a9e8544 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java @@ -148,4 +148,8 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, IPDOM protected int getRecordSize() { return RECORD_SIZE; } + + public boolean mayHaveChildren() { + return true; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index 708772310c9..f2c4c40574d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -331,4 +331,8 @@ class PDOMCPPClassType extends PDOMCPPBinding implements ICPPClassType, public void removeBinding(IBinding binding) throws DOMException { throw new PDOMNotImplementedError(); } + + public boolean mayHaveChildren() { + return true; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java index cd3ef20f4cf..3b7beb53620 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.BTree; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.cdt.internal.core.pdom.dom.FindBindingsInBTree; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNamedNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; @@ -201,4 +202,7 @@ class PDOMCPPNamespace extends PDOMCPPBinding public void removeBinding(IBinding binding) throws DOMException { throw new PDOMNotImplementedError(); } + public boolean mayHaveChildren() { + return true; + } }