1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

167096: check in of new functionality

This commit is contained in:
Andrew Ferguson 2007-03-19 16:28:18 +00:00
parent 855cc012dd
commit 6d88aaec37
22 changed files with 1409 additions and 58 deletions

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Ltd. 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:
* Andrew Ferguson (Symbian) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.internal.index.provider.test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.index.provider.IPDOMDescriptor;
import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.core.runtime.CoreException;
/**
* Provides no pdom descriptors, used for testing the behaviour of IndexManager over
* project lifecycles.
*/
public class DummyProvider1 implements IReadOnlyPDOMProvider {
static List trace = Collections.synchronizedList(new ArrayList());
public static List getProjectsTrace() {
return trace;
}
public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config) {
return new IPDOMDescriptor[0];
}
public boolean providesFor(ICProject project) throws CoreException {
trace.add(project);
return true;
}
}

View file

@ -0,0 +1,475 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.cdtvariables.ICdtVariablesContributor;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.provider.IIndexProvider;
import org.eclipse.cdt.core.internal.index.provider.test.DummyProvider1;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.settings.model.ICBuildSetting;
import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICExternalSetting;
import org.eclipse.cdt.core.settings.model.ICFileDescription;
import org.eclipse.cdt.core.settings.model.ICFolderDescription;
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.cdt.core.settings.model.ICSettingContainer;
import org.eclipse.cdt.core.settings.model.ICSettingObject;
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
import org.eclipse.cdt.core.settings.model.ICStorageElement;
import org.eclipse.cdt.core.settings.model.ICTargetPlatformSetting;
import org.eclipse.cdt.core.settings.model.WriteAccessException;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.provider.IIndexFragmentProvider;
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.QualifiedName;
/**
* Example usage and test for IIndexProvider
*/
public class IndexProviderManagerTest extends IndexTestBase {
public IndexProviderManagerTest() {
super("IndexProviderManagerTest");
}
public static TestSuite suite() {
return suite(IndexProviderManagerTest.class);
}
public void testProvider_SimpleLifeCycle() throws Exception {
DummyProvider1.getProjectsTrace().clear();
List cprojects = new ArrayList(), expectedTrace = new ArrayList();
try {
for(int i=0; i<3; i++) {
ICProject cproject = CProjectHelper.createCProject("P"+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER);
IIndex index = CCorePlugin.getIndexManager().getIndex(cproject);
cprojects.add(cproject);
expectedTrace.add(cproject);
}
assertEquals(expectedTrace, DummyProvider1.getProjectsTrace());
for(int i=0; i<expectedTrace.size(); i++) {
ICProject cproject = (ICProject) expectedTrace.get(i);
IIndex index = CCorePlugin.getIndexManager().getIndex(cproject);
}
assertEquals(expectedTrace, DummyProvider1.getProjectsTrace());
} finally {
for(int i=0; i<cprojects.size(); i++) {
ICProject cproject = (ICProject) expectedTrace.get(i);
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
}
}
}
public void testProvider_OverDeleteAndAdd() throws Exception {
DummyProvider1.getProjectsTrace().clear();
List expectedTrace = new ArrayList();
ICProject cproject = null;
try {
String name = "P"+System.currentTimeMillis();
cproject = CProjectHelper.createCProject(name, "bin", IPDOMManager.ID_NO_INDEXER);
IIndex index = CCorePlugin.getIndexManager().getIndex(cproject);
expectedTrace.add(cproject);
assertEquals(expectedTrace, DummyProvider1.getProjectsTrace());
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
cproject = CProjectHelper.createCProject(name, "bin", IPDOMManager.ID_NO_INDEXER);
index = CCorePlugin.getIndexManager().getIndex(cproject);
expectedTrace.add(cproject);
assertEquals(expectedTrace, DummyProvider1.getProjectsTrace());
} finally {
if(cproject!=null) {
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
}
}
}
public void testProvider_OverMove() throws Exception {
DummyProvider1.getProjectsTrace().clear();
List cprojects = new ArrayList();
List expectedTrace = new ArrayList();
/* n.b. here we test for the current implementation expected behaviour,
* not the contract of IIndexProvider.providesFor
*/
ICProject cproject = null;
try {
String name = "P"+System.currentTimeMillis();
cproject = CProjectHelper.createCProject(name, "bin", IPDOMManager.ID_NO_INDEXER);
IIndex index = CCorePlugin.getIndexManager().getIndex(cproject);
expectedTrace.add(cproject);
assertEquals(expectedTrace, DummyProvider1.getProjectsTrace());
// move the project to a random new location
File newLocation = CProjectHelper.freshDir();
IProjectDescription description = cproject.getProject().getDescription();
description.setLocationURI(newLocation.toURI());
cproject.getProject().move(description, IResource.FORCE | IResource.SHALLOW, new NullProgressMonitor());
index = CCorePlugin.getIndexManager().getIndex(cproject);
assertEquals(expectedTrace, DummyProvider1.getProjectsTrace());
} finally {
if(cproject!=null) {
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
}
}
}
public void testGetProvidedFragments() throws Exception {
ICProject cproject= CProjectHelper.createCProject("IndexProviderManagerTest", "bin", IPDOMManager.ID_NO_INDEXER);
try {
MockState mockState = new MockState(cproject);
MockStateIndexFragmentProvider provider1 = new MockStateIndexFragmentProvider(cproject);
MockStateIndexFragmentProvider provider2 = new MockStateIndexFragmentProvider(cproject);
IndexProviderManager ipm = ((PDOMManager)CCorePlugin.getIndexManager()).getIndexProviderManager();
ipm.addIndexProvider(provider1);
ipm.addIndexProvider(provider2);
IIndexFragment[] fragments;
mockState.setConfig(MockState.REL_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[0]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[0]));
mockState.setConfig(MockState.DBG_V2_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[3]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[3]));
mockState.setConfig(MockState.DBG_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(0, fragments.length);
mockState.setConfig(MockState.REL_V2_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[1]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[1]));
mockState.setConfig(MockState.REL_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[0]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[0]));
provider1.invert();
mockState.setConfig(MockState.REL_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[3]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[0]));
mockState.setConfig(MockState.DBG_V2_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[0]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[3]));
mockState.setConfig(MockState.DBG_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(1, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[1]));
mockState.setConfig(MockState.REL_V2_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(1, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[1]));
mockState.setConfig(MockState.REL_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[3]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[0]));
provider2.invert();
mockState.setConfig(MockState.REL_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[3]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[3]));
mockState.setConfig(MockState.DBG_V2_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[0]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[0]));
mockState.setConfig(MockState.DBG_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[1]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[1]));
mockState.setConfig(MockState.REL_V2_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(0, fragments.length);
mockState.setConfig(MockState.REL_V1_ID);
fragments = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
assertEquals(2, fragments.length);
assertTrue(ArrayUtil.contains(fragments, provider1.fragments[3]));
assertTrue(ArrayUtil.contains(fragments, provider2.fragments[3]));
} finally {
if (cproject != null) {
cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
}
}
}
}
class MockStateIndexProvider implements IIndexProvider {
protected ICProject targetProject;
public MockStateIndexProvider(ICProject cproject) {
this.targetProject = cproject;
}
public boolean providesFor(ICProject cproject) throws CoreException {
return this.targetProject.equals(cproject);
}
}
class MockStateIndexFragmentProvider extends MockStateIndexProvider implements IIndexFragmentProvider {
IIndexFragment[] fragments;
int[] mcounts;
boolean invert;
public void invert() {
invert = !invert;
}
public MockStateIndexFragmentProvider(ICProject cproject) {
super(cproject);
fragments = new IIndexFragment[MockState.states.size()];
mcounts = new int[MockState.states.size()];
for(int i=0; i<MockState.states.size(); i++) {
fragments[i] = createMockFragment(mcounts, i);
}
}
public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) throws CoreException {
int index = MockState.states.indexOf(config.getId());
index = invert ? (fragments.length-1)-index : index;
// nb. we're checking this after inverting on purpose
if(index == MockState.states.indexOf(MockState.DBG_V1_ID)) {
return new IIndexFragment[0];
} else {
return new IIndexFragment[] {fragments[index]};
}
}
public IIndexFragment createMockFragment(final int[] mcounts, final int index) {
return (IIndexFragment) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {IIndexFragment.class}, new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
if(method.getReturnType().isArray()) {
result = Array.newInstance(method.getReturnType().getComponentType(), 0);
}
if(method.getName().equals("toString")) {
return "[Mock index fragment #"+index+"]";
}
mcounts[index]++;
return result;
}
});
}
}
class MockConfig implements ICConfigurationDescription {
String id;
IProject project;
MockConfig(String id, IProject project) {
this.id= id;
this.project= project;
}
public String getId() {
return id;
}
public ICConfigExtensionReference create(String extensionPoint,
String extension) throws CoreException {
return null;
}
public ICExternalSetting createExternalSetting(String[] languageIDs,
String[] contentTypeIds, String[] extensions,
ICLanguageSettingEntry[] entries) throws WriteAccessException {
return null;
}
public ICFileDescription createFileDescription(IPath path,
ICResourceDescription base) throws CoreException,
WriteAccessException {
return null;
}
public ICFolderDescription createFolderDescription(IPath path,
ICFolderDescription base) throws CoreException,
WriteAccessException {
return null;
}
public ICConfigExtensionReference[] get(String extensionPointID) {
return null;
}
public ICBuildSetting getBuildSetting() {
return null;
}
public String getBuildSystemId() {
return null;
}
public ICdtVariablesContributor getBuildVariablesContributor() {
return null;
}
public CConfigurationData getConfigurationData() {
return null;
}
public String getDescription() {
return null;
}
public ICExternalSetting[] getExternalSettings() {
return null;
}
public ICFileDescription[] getFileDescriptions() {
return null;
}
public ICFolderDescription[] getFolderDescriptions() {
return null;
}
public ICProjectDescription getProjectDescription() {
return CoreModel.getDefault().getProjectDescription(project);
}
public Map getReferenceInfo() {
return null;
}
public ICResourceDescription getResourceDescription(IPath path,
boolean exactPath) {
return null;
}
public ICResourceDescription[] getResourceDescriptions() {
return null;
}
public ICFolderDescription getRootFolderDescription() {return null;}
public Object getSessionProperty(QualifiedName name) {return null;}
public ICSourceEntry[] getSourceEntries() {return null;}
public ICTargetPlatformSetting getTargetPlatformSetting() {return null;}
public boolean isActive() {return false;}
public boolean isModified() {return false;}
public boolean isPreferenceConfiguration() {return false;}
public void remove(ICConfigExtensionReference ext) throws CoreException {}
public void remove(String extensionPoint) throws CoreException {}
public void removeExternalSetting(ICExternalSetting setting) throws WriteAccessException {}
public void removeExternalSettings() throws WriteAccessException {}
public void removeResourceDescription(ICResourceDescription des)
throws CoreException, WriteAccessException {}
public void setActive() throws WriteAccessException {}
public void setConfigurationData(String buildSystemId,
CConfigurationData data) throws WriteAccessException {}
public void setDescription(String des) throws WriteAccessException {}
public void setName(String name) throws WriteAccessException {}
public void setReferenceInfo(Map refs) throws WriteAccessException {}
public void setSessionProperty(QualifiedName name, Object value) {}
public void setSourceEntries(ICSourceEntry[] entries) throws CoreException,
WriteAccessException {}
public ICSettingObject[] getChildSettings() {return null;}
public ICConfigurationDescription getConfiguration() {return null;}
public String getName() {return null;}
public ICSettingContainer getParent() {return null;}
public int getType() {return 0;}
public boolean isReadOnly() {return false;}
public boolean isValid() {return false;}
public ICStorageElement getStorage(String id, boolean create)
throws CoreException {
return null;
}
public void removeStorage(String id) throws CoreException {
}
}
/*
* This represents a project state, here we use configuration IDs as the only state variable
*/
class MockState {
public static final String REL_V1_ID = "rel_v1";
public static final String REL_V2_ID = "rel_v2";
public static final String DBG_V1_ID = "dbg_v1";
public static final String DBG_V2_ID = "dbg_v2";
public static final List states = new ArrayList(Arrays.asList(new String[]{REL_V1_ID, REL_V2_ID, DBG_V1_ID, DBG_V2_ID}));
private IProject project;
private String currentConfig;
public MockState(ICProject cproject) {
this.currentConfig = REL_V1_ID;
this.project= cproject.getProject();
}
public ICConfigurationDescription getCurrentConfig() {
return new MockConfig(currentConfig, project);
}
public void setConfig(String newConfig) throws CoreException {
currentConfig = newConfig;
}
}

View file

@ -29,6 +29,7 @@ public class IndexTests extends TestSuite {
suite.addTest(IndexBugsTests.suite());
suite.addTest(EnclosingNamesTest.suite());
suite.addTest(TeamSharedIndexTest.suite());
suite.addTest(IndexProviderManagerTest.suite());
IndexCBindingResolutionTest.addTests(suite);
IndexCPPBindingResolutionTest.addTests(suite);

View file

@ -0,0 +1,215 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.pdom.tests;
import java.io.File;
import java.net.URI;
import junit.framework.Test;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.index.ResourceContainerRelativeLocationConverter;
import org.eclipse.cdt.core.index.URIRelativeLocationConverter;
import org.eclipse.cdt.core.index.provider.IPDOMDescriptor;
import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
import org.eclipse.cdt.internal.core.index.provider.ReadOnlyPDOMProviderBridge;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* Tests addition of external pdom's into the logical index
*/
public class PDOMProviderTests extends PDOMTestBase {
public static Test suite() {
return suite(PDOMProviderTests.class);
}
public void testLifeCycle() throws Exception {
final File tempPDOM= File.createTempFile("foo", "bar");
{
ICProject cproject= CProjectHelper.createCCProject("foo"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n");
CCorePlugin.getIndexManager().joinIndexer(3000, NPM);
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
} finally {
index.releaseReadLock();
}
ResourceContainerRelativeLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject());
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, tempPDOM, cvr);
assertTrue(tempPDOM.exists());
CProjectHelper.delete(cproject);
}
final URI baseURI= new File("c:/ExternalSDK/").toURI();
final ICProject cproject2= CProjectHelper.createCCProject("bar"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n");
CCorePlugin.getIndexManager().joinIndexer(3000, NPM);
IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager();
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() {
public IPDOMDescriptor[] getDescriptors(
ICConfigurationDescription config) {
return new IPDOMDescriptor[] {
new IPDOMDescriptor() {
public IIndexLocationConverter getIndexLocationConverter() {
return new URIRelativeLocationConverter(baseURI);
}
public IPath getLocation() {
return new Path(tempPDOM.getAbsolutePath());
}
}
};
}
public boolean providesFor(ICProject project)
throws CoreException {
return cproject2.equals(project);
}
}
));
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject2);
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
});
assertEquals(2, bindings.length);
}
public void testCommonSDK() throws Exception {
final File tempPDOM= File.createTempFile("foo", "bar");
{
ICProject cproject= CProjectHelper.createCCProject("foo"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject.getProject(), new Path("/this.h"), "class A {};\n\n");
CCorePlugin.getIndexManager().joinIndexer(3000, NPM);
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject);
index.acquireReadLock();
try {
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
} finally {
index.releaseReadLock();
}
ResourceContainerRelativeLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject());
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, tempPDOM, cvr);
assertTrue(tempPDOM.exists());
CProjectHelper.delete(cproject);
}
final ICProject cproject3= CProjectHelper.createCCProject("bar"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject3.getProject(), new Path("/source.cpp"), "namespace Y { class A {}; }\n\n");
CCorePlugin.getIndexManager().joinIndexer(3000, NPM);
final URI baseURI= new File("c:/ExternalSDK/").toURI();
final ICProject cproject2= CProjectHelper.createCCProject("baz"+System.currentTimeMillis(), null, IPDOMManager.ID_FAST_INDEXER);
TestSourceReader.createFile(cproject2.getProject(), new Path("/source.cpp"), "namespace X { class A {}; }\n\n");
CCorePlugin.getIndexManager().joinIndexer(3000, NPM);
IndexProviderManager ipm= CCoreInternals.getPDOMManager().getIndexProviderManager();
ipm.addIndexProvider(new ReadOnlyPDOMProviderBridge(
new IReadOnlyPDOMProvider() {
public IPDOMDescriptor[] getDescriptors(
ICConfigurationDescription config) {
return new IPDOMDescriptor[] {
new IPDOMDescriptor() {
public IIndexLocationConverter getIndexLocationConverter() {
return new URIRelativeLocationConverter(baseURI);
}
public IPath getLocation() {
return new Path(tempPDOM.getAbsolutePath());
}
}
};
}
public boolean providesFor(ICProject project)
throws CoreException {
return cproject2.equals(project) || cproject3.equals(project);
}
}
));
{
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject2);
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertEquals(1, index.findDefinitions(bindings[0]).length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
});
assertEquals(2, bindings.length);
}
{
IIndex index= CCorePlugin.getIndexManager().getIndex(cproject3);
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertEquals(1, index.findDefinitions(bindings[0]).length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
});
assertEquals(2, bindings.length);
}
{
IIndex index= CCorePlugin.getIndexManager().getIndex(new ICProject[]{cproject2, cproject3});
IBinding[] bindings= index.findBindings("A".toCharArray(), IndexFilter.ALL, NPM);
assertEquals(1, bindings.length);
assertEquals(1, index.findDefinitions(bindings[0]).length);
bindings= index.findBindingsForPrefix("A".toCharArray(), false, new IndexFilter() {
public boolean acceptBinding(IBinding binding) {
return binding instanceof ICPPClassType;
}
});
assertEquals(3, bindings.length);
}
}
}

View file

@ -24,11 +24,13 @@ public class PDOMTests extends TestSuite {
public static Test suite() {
TestSuite suite = new PDOMTests();
suite.addTest(DBTest.suite());
suite.addTest(DBPropertiesTests.suite());
suite.addTest(PDOMBugsTest.suite());
suite.addTest(PDOMSearchTest.suite());
suite.addTest(PDOMLocationTests.suite());
suite.addTest(PDOMProviderTests.suite());
suite.addTest(EnumerationTests.suite());
suite.addTest(ClassTests.suite());
suite.addTest(TypesTests.suite());

View file

@ -27,5 +27,11 @@
class="org.eclipse.cdt.internal.index.tests.FakeIndexer">
</run>
</extension>
<extension
point="org.eclipse.cdt.core.CIndex">
<ReadOnlyPDOMProvider
class="org.eclipse.cdt.core.internal.index.provider.test.DummyProvider1">
</ReadOnlyPDOMProvider>
</extension>
</plugin>

View file

@ -23,6 +23,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.core.formatter,
org.eclipse.cdt.core.index,
org.eclipse.cdt.core.index.export,
org.eclipse.cdt.core.index.provider,
org.eclipse.cdt.core.model,
org.eclipse.cdt.core.model.util,
org.eclipse.cdt.core.parser,
@ -44,6 +45,7 @@ Export-Package: org.eclipse.cdt.core,
org.eclipse.cdt.internal.core.dom.parser.cpp;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.envvar,
org.eclipse.cdt.internal.core.index;x-internal:=true,
org.eclipse.cdt.internal.core.index.provider,
org.eclipse.cdt.internal.core.language,
org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring",
org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui",

View file

@ -32,10 +32,33 @@ import org.eclipse.core.runtime.IProgressMonitor;
* @since 4.0
*/
public interface IIndexManager {
/**
* Constant for passing to getIndex methods. This constant, when set, indicates
* projects referenced by the set of input projects should also be added
* to the resulting index.
*/
public final static int ADD_DEPENDENCIES = 0x1;
/**
* Constant for passing to getIndex methods. This constant, when set, indicates
* projects which reference any of the set of input projects should also be
* added to the resulting index.
*/
public final static int ADD_DEPENDENT = 0x2;
/**
* Constant for passing to getIndex methods. This constant, when set, indicates
* that index content provided via the CIndex extension point should not be included
* in the resulting index, as it would have done otherwise.
*/
public final static int SKIP_PROVIDED = 0x4;
/**
* Constant for indicating there is no time out period for joining the indexer job.
* @see IIndexManager#joinIndexer(int, IProgressMonitor)
*/
public final static int FOREVER= -1;
/**
* Returns the index for the given project.
* @param project the project to get the index for

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.core.index.provider;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.core.runtime.CoreException;
/**
* An IIndexProvider implementation provides additional indexing information for CDT projects
* This interface only exists to hold commonality from sub-interfaces.
*/
public interface IIndexProvider {
/**
* This method is called to attach the index provider to the project specified. If the provider determines that it doesn't
* and will never provide indexes for the specified project, then it should return false to opt-out of being queried for
* that project.
* <p>
* The method will only be called once per project per eclipse session. This method will be called when a project is deleted
* and a new project of the same name added. It also may be called lazily (at the point of first logical index use).
* <p>
* It is also expected the provider implementation will want to watch some properties of the project to determine
* what index content to provide.
* @param project
* @return
*/
public boolean providesFor(ICProject project) throws CoreException;
}

View file

@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.core.index.provider;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.core.runtime.IPath;
/**
*
*/
public interface IPDOMDescriptor {
/**
* The absolute location in a local file system of the PDOM format file
* to contribute to the logical index.
* @return an absolute location of an existing file
*/
IPath getLocation();
/**
* An index location converter suitable of translating the internal
* formatted path representations to index locations representing the
* current content location.
* @return an index location converter
*/
IIndexLocationConverter getIndexLocationConverter();
}

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.core.index.provider;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
/**
* This interface is intended for ISVs to implement when plugging a mechanism
* for read-only/offline indexes into the CIndex.ReadOnlyPDOMProvider extension point element.
*/
public interface IReadOnlyPDOMProvider extends IIndexProvider {
/**
* Returns the descriptors
* @param cproject
* @param config
* @return
*/
public IPDOMDescriptor[] getDescriptors(ICConfigurationDescription config);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others.
* Copyright (c) 2007 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
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index;
@ -17,6 +18,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -25,6 +27,9 @@ import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
@ -36,6 +41,7 @@ import org.eclipse.core.runtime.CoreException;
public class IndexFactory {
private static final int ADD_DEPENDENCIES = IIndexManager.ADD_DEPENDENCIES;
private static final int ADD_DEPENDENT = IIndexManager.ADD_DEPENDENT;
private static final int SKIP_PROVIDED = IIndexManager.SKIP_PROVIDED;
private PDOMManager fPDOMManager;
@ -44,26 +50,37 @@ public class IndexFactory {
}
public IIndex getIndex(ICProject[] projects, int options) throws CoreException {
projects = (ICProject[]) ArrayUtil.removeNulls(ICProject.class, projects);
boolean addDependencies= (options & ADD_DEPENDENCIES) != 0;
boolean addDependent= (options & ADD_DEPENDENT) != 0;
boolean skipProvided= (options & SKIP_PROVIDED) != 0;
IndexProviderManager m = ((PDOMManager)CCorePlugin.getPDOMManager()).getIndexProviderManager();
HashMap map= new HashMap();
Collection selectedProjects= getProjects(projects, addDependencies, addDependent, map, new Integer(1));
ArrayList pdoms= new ArrayList();
HashMap fragments= new LinkedHashMap();
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
ICProject project = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(project);
ICProject cproject = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
if (pdom != null) {
pdoms.add(pdom);
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
if(!skipProvided) {
ICConfigurationDescription activeCfg= CoreModel.getDefault().getProjectDescription(cproject.getProject()).getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) {
fragments.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]);
}
}
}
}
if (pdoms.isEmpty()) {
if (fragments.isEmpty()) {
return EmptyCIndex.INSTANCE;
}
// todo add the SDKs
int primaryFragmentCount= pdoms.size();
int primaryFragmentCount= fragments.size();
if (!addDependencies) {
projects= (ICProject[]) selectedProjects.toArray(new ICProject[selectedProjects.size()]);
@ -71,15 +88,22 @@ public class IndexFactory {
// don't clear the map, so projects are not selected again
selectedProjects= getProjects(projects, true, false, map, new Integer(2));
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
ICProject project = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(project);
ICProject cproject = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
if (pdom != null) {
pdoms.add(pdom);
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
}
if(!skipProvided) {
ICConfigurationDescription activeCfg= CoreModel.getDefault().getProjectDescription(cproject.getProject()).getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) {
fragments.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]);
}
}
}
// todo add further SDKs
}
Collection pdoms= fragments.values();
return new CIndex((IIndexFragment[]) pdoms.toArray(new IIndexFragment[pdoms.size()]), primaryFragmentCount);
}
@ -147,34 +171,41 @@ public class IndexFactory {
// mstodo to support dependent projects: Collection selectedProjects= getSelectedProjects(new ICProject[]{project}, false);
Collection selectedProjects= Collections.singleton(project);
ArrayList pdoms= new ArrayList();
Map readOnlyFrag= new LinkedHashMap();
Map fragments= new LinkedHashMap();
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
ICProject p = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(p);
if (pdom != null) {
pdoms.add(pdom);
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
IndexProviderManager m = ((PDOMManager)CCorePlugin.getPDOMManager()).getIndexProviderManager();
ICConfigurationDescription activeCfg= CoreModel.getDefault().getProjectDescription(p.getProject()).getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) {
readOnlyFrag.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]);
}
}
}
selectedProjects= getProjects(new ICProject[] {project}, true, false, new HashMap(), new Integer(1));
selectedProjects.remove(project);
ArrayList readOnly= new ArrayList();
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
ICProject cproject = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
if (pdom != null) {
readOnly.add(pdom);
readOnlyFrag.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
}
}
if (pdoms.isEmpty()) {
if (fragments.isEmpty()) {
throw new CoreException(CCorePlugin.createStatus(
MessageFormat.format(Messages.IndexFactory_errorNoSuchPDOM0, new Object[]{project.getElementName()})));
}
Collection pdoms= fragments.values();
Collection roPdoms= readOnlyFrag.values();
return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.size()]),
(IIndexFragment[]) readOnly.toArray(new IIndexFragment[readOnly.size()]) );
(IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) );
}
}

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.provider;
import org.eclipse.cdt.core.index.provider.IIndexProvider;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.core.runtime.CoreException;
/**
* The ICProject IIndex is a logical index composed of potentially many
* IIndexFragments. An IIndexFragmentProvider is a source of IIndexFragments.
* <p>
*
* <p>
* IndexProviders are registered via the extension point
* <code>org.eclipse.cdt.core.CIndex</code>
* <p>
*/
public interface IIndexFragmentProvider extends IIndexProvider {
/**
* Returns an array of IIndexFragment objects to add to the specified {@link ICConfigurationDescription}
* @param project
* @return an array of IIndexFragment objects to add to the specified {@link ICConfigurationDescription}
*/
IIndexFragment[] getIndexFragments(ICConfigurationDescription config) throws CoreException;
}

View file

@ -0,0 +1,187 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.provider;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.provider.IIndexProvider;
import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
/**
* The IndexProviderManager is responsible for maintaining the set of index
* fragments contributed via the CIndex extension point. This is done
* for the current project state (on a per-project basis).
* <p>
* It is an internal class, and is public only for testing purposes.
*/
public final class IndexProviderManager implements IElementChangedListener {
public static final String READ_ONLY_PDOM_PROVIDER= "ReadOnlyPDOMProvider"; //$NON-NLS-1$
private IIndexFragmentProvider[] allProviders;
public IndexProviderManager() {
List providers = new ArrayList();
IExtensionRegistry registry = Platform.getExtensionRegistry();
IExtensionPoint indexProviders = registry.getExtensionPoint(CCorePlugin.INDEX_UNIQ_ID);
IExtension[] extensions = indexProviders.getExtensions();
for(int i=0; i<extensions.length; i++) {
IExtension extension = extensions[i];
try {
IConfigurationElement[] ce = extension.getConfigurationElements();
for(int j=0; j<ce.length; j++) {
if(ce[j].getName().equals(READ_ONLY_PDOM_PROVIDER)) {
IIndexProvider provider = (IIndexProvider) ce[0].createExecutableExtension("class"); //$NON-NLS-1$
if(provider instanceof IReadOnlyPDOMProvider) {
provider = new ReadOnlyPDOMProviderBridge((IReadOnlyPDOMProvider)provider);
providers.add(provider);
} else {
CCorePlugin.log(MessageFormat.format(
Messages.IndexProviderManager_0,
new Object[] {extension.getContributor().getName()}
));
}
}
}
} catch(CoreException ce) {
CCorePlugin.log(ce);
}
}
CoreModel.getDefault().addElementChangedListener(this);
this.allProviders = (IIndexFragmentProvider[]) providers.toArray(new IIndexFragmentProvider[providers.size()]);
}
/**
* Get the array of IIndexFragment objects provided by all of the
* registered IIndexProvider objects for the specified project, and
* for the current state of the project.
* Order in the array is not significant.
* @param project
* @return the array of IIndexFragment objects for the current state
*/
public IIndexFragment[] getProvidedIndexFragments(ICConfigurationDescription config) throws CoreException {
List preResult = new ArrayList();
IProject project= config.getProjectDescription().getProject();
for(int i=0; i<allProviders.length; i++) {
try {
if(providesForProject(allProviders[i], project)) {
preResult.addAll(Arrays.asList(allProviders[i].getIndexFragments(config)));
}
} catch(CoreException ce) {
CCorePlugin.log(ce);
}
}
IIndexFragment[] result = (IIndexFragment[]) preResult.toArray(new IIndexFragment[preResult.size()]);
return result;
}
/**
* This is only public for test purposes
* @param provider
*/
public void addIndexProvider(IIndexProvider provider) {
if(!(provider instanceof IIndexFragmentProvider)) {
/* This engineering compromise can be resolved when we address whether
* IIndexFragment can be made public. The extension point only accepts
* instances of IOfflinePDOMIndexProvider so this should never happen (tm)
*/
CCorePlugin.log("An unknown index provider implementation was plugged in to the CIndex extension point"); //$NON-NLS-1$
return;
}
IIndexFragmentProvider[] newAllProviders = new IIndexFragmentProvider[allProviders.length+1];
System.arraycopy(allProviders, 0, newAllProviders, 0, allProviders.length);
newAllProviders[allProviders.length] = (IIndexFragmentProvider) provider;
allProviders = newAllProviders;
}
Map map = new HashMap();
private boolean providesForProject(IIndexProvider provider, IProject project) {
List key = new ArrayList();
key.add(provider);
key.add(project);
if(!map.containsKey(key)) {
try {
ICProject cproject= CoreModel.getDefault().create(project);
map.put(key, new Boolean(provider.providesFor(cproject)));
} catch(CoreException ce) {
CCorePlugin.log(ce);
map.put(key, Boolean.FALSE);
}
}
return ((Boolean) map.get(key)).booleanValue();
}
public void elementChanged(ElementChangedEvent event) {
try {
if (event.getType() == ElementChangedEvent.POST_CHANGE) {
processDelta(event.getDelta());
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
private void processDelta(ICElementDelta delta) throws CoreException {
int type = delta.getElement().getElementType();
switch (type) {
case ICElement.C_MODEL:
// Loop through the children
ICElementDelta[] children = delta.getAffectedChildren();
for (int i = 0; i < children.length; ++i)
processDelta(children[i]);
break;
case ICElement.C_PROJECT:
// Find the appropriate indexer and pass the delta on
final ICProject cproject = (ICProject)delta.getElement();
switch (delta.getKind()) {
case ICElementDelta.REMOVED:
List toRemove = new ArrayList();
for(Iterator i = map.keySet().iterator(); i.hasNext(); ) {
List key = (List) i.next();
if(key.contains(cproject.getProject())) {
toRemove.add(key);
}
}
for(Iterator i = toRemove.iterator(); i.hasNext(); ) {
map.remove(i.next());
}
break;
}
}
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.provider;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.index.provider.messages"; //$NON-NLS-1$
public static String IndexProviderManager_0;
public static String OfflinePDOMProviderBridge_UnsupportedUsage;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
}
private Messages() {
}
}

View file

@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.provider;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
/**
* Internal singleton map maintained for non-project PDOM objects
*/
class PDOMCache {
private Map/*<File, PDOM>*/ path2pdom; // gives the pdom for a particular path
private static PDOMCache singleton;
private static Object singletonMutex = new Object();
private PDOMCache() {
this.path2pdom = new HashMap();
}
/**
* Returns the instance of the cache
* @return
*/
public static PDOMCache getInstance() {
synchronized(singletonMutex) {
if(singleton == null) {
singleton = new PDOMCache();
}
return singleton;
}
}
/**
* Returns the mapped pdom for the path specified, if such a pdom is not already known about
* then one is created using the location converter specified.
* @param path
* @param converter
* @return a pdom instance
*/
public PDOM getPDOM(IPath path, IIndexLocationConverter converter) {
File file = path.toFile();
synchronized(path2pdom) {
PDOM result = null;
if(path2pdom.containsKey(file)) {
result = (PDOM) path2pdom.get(file);
}
if(result==null) {
try {
result = new PDOM(file, converter);
} catch(CoreException ce) {
CCorePlugin.log(ce);
}
path2pdom.put(file, result);
}
return result;
}
}
}

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.provider;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.index.provider.IPDOMDescriptor;
import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.core.runtime.CoreException;
/**
* Wraps the offline PDOM provider as an IIndexFragmentProvider
*/
public class ReadOnlyPDOMProviderBridge implements IIndexFragmentProvider {
protected IReadOnlyPDOMProvider opp;
public ReadOnlyPDOMProviderBridge(IReadOnlyPDOMProvider opp) {
this.opp = opp;
}
public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) throws CoreException {
IPDOMDescriptor[] descs = opp.getDescriptors(config);
List preresult = new ArrayList();
if(descs!=null) {
for(int i=0; i<descs.length; i++) {
preresult.add(PDOMCache.getInstance().getPDOM(descs[i].getLocation(), descs[i].getIndexLocationConverter()));
}
}
return (IIndexFragment[]) preresult.toArray(new IIndexFragment[preresult.size()]);
}
public boolean providesFor(ICProject cproject) throws CoreException {
return opp.providesFor(cproject);
}
}

View file

@ -0,0 +1,2 @@
IndexProviderManager_0=Ignoring unrecognized implementation of IIndexProvider contributed by {0}
OfflinePDOMProviderBridge_UnsupportedUsage=Unsupported usage of IOfflinePDOMProvider

View file

@ -47,6 +47,7 @@ import org.eclipse.cdt.internal.core.index.IWritableIndexManager;
import org.eclipse.cdt.internal.core.index.IndexChangeEvent;
import org.eclipse.cdt.internal.core.index.IndexFactory;
import org.eclipse.cdt.internal.core.index.IndexerStateEvent;
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
import org.eclipse.cdt.internal.core.pdom.PDOM.IListener;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter;
@ -136,6 +137,7 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
private IElementChangedListener fCModelListener= new CModelListener(this);
private IndexFactory fIndexFactory= new IndexFactory(this);
private IndexProviderManager manager = new IndexProviderManager();
/**
* Serializes creation of new indexer, when acquiring the lock you are
@ -162,6 +164,10 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen
}
}
public IndexProviderManager getIndexProviderManager() {
return manager;
}
public IPDOM getPDOM(ICProject project) throws CoreException {
synchronized (fProjectToPDOM) {
IProject rproject = project.getProject();

View file

@ -8,6 +8,7 @@
* Contributors:
* QNX - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@ -339,21 +340,26 @@ public class PDOMFile implements IIndexFragmentFile {
public static IIndexFragmentFile findFile(PDOM pdom, BTree btree, IIndexFileLocation location, IIndexLocationConverter strategy)
throws CoreException {
Finder finder = new Finder(pdom.getDB(), location, strategy);
btree.accept(finder);
int record = finder.getRecord();
String internalRepresentation= strategy.toInternalFormat(location);
int record= 0;
if(internalRepresentation!=null) {
Finder finder = new Finder(pdom.getDB(), internalRepresentation);
btree.accept(finder);
record= finder.getRecord();
}
return record != 0 ? new PDOMFile(pdom, record) : null;
}
private static class Finder implements IBTreeVisitor {
private final Database db;
private final String rawKey;
private int record;
public Finder(Database db, IIndexFileLocation location, IIndexLocationConverter strategy)
public Finder(Database db, String internalRepresentation)
throws CoreException
{
this.db = db;
this.rawKey = strategy.toInternalFormat(location);
this.rawKey = internalRepresentation;
}
public int compare(int record) throws CoreException {

View file

@ -14,6 +14,7 @@
<complexType>
<choice minOccurs="1" maxOccurs="unbounded">
<element ref="ExportProjectProvider"/>
<element ref="ReadOnlyPDOMProvider"/>
</choice>
<attribute name="point" type="string" use="required">
<annotation>
@ -45,7 +46,9 @@
<element name="ExportProjectProvider">
<annotation>
<documentation>
This element allows contribution of alternate IExportProjectProvider implementations. These can then be referenced by fully qualified class name in the command line tool (see option -pprovider).
&lt;h2&gt;ExportProjectProvider&lt;/h2&gt;
&lt;p&gt;
This subelement of CIndex allows contribution of alternate IExportProjectProvider implementations. These can then be referenced by fully qualified class name in the command line tool (see option -pprovider).
&lt;p&gt;
&lt;b&gt;Invoking the application as a headless application&lt;/b&gt;
@ -53,30 +56,30 @@ This example ant file shows how to invoke the tool headlessly, the same approach
&lt;pre&gt;
&lt;project name=&quot;Generate PDOM&quot; default=&quot;generate&quot;&gt;
&lt;target name=&quot;generate&quot;&gt;
&lt;!-- This script shows how to invoke the default project provider (ExternalExportProjectProvider) --&gt;
&lt;property name=&quot;pprovider&quot; value=&quot;org.eclipse.cdt.core.index.export.ExternalExportProjectProvider&quot;/&gt;
&lt;property name=&quot;target&quot; value=&quot;C:\ExportedPDOMs\acmeSDK_2_5.pdom&quot;/&gt; &lt;!-- Where the output pdom is to go --&gt;
&lt;property name=&quot;source&quot; value=&quot;E:\AcmeSDK\v2.5\inc&quot;/&gt; &lt;!-- e.g. the directory to source content from --&gt;
&lt;property name=&quot;id&quot; value=&quot;com.acme.mysdk.v2.5&quot;/&gt; &lt;!-- the id to store in the generate pdom --&gt;
&lt;property name=&quot;eclipse.home&quot; value=&quot;C:\eclipse&quot;/&gt; &lt;!-- e.g. The eclipse installation to use. This installation must contain CDT 4.0+ plugins --&gt;
&lt;java classname=&quot;org.eclipse.equinox.launcher.Main&quot;&gt;
&lt;classpath&gt;
&lt;fileset dir=&quot;${eclipse.home}/plugins&quot;&gt;
&lt;include name=&quot;*equinox.launcher*.jar&quot;/&gt;
&lt;/fileset&gt;
&lt;/classpath&gt;
&lt;arg value=&quot;-nosplash&quot;/&gt;
&lt;arg value=&quot;-exitdata&quot;/&gt;
&lt;arg value=&quot;-application&quot;/&gt;&lt;arg value=&quot;org.eclipse.cdt.core.GeneratePDOM&quot;/&gt;
&lt;arg value=&quot;-pprovider&quot;/&gt;&lt;arg value=&quot;${pprovider}&quot;/&gt;
&lt;arg value=&quot;-source&quot;/&gt;&lt;arg value=&quot;${source}&quot;/&gt;
&lt;arg value=&quot;-target&quot;/&gt;&lt;arg value=&quot;${target}&quot;/&gt;
&lt;arg value=&quot;-id&quot;/&gt;&lt;arg value=&quot;${id}&quot;/&gt;
&lt;/java&gt;
&lt;/target&gt;
&lt;target name=&quot;generate&quot;&gt;
&lt;!-- This script shows how to invoke the default project provider (ExternalExportProjectProvider) --&gt;
&lt;property name=&quot;pprovider&quot; value=&quot;org.eclipse.cdt.core.index.export.ExternalExportProjectProvider&quot;/&gt;
&lt;property name=&quot;target&quot; value=&quot;C:\ExportedPDOMs\acmeSDK_2_5.pdom&quot;/&gt; &lt;!-- Where the output pdom is to go --&gt;
&lt;property name=&quot;source&quot; value=&quot;E:\AcmeSDK\v2.5\inc&quot;/&gt; &lt;!-- e.g. the directory to source content from --&gt;
&lt;property name=&quot;id&quot; value=&quot;com.acme.mysdk.v2.5&quot;/&gt; &lt;!-- the id to store in the generate pdom --&gt;
&lt;property name=&quot;eclipse.home&quot; value=&quot;C:\eclipse&quot;/&gt; &lt;!-- e.g. The eclipse installation to use. This installation must contain CDT 4.0+ plugins --&gt;
&lt;java classname=&quot;org.eclipse.equinox.launcher.Main&quot;&gt;
&lt;classpath&gt;
&lt;fileset dir=&quot;${eclipse.home}/plugins&quot;&gt;
&lt;include name=&quot;*equinox.launcher*.jar&quot;/&gt;
&lt;/fileset&gt;
&lt;/classpath&gt;
&lt;arg value=&quot;-nosplash&quot;/&gt;
&lt;arg value=&quot;-exitdata&quot;/&gt;
&lt;arg value=&quot;-application&quot;/&gt;&lt;arg value=&quot;org.eclipse.cdt.core.GeneratePDOM&quot;/&gt;
&lt;arg value=&quot;-pprovider&quot;/&gt;&lt;arg value=&quot;${pprovider}&quot;/&gt;
&lt;arg value=&quot;-source&quot;/&gt;&lt;arg value=&quot;${source}&quot;/&gt;
&lt;arg value=&quot;-target&quot;/&gt;&lt;arg value=&quot;${target}&quot;/&gt;
&lt;arg value=&quot;-id&quot;/&gt;&lt;arg value=&quot;${id}&quot;/&gt;
&lt;/java&gt;
&lt;/target&gt;
&lt;/project&gt;
&lt;/pre&gt;
&lt;p&gt;
@ -85,15 +88,15 @@ This example ant file shows how to invoke the tool headlessly, the same approach
Specify &quot;org.eclipse.cdt.core.GeneratePDOM&quot; as the application to launch
&lt;p&gt;
In the Argument tabs provide (for example)
-target C:\ExportedPDOMs\acmeSDK_2_5.pdom -source E:\AcmeSDK\v2.5\inc -include E:\this.h -id com.acme.mysdk.v2.5
-target C:\ExportedPDOMs\acmeSDK_2_5.pdom -source E:\AcmeSDK\v2.5\inc -include E:\this.h -id com.acme.mysdk.v2.5
&lt;p&gt;
</documentation>
</annotation>
<complexType>
<attribute name="class" type="string">
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
the fully qualified name of the IExportProjectProvider implementation to register
</documentation>
<appInfo>
<meta.attribute kind="java"/>
@ -103,6 +106,66 @@ In the Argument tabs provide (for example)
</complexType>
</element>
<element name="ReadOnlyPDOMProvider">
<annotation>
<documentation>
&lt;h2&gt;ReadOnlyPDOMProvider&lt;/h2&gt;
&lt;p&gt;
This subelement of CIndex allows ISVs to contribute read-only prebuilt PDOM files to the CDT Index. The only information needed is the fully qualified class name of an implementatin of org.eclipse.cdt.core.index.IOfflinePDOMProvider. This implementation will be consulted during the eclipse session for the appropriate read-only content to make add to the logical index. The logical index is accessible via the org.eclipse.core.index.IIndex API.
An example of contributing a prebuilt read-only pdom:
&lt;pre&gt;
&lt;CIndex&gt;
&lt;ReadOnlyPDOMProvider class=&quot;com.acme.ide.index.AcmeSDKProvider&quot;/&gt;
&lt;/CIndex&gt;
&lt;/pre&gt;
and the corresponding implementation
&lt;pre&gt;
package com.acme.ide.index.sdk;
import org.eclipse.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.core.index.provider.IPDOMDescriptor;
import org.eclipse.core.index.IIndexLocationConverter;
import org.eclipse.core.index.URIRelativeLocationConverter;
public class AcmeSDKProvider implements IReadOnlyPDOMProvider {
public boolean providesFor(ICProject project) {
// e.g. decide by looking for acme project nature
return AcmeNature.isAcmeProject(project);
}
public IPDOMDescriptor[] getDescriptors(ICProject cproject, ICConfigurationDescription config) {
final IPath sdkBase = AcmeSDKAPI.getSDKBase(cproject, config);
return new IPDOMDescriptor[] { new IPDOMDescriptor() {
public IIndexLocationConverter getIndexLocationConverter() {
return new URIRelativeLocationConverter(URIUtil.toURI(sdkBase));
}
public IPath getLocation() {
IPath path = sdkBase.append(AcmeSDKAPI.getPrebuiltPDOMFilename(config));
return path;
}
}};
}
}
&lt;/pre&gt;
</documentation>
</annotation>
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
the fully qualified name of the IReadOnlyPDOMProvider implementation to register
</documentation>
<appInfo>
<meta.attribute kind="java" basedOn="org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appInfo>
<meta.section type="since"/>

View file

@ -8,19 +8,23 @@
* Contributors:
* IBM Corporation - initial API and implementation
* QNX Software Systems - adapted for use in CDT
* Andrew Ferguson (Symbian)
*******************************************************************************/
package org.eclipse.cdt.ui.browser.typeinfo;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.cdt.core.browser.IQualifiedTypeName;
import org.eclipse.cdt.core.browser.ITypeInfo;
import org.eclipse.cdt.core.browser.ITypeReference;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
public class TypeInfoLabelProvider extends LabelProvider {
@ -112,7 +116,12 @@ public class TypeInfoLabelProvider extends LabelProvider {
ITypeReference ref = typeRef.getResolvedReference();
if (ref != null) {
path = ref.getPath();
if (CoreModel.isValidHeaderUnitName(typeRef.getEnclosingProject().getProject(), path.lastSegment())) {
// IndexTypeInfo may not have an enclosing project
ICProject cproject = typeRef.getEnclosingProject();
IProject project = cproject==null ? null : cproject.getProject();
if (CoreModel.isValidHeaderUnitName(project, path.lastSegment())) {
return HEADER_ICON;
}
}