diff options
12 files changed, 915 insertions, 122 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java new file mode 100644 index 00000000000..a2e41c70274 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * 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.internal.index.tests; + +import java.util.regex.Pattern; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.index.IIndexFileLocation; +import org.eclipse.cdt.core.index.IIndexLinkage; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.internal.core.index.IIndexFragment; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; +import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude; +import org.eclipse.cdt.internal.core.index.IIndexFragmentName; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * An empty index fragment implementation + * @since 4.0.1 + */ +public class EmptyIndexFragment implements IIndexFragment { + public void acquireReadLock() throws InterruptedException {} + + public IIndexFragmentBinding adaptBinding(IBinding binding) + throws CoreException { + return null; + } + + public IIndexFragmentBinding adaptBinding(IIndexFragmentBinding proxy) + throws CoreException { + return null; + } + + public IIndexFragmentBinding findBinding(IASTName astName) throws CoreException { + return null; + } + + public IIndexFragmentBinding[] findBindings(Pattern[] patterns, + boolean isFullyQualified, IndexFilter filter, + IProgressMonitor monitor) throws CoreException { + return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; + } + + public IIndexFragmentBinding[] findBindings(char[][] names, + IndexFilter filter, IProgressMonitor monitor) throws CoreException { + return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; + } + + public IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, + boolean filescope, IndexFilter filter, IProgressMonitor monitor) + throws CoreException { + return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; + } + + public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) + throws CoreException { + return IIndexFragmentInclude.EMPTY_FRAGMENT_INCLUDES_ARRAY; + } + + public IIndexFragmentName[] findNames(IIndexFragmentBinding binding, + int flags) throws CoreException { + return IIndexFragmentName.EMPTY_NAME_ARRAY; + } + + public long getCacheHits() { + return 0; + } + + public long getCacheMisses() { + return 0; + } + + public IIndexFragmentFile getFile(IIndexFileLocation location) + throws CoreException { + return null; + } + + public long getLastWriteAccess() { + return 0; + } + + public IIndexLinkage[] getLinkages() { + return IIndexLinkage.EMPTY_INDEX_LINKAGE_ARRAY; + } + + public String getProperty(String key) throws CoreException { + if(IIndexFragment.PROPERTY_FRAGMENT_ID.equals(key)) { + return "org.eclipse.cdt.internal.core.index.EmptyIndexFragment"; //$NON-NLS-1$ + } + if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(key)) { + return "org.eclipse.cdt.internal.core.index.EmptyIndexFragmentFormat"; //$NON-NLS-1$ + } + if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(key)) { + return "0"; //$NON-NLS-1$ + } + return null; + } + + public void releaseReadLock() {} + public void resetCacheCounters() {} +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java index 0859add59cf..8d2df68f928 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java @@ -11,10 +11,6 @@ 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; @@ -55,6 +51,7 @@ 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.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOMManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; @@ -63,6 +60,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.osgi.service.resolver.VersionRange; /** * Example usage and test for IIndexProvider @@ -76,6 +74,14 @@ public class IndexProviderManagerTest extends IndexTestBase { final static Class DP5= Providers.Dummy5.class; final static Class[] DPS= new Class[] {DP4, DP2, DP1, DP3, DP5}; + /* + * Fictional compatibility ranges for testing + */ + final static VersionRange VERSION_400= new VersionRange("36"); + final static VersionRange VERSION_401= new VersionRange("[36,37]"); + final static VersionRange VERSION_405= new VersionRange("[37,39]"); + final static VersionRange VERSION_502= new VersionRange("[89,91]"); + final CCorePlugin core= CCorePlugin.getDefault(); public IndexProviderManagerTest() { @@ -86,6 +92,11 @@ public class IndexProviderManagerTest extends IndexTestBase { return suite(IndexProviderManagerTest.class); } + protected void tearDown() throws Exception { + IndexProviderManager ipm= ((PDOMManager)CCorePlugin.getIndexManager()).getIndexProviderManager(); + ipm.reset(); ipm.startup(); + } + public void testProvider_SimpleLifeCycle_200958() throws Exception { for(int i=0; i<DPS.length; i++) DPT.reset(DPS[i]); @@ -170,6 +181,136 @@ public class IndexProviderManagerTest extends IndexTestBase { } } + public void testVersioning_IncompatibleIgnored() throws Exception { + IndexProviderManager ipm= ((PDOMManager)CCorePlugin.getIndexManager()).getIndexProviderManager(); + + ICProject cproject = null; + try { + cproject= CProjectHelper.createCCProject("IndexFactoryConfigurationUsageTest", IPDOMManager.ID_NO_INDEXER); + IProject project= cproject.getProject(); + + + MockState mockState = new MockState(cproject); + mockState.setConfig(MockState.REL_V1_ID); + + IIndexProvider provider1= new IIndexFragmentProvider() { + IIndexFragment[] fragments= new IIndexFragment[] { + new MockPDOM("contentID.contentA", "36"), + new MockPDOM("contentID.contentA", "37"), + new MockPDOM("contentID.foo", "90"), + new MockPDOM("contentID.bar", "91"), + new MockPDOM("contentID.baz", "89") + }; + public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) { + return fragments; + } + public boolean providesFor(ICProject project) throws CoreException { + return true; + } + }; + IIndexProvider provider2= new IIndexFragmentProvider() { + IIndexFragment[] fragments= new IIndexFragment[] { + new MockPDOM("contentID.baz", "90"), + new MockPDOM("contentID.contentA", "38"), + }; + public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) { + return fragments; + } + public boolean providesFor(ICProject project) throws CoreException { + return true; + } + }; + + CCorePlugin.getIndexManager().joinIndexer(8000, NPM); // ensure IPM is called only once under test conditions + setExpectedNumberOfLoggedNonOKStatusObjects(3); // foo, bar and baz have no compatible fragments available + + ipm.reset(VERSION_405); ipm.startup(); + ipm.addIndexProvider(provider1); ipm.addIndexProvider(provider2); + + IIndexFragment[] actual = ipm.getProvidedIndexFragments(mockState.getCurrentConfig()); + assertEquals(1, actual.length); + assertFragmentPresent("contentID.contentA", "38", actual); + } finally { + if(cproject!=null) { + cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor()); + } + } + } + + public void testVersioning_NoCompatibleVersionsFound() throws Exception { + IndexProviderManager ipm= ((PDOMManager)CCorePlugin.getIndexManager()).getIndexProviderManager(); + + ICProject cproject = null; + try { + cproject= CProjectHelper.createCCProject("IndexFactoryConfigurationUsageTest", IPDOMManager.ID_NO_INDEXER); + IProject project= cproject.getProject(); + + + MockState mockState = new MockState(cproject); + mockState.setConfig(MockState.REL_V1_ID); + + IIndexProvider provider1= new IIndexFragmentProvider() { + IIndexFragment[] fragments= new IIndexFragment[] { + new MockPDOM("contentID.contentA", "36"), + new MockPDOM("contentID.contentA", "37"), + new MockPDOM("contentID.foo", "90"), + new MockPDOM("contentID.bar", "91"), + new MockPDOM("contentID.baz", "89") + }; + public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) { + return fragments; + } + public boolean providesFor(ICProject project) throws CoreException { + return true; + } + }; + IIndexProvider provider2= new IIndexFragmentProvider() { + IIndexFragment[] fragments= new IIndexFragment[] { + new MockPDOM("contentID.contentA", "41"), + }; + public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) { + return fragments; + } + public boolean providesFor(ICProject project) throws CoreException { + return true; + } + }; + + CCorePlugin.getIndexManager().joinIndexer(8000, NPM); // ensure IPM is called only once under test conditions + setExpectedNumberOfLoggedNonOKStatusObjects(1); // contentA has no compatible fragments available + + ipm.reset(VERSION_502); ipm.startup(); + ipm.addIndexProvider(provider1); ipm.addIndexProvider(provider2); + + IIndexFragment[] actual = ipm.getProvidedIndexFragments(mockState.getCurrentConfig()); + assertEquals(3, actual.length); + assertFragmentPresent("contentID.foo", "90", actual); + assertFragmentPresent("contentID.bar", "91", actual); + assertFragmentPresent("contentID.baz", "89", actual); + } finally { + if(cproject!=null) { + cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor()); + } + } + } + + private void assertFragmentPresent(String id, String version, IIndexFragment[] fragments) throws Exception { + for(int i=0; i<fragments.length; i++) { + IIndexFragment candidate= fragments[i]; + String cid= null, csver= null; + try { + candidate.acquireReadLock(); + cid= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); + csver= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION); + } finally { + candidate.releaseReadLock(); + } + if(id.equals(cid) && version.equals(csver)) + return; + } + fail("Fragment matching (id="+id+",version="+version+") was not present"); + } + public void testIndexFactoryConfigurationUsage() throws Exception { IIndex index; @@ -372,10 +513,9 @@ class MockStateIndexProvider implements IIndexProvider { } class MockStateIndexFragmentProvider extends MockStateIndexProvider implements IIndexFragmentProvider { - IIndexFragment[] fragments; - int[] mcounts; - boolean invert; - + private boolean invert; + final IIndexFragment[] fragments; + public void invert() { invert = !invert; } @@ -384,9 +524,8 @@ class MockStateIndexFragmentProvider extends MockStateIndexProvider implements I 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); + fragments[i] = new MockPDOM("mock.test.index."+System.identityHashCode(this)+"."+i, ""+PDOM.CURRENT_VERSION); } } @@ -401,22 +540,6 @@ class MockStateIndexFragmentProvider extends MockStateIndexProvider implements I 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 { @@ -589,3 +712,29 @@ class MockState { } } +class MockPDOM extends EmptyIndexFragment { + String id; + String version; + + MockPDOM(String id, String version) { + this.id= id; + this.version= version; + } + + public String getProperty(String propertyName) throws CoreException { + if(IIndexFragment.PROPERTY_FRAGMENT_ID.equals(propertyName)) { + return id; + } + if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)) { + return PDOM.FRAGMENT_PROPERTY_VALUE_FORMAT_ID; + } + if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) { + return version; + } + return null; + } + + public String toString() { + return "[Mock index fragment "+id+"."+System.identityHashCode(this)+"]"; + } +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java index e33a81980a3..c79d3bf8407 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java @@ -52,16 +52,33 @@ public interface IIndexFragment { final int FIND_ALL_OCCURENCES = IIndex.FIND_ALL_OCCURENCES; /** - * Property key constant for the fragment ID. The fragment ID should uniquely identify the fragments usage within + * Property key for the fragment ID. The fragment ID should uniquely identify the fragments usage within * a logical index. + * @since 4.0 */ public static final String PROPERTY_FRAGMENT_ID= "org.eclipse.cdt.internal.core.index.fragment.id"; //$NON-NLS-1$ + + /** + * Property key for the fragment format ID. The fragment format ID should uniquely identify a format of an index fragment + * up to version information. That is, as a particular format changes version its ID should remain the same. + * @since 4.0.1 + */ + public static final String PROPERTY_FRAGMENT_FORMAT_ID= "org.eclipse.cdt.internal.core.index.fragment.format.id"; //$NON-NLS-1$ + + /** + * Property key for the fragment format's version. Version numbers belonging to the same format (identified by format ID) should be + * comparable with each other. The version scheme exposed should be compatible with the OSGi framework's + * version scheme - i.e. it should be successfully parsed by org.osgi.framework.Version.parseVersion(String). A null value + * for this property is interpreted as Version(0.0.0) + * @since 4.0.1 + */ + public static final String PROPERTY_FRAGMENT_FORMAT_VERSION= "org.eclipse.cdt.internal.core.index.fragment.format.version"; //$NON-NLS-1$ /** * Returns the file for the given location. May return <code>null</code>, if no such file exists. - * This method may only return files that are actually managed by this fragement. + * This method may only return files that are actually managed by this fragment. * @param location the IIndexFileLocation representing the location of the file - * @return the file for the location + * @return the file for the location, or <code>null</code> if the file is not present in the index * @throws CoreException */ IIndexFragmentFile getFile(IIndexFileLocation location) throws CoreException; @@ -167,11 +184,17 @@ public interface IIndexFragment { /** * Read the named property in this fragment. All fragments are expected to return a non-null value for - * <pre>PROPERTY_FRAGMENT_ID</pre> + * <ul> + * <li>PROPERTY_FRAGMENT_ID</li> + * <li>PROPERTY_FRAGMENT_FORMAT_ID</li> + * <li>PROPERTY_FRAGMENT_FORMAT_VERSION</li> + * </ul> * @param key a case-sensitive identifier for a property, or null * @return the value associated with the key, or null if either no such property is set, or the specified key was null * @throws CoreException * @see IIndexFragment#PROPERTY_FRAGMENT_ID + * @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_ID + * @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_VERSION */ public String getProperty(String propertyName) throws CoreException; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java index aadc4ed83eb..0a134b6dc9e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java @@ -13,11 +13,12 @@ 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.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.index.provider.IIndexProvider; @@ -28,31 +29,70 @@ 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.parser.util.ArrayUtil; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.internal.core.index.IIndexFragment; +import org.eclipse.cdt.internal.core.pdom.PDOM; 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.IStatus; import org.eclipse.core.runtime.Platform; - +import org.eclipse.core.runtime.Status; +import org.eclipse.osgi.service.resolver.VersionRange; +import org.osgi.framework.Version; /** * The IndexProviderManager is responsible for maintaining the set of index * fragments contributed via the CIndex extension point. * <p> * It is an internal class, and is public only for testing purposes. + * @since 4.0 + */ +/* + * For bug 196338, the role of this class was extended. It now has responsibility to + * look at the pool of fragments available depending on their IDs, and select the most appropriate. + * The following rules are applied + * (i) If its not compatible, don't use it + * (ii) If multiple are compatible, pick the latest + * + * A warning is logged if a fragment is contributed which is incompatible, and for which there is + * no compatible equivalent. */ public final class IndexProviderManager implements IElementChangedListener { - public static final String READ_ONLY_PDOM_PROVIDER= "ReadOnlyPDOMProvider"; //$NON-NLS-1$ - private IIndexFragmentProvider[] allProviders= {}; - private Map provisionMap= new HashMap(); + private static final String ELEMENT_RO_PDOMPROVIDER= "ReadOnlyPDOMProvider"; //$NON-NLS-1$ + private static final String ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$ + + private IIndexFragmentProvider[] allProviders; + private Map/*<List,Boolean>*/ provisionMap; + private Set/*<String>*/ compatibleFragmentUnavailable; + private VersionRange pdomVersionRange; public IndexProviderManager() { + reset(); + } + + /** + * <b>Note: This method should not be called by clients for purposes other than testing</b> + */ + public void reset() { + reset(new VersionRange("["+PDOM.MIN_SUPPORTED_VERSION+','+PDOM.CURRENT_VERSION+']')); //$NON-NLS-1$ } + /** + * <b>Note: This method should not be called by clients for purposes other than testing</b> + * @param pdomVersionRange + */ + public void reset(VersionRange pdomVersionRange) { + this.allProviders= new IIndexFragmentProvider[0]; + this.provisionMap= new HashMap(); + this.pdomVersionRange= pdomVersionRange; + this.compatibleFragmentUnavailable= new HashSet(); + } + public void startup() { List providers = new ArrayList(); IExtensionRegistry registry = Platform.getExtensionRegistry(); @@ -63,8 +103,9 @@ public final class IndexProviderManager implements IElementChangedListener { 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[j].createExecutableExtension("class"); //$NON-NLS-1$ + if(ce[j].getName().equals(ELEMENT_RO_PDOMPROVIDER)) { + IIndexProvider provider = (IIndexProvider) ce[j].createExecutableExtension(ATTRIBUTE_CLASS); + if(provider instanceof IReadOnlyPDOMProvider) { provider = new ReadOnlyPDOMProviderBridge((IReadOnlyPDOMProvider)provider); providers.add(provider); @@ -90,29 +131,126 @@ public final class IndexProviderManager implements IElementChangedListener { * registered IIndexProvider objects for the specified project, and * for the current state of the project. * Order in the array is not significant. - * @param project + * @param config * @return the array of IIndexFragment objects for the current state */ public IIndexFragment[] getProvidedIndexFragments(ICConfigurationDescription config) throws CoreException { - List preResult = new ArrayList(); + Map id2fragment = new HashMap(); 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))); + IIndexFragment[] fragments= allProviders[i].getIndexFragments(config); + for(int j=0; j<fragments.length; j++) { + try { + processCandidate(id2fragment, fragments[j]); + } catch(InterruptedException ie) { + CCorePlugin.log(ie); // continue with next candidate + } catch(CoreException ce) { + CCorePlugin.log(ce); // continue with next candidate + } + } } } catch(CoreException ce) { - CCorePlugin.log(ce); + CCorePlugin.log(ce); // move to next provider + } + } + + // Make log entries for any fragments which have no compatible equivalents + List preresult= new ArrayList(); + for(Iterator i=id2fragment.entrySet().iterator(); i.hasNext(); ) { + Map.Entry entry= (Map.Entry) i.next(); + if(entry.getValue()==null) { + String key= (String) entry.getKey(); + if(!compatibleFragmentUnavailable.contains(key)) { + String msg= MessageFormat.format( + Messages.IndexProviderManager_NoCompatibleFragmentsAvailable, + new Object[]{key} + ); + IStatus status= new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, IStatus.WARNING, msg, null); + CCorePlugin.log(status); + compatibleFragmentUnavailable.add(key); + } + } else { + preresult.add(entry.getValue()); } } + return (IIndexFragment[]) preresult.toArray(new IIndexFragment[preresult.size()]); + } + + /** + * Returns the version range supported by the format identified by the specified formatID. + * @param formatID + */ + private VersionRange getCurrentlySupportedVersionRangeForFormat(String formatID) { + /* + * TODO - at the point we support alternate IIndexFragment implementations, this method will need + * to be altered to lookup version ranges for the contributed format via an extension point. + */ + if(!PDOM.FRAGMENT_PROPERTY_VALUE_FORMAT_ID.equals(formatID)) { + throw new IllegalArgumentException("Non-PDOM formats are currently unsupported"); //$NON-NLS-1$ + } + return pdomVersionRange; + } + + /** + * Examines the candidate fragment, adding it to the map (using its fragment id as key) if + * it compatible with the current run-time, and it is better than any existing fragments for + * the same fragment id. + * @param id2fragment + * @param candidate + */ + private void processCandidate(Map id2fragment, IIndexFragment candidate) throws InterruptedException, CoreException { + String cid= null, csver= null, cformatID= null; + try { + candidate.acquireReadLock(); + cid= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); + csver= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION); + cformatID= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID); + } finally { + candidate.releaseReadLock(); + } + assert cid!=null && csver!=null && cformatID!=null; - IIndexFragment[] result = (IIndexFragment[]) preResult.toArray(new IIndexFragment[preResult.size()]); - return result; + Version cver= Version.parseVersion(csver); // illegal argument exception + IIndexFragment existing= (IIndexFragment) id2fragment.get(cid); + + if(getCurrentlySupportedVersionRangeForFormat(cformatID).isIncluded(cver)) { + if(existing != null) { + String esver= null, eformatID= null; + try { + existing.acquireReadLock(); + esver= existing.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION); + eformatID= existing.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID); + } finally { + existing.releaseReadLock(); + } + + if(eformatID.equals(cformatID)) { + Version ever= Version.parseVersion(esver); // illegal argument exception + if(ever.compareTo(cver) < 0) { + id2fragment.put(cid, candidate); + } + } else { + /* + * In future we could allow users to specify + * how format (i.e. PDOM -> custom IIndexFragment implementation) + * changes are coped with. + */ + } + } else { + id2fragment.put(cid, candidate); + } + } else { + if(existing==null) { + id2fragment.put(cid, null); // signifies candidate is unusable + } + } } /** - * This is only public for test purposes + * <b>Note: This method should not be called for purposes other than testing</b> * @param provider */ public void addIndexProvider(IIndexProvider provider) { @@ -131,6 +269,20 @@ public final class IndexProviderManager implements IElementChangedListener { allProviders = newAllProviders; } + /** + * Removes the specified provider by object identity + * <b>Note: This method should not be called for purposes other than testing</b> + * @param provider + */ + public void removeIndexProvider(IIndexProvider provider) { + ArrayUtil.remove(allProviders, provider); + if(allProviders[allProviders.length-1]==null) { + IIndexFragmentProvider[] newAllProviders = new IIndexFragmentProvider[allProviders.length-1]; + System.arraycopy(allProviders, 0, newAllProviders, 0, allProviders.length-1); + allProviders= newAllProviders; + } + } + private boolean providesForProject(IIndexProvider provider, IProject project) { List key = new ArrayList(); key.add(provider); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java index fe1cf9091f3..f448a387f74 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java @@ -15,6 +15,7 @@ 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 IndexProviderManager_NoCompatibleFragmentsAvailable; public static String OfflinePDOMProviderBridge_UnsupportedUsage; public static String PDOMCache_VersionTooOld; static { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java index 382a7a0821b..7b56eef267c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java @@ -12,11 +12,8 @@ package org.eclipse.cdt.internal.core.index.provider; import java.io.File; -import java.text.MessageFormat; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.index.IIndexLocationConverter; @@ -29,17 +26,15 @@ 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 Set/*<File>*/ versionMismatch; - + 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(); - this.versionMismatch = new HashSet(); } - + /** * Returns the instance of the cache * @return @@ -54,48 +49,30 @@ class PDOMCache { } /** - * Returns the mapped pdom for the path specified, if such a pdom is not already known about + * 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 or null if the pdom version was too old + * @return a PDOM instance or null if the PDOM version was too old */ public PDOM getPDOM(IPath path, IIndexLocationConverter converter) { PDOM result= null; File file = path.toFile(); - if(!versionMismatch.contains(file)) { - synchronized(path2pdom) { - if(path2pdom.containsKey(file)) { - result = (PDOM) path2pdom.get(file); - } - if(result==null) { - try { - result = new PDOM(file, converter, LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); - - result.acquireReadLock(); - try { - if(!result.isSupportedVersion()) { - versionMismatch.add(file); - String msg= MessageFormat.format(Messages.PDOMCache_VersionTooOld, new Object[] {file}); - CCorePlugin.log(msg); - return null; - } else { - path2pdom.put(file, result); - } - } finally { - result.releaseReadLock(); - } - } catch(CoreException ce) { - CCorePlugin.log(ce); - } catch(InterruptedException ie) { - CCorePlugin.log(ie); - } + synchronized(path2pdom) { + if(path2pdom.containsKey(file)) { + result = (PDOM) path2pdom.get(file); + } + if(result==null) { + try { + result = new PDOM(file, converter, LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); + path2pdom.put(file, result); + } catch(CoreException ce) { + CCorePlugin.log(ce); } - } } return result; } -} +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties index a0e7f83d6c8..87063621795 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties @@ -11,3 +11,4 @@ IndexProviderManager_0=Ignoring unrecognized implementation of IIndexProvider contributed by {0} OfflinePDOMProviderBridge_UnsupportedUsage=Unsupported usage of IOfflinePDOMProvider PDOMCache_VersionTooOld=External index (PDOM) version is not supported: {0} +IndexProviderManager_NoCompatibleFragmentsAvailable=No compatible index fragment found for fragment id: {0} 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 47fe62dd09c..65df7b909e0 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 @@ -73,47 +73,60 @@ import org.eclipse.core.runtime.Status; public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { protected Database db; + /** + * Identifier for PDOM format + * @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_ID + */ + public static final String FRAGMENT_PROPERTY_VALUE_FORMAT_ID= "org.eclipse.cdt.internal.core.pdom.PDOM"; //$NON-NLS-1$ + public static final int CURRENT_VERSION = 37; public static final int MIN_SUPPORTED_VERSION= 36; public static final int MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX= 37; // to be removed in 4.1 - // 0 - the beginning of it all - // 1 - first change to kick off upgrades - // 2 - added file inclusions - // 3 - added macros and change string implementation - // 4 - added parameters in C++ - // 5 - added types and restructured nodes a bit - // 6 - function style macros. - // 7 - class key - // 8 - enumerators - // 9 - base classes - // 10 - typedefs, types on C++ variables - // 11 - changed how members work - // 12 - one more change for members (is-a list -> has-a list) - // 13 - CV-qualifiers, storage class specifiers, function/method annotations - // 14 - added timestamps for files (bug 149571) - // 15 - fixed offsets for pointer types and qualifier types and PDOMCPPVariable (bug 160540). - // 16 - have PDOMCPPField store type information, and PDOMCPPNamespaceAlias store what it is aliasing - // 17 - use single linked list for names in file, adds a link to enclosing definition name. - // 18 - distinction between c-unions and c-structs. - // 19 - alter representation of paths in the pdom (162172) - // 20 - add pointer to member types, array types, return types for functions - // 21 - change representation of paths in the pdom (167549) - // 22 - fix inheritance relations (167396) - // 23 - types on c-variables, return types on c-functions - // 24 - file local scopes (161216) - // 25 - change ordering of bindings (175275) - // 26 - add properties storage - // 27 - templates: classes, functions, limited nesting support, only template type parameters - // 28 - templates: class instance/specialization base classes - // 29 - includes: fixed modeling of unresolved includes (180159) - // 30 - templates: method/constructor templates, typedef specializations - // 31 - macros: added file locations - // 32 - support stand-alone function types (181936) - // 33 - templates: constructor instances - // 34 - fix for base classes represented by qualified names (183843) - // 35 - add scanner configuration hash-code (62366) - // 36 - changed chunk size back to 4K (184892) - // 37 - added index for nested bindings (189811), compatible with version 36. + + /* + * PDOM internal format history + * + * #x# = the version was used in an official release + * + * 0 - the beginning of it all + * 1 - first change to kick off upgrades + * 2 - added file inclusions + * 3 - added macros and change string implementation + * 4 - added parameters in C++ + * 5 - added types and restructured nodes a bit + * 6 - function style macros + * # 7#- class key - <<CDT 3.1>> + * 8 - enumerators + * 9 - base classes + * 10 - typedefs, types on C++ variables + * #11#- changed how members work - <<CDT 3.1.1>>, <<CDT 3.1.2>> + * 12 - one more change for members (is-a list -> has-a list) + * 13 - CV-qualifiers, storage class specifiers, function/method annotations + * 14 - added timestamps for files (bug 149571) + * 15 - fixed offsets for pointer types and qualifier types and PDOMCPPVariable (bug 160540). + * 16 - have PDOMCPPField store type information, and PDOMCPPNamespaceAlias store what it is aliasing + * 17 - use single linked list for names in file, adds a link to enclosing definition name. + * 18 - distinction between c-unions and c-structs. + * 19 - alter representation of paths in the pdom (162172) + * 20 - add pointer to member types, array types, return types for functions + * 21 - change representation of paths in the pdom (167549) + * 22 - fix inheritance relations (167396) + * 23 - types on c-variables, return types on c-functions + * 24 - file local scopes (161216) + * 25 - change ordering of bindings (175275) + * 26 - add properties storage + * 27 - templates: classes, functions, limited nesting support, only template type parameters + * 28 - templates: class instance/specialization base classes + * 29 - includes: fixed modeling of unresolved includes (180159) + * 30 - templates: method/constructor templates, typedef specializations + * 31 - macros: added file locations + * 32 - support stand-alone function types (181936) + * 33 - templates: constructor instances + * 34 - fix for base classes represented by qualified names (183843) + * 35 - add scanner configuration hash-code (62366) + * #36#- changed chunk size back to 4K (184892) - <<CDT 4.0>> + * #37#- added index for nested bindings (189811), compatible with version 36 - <<CDT 4.0.1>> + */ public static final int LINKAGES = Database.DATA_AREA; public static final int FILE_INDEX = Database.DATA_AREA + 4; @@ -760,6 +773,12 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM { } public String getProperty(String propertyName) throws CoreException { + if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)) { + return FRAGMENT_PROPERTY_VALUE_FORMAT_ID; + } + if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) { + return ""+db.getVersion(); //$NON-NLS-1$ + } return new DBProperties(db, PROPERTIES).getProperty(propertyName); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java index 158c70591d2..508bde45d3b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java @@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexLocationConverter; +import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IWritableIndexFragment; import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation; @@ -88,11 +89,18 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment { return result; } + /* + * (non-Javadoc) + * @see org.eclipse.cdt.internal.core.index.IWritableIndexFragment#setProperty(java.lang.String, java.lang.String) + */ public void setProperty(String propertyName, String value) throws CoreException { + if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName) + || IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) { + throw new IllegalArgumentException("Property "+value+" may not be written to"); //$NON-NLS-1$ //$NON-NLS-2$ + } new DBProperties(db, PROPERTIES).setProperty(propertyName, value); } - /** * Use the specified location converter to update each internal representation of a file location. * The file index is rebuilt with the new representations. Individual PDOMFile records are unmoved so diff --git a/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning.html b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning.html new file mode 100644 index 00000000000..dc319b7243c --- /dev/null +++ b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning.html @@ -0,0 +1,350 @@ +<html xmlns:v="urn:schemas-microsoft-com:vml" +xmlns:o="urn:schemas-microsoft-com:office:office" +xmlns:w="urn:schemas-microsoft-com:office:word" +xmlns="http://www.w3.org/TR/REC-html40"> + +<head> +<meta http-equiv=Content-Type content="text/html; charset=windows-1252"> +<meta name=ProgId content=Word.Document> +<meta name=Generator content="Microsoft Word 10"> +<meta name=Originator content="Microsoft Word 10"> +<link rel=File-List href="prebuiltVersioning_files/filelist.xml"> +<link rel=Edit-Time-Data href="prebuiltVersioning_files/editdata.mso"> +<!--[if !mso]> +<style> +v\:* {behavior:url(#default#VML);} +o\:* {behavior:url(#default#VML);} +w\:* {behavior:url(#default#VML);} +.shape {behavior:url(#default#VML);} +</style> +<![endif]--> +<title>Versioning pre-built indexes</title> +<!--[if gte mso 9]><xml> + <w:WordDocument> + <w:Zoom>80</w:Zoom> + <w:SpellingState>Clean</w:SpellingState> + <w:GrammarState>Clean</w:GrammarState> + <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> + </w:WordDocument> +</xml><![endif]--> +<style> +<!-- + /* Style Definitions */ + p.MsoNormal, li.MsoNormal, div.MsoNormal + {mso-style-parent:""; + margin:0cm; + margin-bottom:.0001pt; + mso-pagination:widow-orphan; + font-size:12.0pt; + font-family:"Times New Roman"; + mso-fareast-font-family:"Times New Roman";} +h1 + {mso-style-next:Normal; + margin-top:12.0pt; + margin-right:0cm; + margin-bottom:3.0pt; + margin-left:0cm; + mso-pagination:widow-orphan; + page-break-after:avoid; + mso-outline-level:1; + font-size:16.0pt; + font-family:Arial; + mso-font-kerning:16.0pt;} +h2 + {mso-style-next:Normal; + margin-top:12.0pt; + margin-right:0cm; + margin-bottom:3.0pt; + margin-left:0cm; + mso-pagination:widow-orphan; + page-break-after:avoid; + mso-outline-level:2; + font-size:14.0pt; + font-family:Arial; + font-style:italic;} +a:link, span.MsoHyperlink + {color:blue; + text-decoration:underline; + text-underline:single;} +a:visited, span.MsoHyperlinkFollowed + {color:#606420; + text-decoration:underline; + text-underline:single;} +span.SpellE + {mso-style-name:""; + mso-spl-e:yes;} +span.GramE + {mso-style-name:""; + mso-gram-e:yes;} +@page Section1 + {size:612.0pt 792.0pt; + margin:72.0pt 90.0pt 72.0pt 90.0pt; + mso-header-margin:35.4pt; + mso-footer-margin:35.4pt; + mso-paper-source:0;} +div.Section1 + {page:Section1;} +--> +</style> +<!--[if gte mso 10]> +<style> + /* Style Definitions */ + table.MsoNormalTable + {mso-style-name:"Table Normal"; + mso-tstyle-rowband-size:0; + mso-tstyle-colband-size:0; + mso-style-noshow:yes; + mso-style-parent:""; + mso-padding-alt:0cm 5.4pt 0cm 5.4pt; + mso-para-margin:0cm; + mso-para-margin-bottom:.0001pt; + mso-pagination:widow-orphan; + font-size:10.0pt; + font-family:"Times New Roman";} +</style> +<![endif]--><!--[if gte mso 9]><xml> + <o:shapedefaults v:ext="edit" spidmax="3074"/> +</xml><![endif]--><!--[if gte mso 9]><xml> + <o:shapelayout v:ext="edit"> + <o:idmap v:ext="edit" data="1"/> + </o:shapelayout></xml><![endif]--> +</head> + +<body lang=EN-GB link=blue vlink="#606420" style='tab-interval:36.0pt'> + +<div class=Section1> + +<h1 align=center style='text-align:center'>Versioning of pre-built indexes</h1> + +<p class=MsoNormal> </p> + +<p class=MsoNormal style='text-align:justify'>In CDT 4.0.1 support for +versioning of pre-built indexes was added. This means that if you release +pre-built indexes for the same content (for example, the same SDK version), but +they were built with different versions of CDT, then a suitable version will +now be used automatically. The previous behaviour assumed only one format +version of any particular content would be provided via the <span class=SpellE>CIndex</span> +extension point.</p> + +<p class=MsoNormal style='text-align:justify'> </p> + +<p class=MsoNormal style='text-align:justify'>It is important to distinguish +between two versions: the content version and the index format version. A +content version refers to the version of the source code being indexed +independent of how it is represented in the index e.g. SDK v1.0 and SDK v1.2. +The index format version is the version of the internal representation of the +index. This document is about coping with the latter.</p> + +<p class=MsoNormal style='text-align:justify'> </p> + +<p class=MsoNormal style='text-align:justify'>Our versioning policy for index +formats is that they should be compatible within major (yearly) release +versions. That is if you build an index using CDT 4.0.X it should work with CDT +4.0.Y. This policy should mean that ISVs do not need to worry about index +format versioning, but this page describes how to handle it should it be +necessary (for example <span class=SpellE>bugzilla</span> 189811).Each +pre-built index carries a string ID which identifies it uniquely within a +logical index - i.e. it identifies the content (<span class=SpellE>e.g</span> <span +class=SpellE>MySDK</span> v1.2). When multiple pre-built indexes are provided +with the same ID, the particular one for use is disambiguated automatically by +CDT which chooses the most recent compatible version.</p> + +<h2><span style='font-style:normal;mso-bidi-font-style:italic'>Compatibility +Table<o:p></o:p></span></h2> + +<p class=MsoNormal> </p> + +<p class=MsoNormal style='text-align:justify'>This table shows the +compatibility of pre-built indexes built with one version of CDT and used with +another. “Built With” is the vertical axis.</p> + +<p class=MsoNormal> </p> + +<table class=MsoNormalTable border=0 cellspacing=0 cellpadding=0 width=516 + style='width:387.0pt;margin-left:23.4pt;border-collapse:collapse;mso-padding-alt: + 0cm 0cm 0cm 0cm'> + <tr style='mso-yfti-irow:0'> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal><b><span style='font-size:8.0pt'>Built With \ Use With</span></b></p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>CDT 4.0</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>CDT 4.0.1</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>CDT Next**</p> + </td> + <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal><b> </b></p> + </td> + </tr> + <tr style='mso-yfti-irow:1'> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>CDT 4.0</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>Yes*</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>Yes*</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>No</p> + </td> + <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + </tr> + <tr style='mso-yfti-irow:2'> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>CDT 4.0.1</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>Yes*</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>Yes</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>No</p> + </td> + <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + </tr> + <tr style='mso-yfti-irow:3'> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>CDT Next**</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>No</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>No</p> + </td> + <td width=118 valign=top style='width:88.55pt;border-top:none;border-left: + none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal>Yes</p> + </td> + <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt; + background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + </tr> + <tr style='mso-yfti-irow:4;mso-yfti-lastrow:yes'> + <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt; + background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + <td width=44 valign=top style='width:32.8pt;background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'> + <p class=MsoNormal> </p> + </td> + </tr> +</table> + +<p class=MsoNormal> </p> + +<p class=MsoNormal style='text-align:justify'>Note that even though in the PDOM +format has its own internal versioning scheme, consumers of official CDT +releases need only be aware of compatibility constraints between these +releases.</p> + +<p class=MsoNormal> </p> + +<p class=MsoNormal><span style='font-size:8.0pt'>* <span class=GramE>with</span> +performance issues in very large projects. See <a +href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=189811">https://bugs.eclipse.org/bugs/show_bug.cgi?id=189811</a></span></p> + +<p class=MsoNormal><span class=GramE><span style='font-size:8.0pt'>** represents +the next major release of CDT.</span></span><span style='font-size:8.0pt'> It +is assumed significant changes to the PDOM database will occur.<o:p></o:p></span></p> + +<p class=MsoNormal><span style='font-size:8.0pt'><o:p> </o:p></span></p> + +<h2><span style='font-style:normal;mso-bidi-font-style:italic'>Example scenario<o:p></o:p></span></h2> + +<p class=MsoNormal><o:p> </o:p></p> + +<span style='font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family: +"Times New Roman";mso-ansi-language:EN-GB;mso-fareast-language:EN-GB; +mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'> +</span> + +<p class=MsoNormal align=center style='text-align:center'> </p> + +<p class=MsoNormal align=center style='text-align:center'><img border=0 +width=421 height=653 id="_x0000_i1025" +src="prebuiltVersioning_files/image001.jpg"></p> + +<p class=MsoNormal align=center style='text-align:center'> </p> + +<p class=MsoNormal style='text-align:justify'>The figure above shows an example +scenario where pre-built indexes are contributed by multiple <span class=GramE>plug-ins</span>. +The same content is contributed in multiple index format versions. The versions +selected for use by each version of CDT are highlighted in <span class=SpellE>gray</span>.</p> + +<p class=MsoNormal style='text-align:justify'><o:p> </o:p></p> + +<p class=MsoNormal style='text-align:justify'><o:p> </o:p></p> + +<p class=MsoNormal style='text-align:justify'><o:p> </o:p></p> + +<p class=MsoNormal><span style='font-size:10.0pt'>Versioning <span +class=SpellE>Bugzilla</span>: <a +href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=196338">https://bugs.eclipse.org/bugs/show_bug.cgi?id=196338</a></span></p> + +<p class=MsoNormal style='text-align:justify'><o:p> </o:p></p> + +</div> + +</body> + +</html> diff --git a/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning_files/image001.jpg b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning_files/image001.jpg Binary files differnew file mode 100644 index 00000000000..0acc405f981 --- /dev/null +++ b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning_files/image001.jpg diff --git a/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml b/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml index c81a1aaac09..ae30603660c 100644 --- a/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml +++ b/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml @@ -6,6 +6,7 @@ <toc label="Guide"> <topic label="CDT DOM" href="guide/dom/index.html"> <topic label="Prebuilt Indexes in CDT 4.0" href="guide/dom/index/prebuiltIndexes.html"/> + <topic label="Versioning of Prebuilt Indexes" href="guide/dom/index/prebuiltVersioning.html"/> </topic> <topic label="Managed Build System Extensibility Document" href="guide/mbs/extensibilityGuide/Managed_Build_Extensibility.html"/> <topic label="Project Template Engine" href="guide/projectTemplateEngine/index.html"/> |