1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

178998: apply fix for controlled behaviour on prebuilt pdom version mismatch

This commit is contained in:
Andrew Ferguson 2007-03-27 11:32:21 +00:00
parent bcb116eda7
commit 6ddba293ac
7 changed files with 163 additions and 39 deletions

View file

@ -28,11 +28,13 @@ import org.eclipse.cdt.core.index.provider.IPDOMDescriptor;
import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider; import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager; import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
import org.eclipse.cdt.internal.core.index.provider.ReadOnlyPDOMProviderBridge; import org.eclipse.cdt.internal.core.index.provider.ReadOnlyPDOMProviderBridge;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
@ -212,4 +214,70 @@ public class PDOMProviderTests extends PDOMTestBase {
assertEquals(3, bindings.length); assertEquals(3, bindings.length);
} }
} }
/*
* see bugzilla 178998
*/
public void testVersionMismatchOfExternalPDOM() 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);
ResourceContainerRelativeLocationConverter cvr= new ResourceContainerRelativeLocationConverter(cproject.getProject());
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, tempPDOM, cvr);
CProjectHelper.delete(cproject);
// mimic a pdom with superceded version
WritablePDOM wpdom= new WritablePDOM(tempPDOM, cvr);
wpdom.acquireWriteLock();
try {
wpdom.getDB().setVersion(1);
} finally {
wpdom.releaseWriteLock();
wpdom.close();
}
}
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);
}
}
));
setExpectedNumberOfLoggedNonOKStatusObjects(1); // (this applies to the entire test duration)
for(int i=0; i<3; i++) {
// try several times in order to test the status is logged only once
ICProjectDescription pd= CCorePlugin.getDefault().getProjectDescription(cproject2.getProject(), false);
assertEquals(0, ipm.getProvidedIndexFragments(pd.getActiveConfiguration()).length);
}
}
} }

View file

@ -38,7 +38,7 @@ public class BaseTestCase extends TestCase {
private boolean fExpectFailure= false; private boolean fExpectFailure= false;
private int fBugnumber= 0; private int fBugnumber= 0;
private boolean allowsCoreLogErrors= false; private int fExpectedLoggedNonOK= 0;
public BaseTestCase() { public BaseTestCase() {
super(); super();
@ -111,9 +111,11 @@ public class BaseTestCase extends TestCase {
try { try {
super.runBare(); super.runBare();
if(!allowsCoreLogErrors && !statusLog.isEmpty()) { if(statusLog.size()!=fExpectedLoggedNonOK) {
StringBuffer msg= new StringBuffer("Non-OK Status was logged to CCorePlugin: \n"); StringBuffer msg= new StringBuffer("Expected number ("+fExpectedLoggedNonOK+") of ");
msg.append("non-OK status objects differs from actual ("+statusLog.size()+").\n");
Throwable cause= null; Throwable cause= null;
if(!statusLog.isEmpty()) {
for(Iterator i= statusLog.iterator(); i.hasNext(); ) { for(Iterator i= statusLog.iterator(); i.hasNext(); ) {
IStatus status= (IStatus) i.next(); IStatus status= (IStatus) i.next();
if(cause==null) { if(cause==null) {
@ -122,6 +124,7 @@ public class BaseTestCase extends TestCase {
Throwable t= status.getException(); Throwable t= status.getException();
msg.append("\t"+status.getMessage()+" "+(t!=null?t.getMessage():"")+"\n"); msg.append("\t"+status.getMessage()+" "+(t!=null?t.getMessage():"")+"\n");
} }
}
AssertionFailedError afe= new AssertionFailedError(msg.toString()); AssertionFailedError afe= new AssertionFailedError(msg.toString());
afe.initCause(cause); afe.initCause(cause);
throw afe; throw afe;
@ -168,10 +171,12 @@ public class BaseTestCase extends TestCase {
/** /**
* The last value passed to this method in the body of a testXXX method * The last value passed to this method in the body of a testXXX method
* will be used to determine whether or not the presence of non-OK status objects * will be used to determine whether or not the presence of non-OK status objects
* in the log should fail the test. * in the log should fail the test. If the logged number of non-OK status objects
* differs from the last value passed, the test is failed. If this method is not called
* at all, the expected number defaults to zero.
* @param value * @param value
*/ */
public void setAllowCCorePluginLogErrors(boolean value) { public void setExpectedNumberOfLoggedNonOKStatusObjects(int count) {
allowsCoreLogErrors= value; fExpectedLoggedNonOK= count;
} }
} }

View file

@ -67,7 +67,7 @@ public class IndexFactory {
ICProject cproject = (ICProject) iter.next(); ICProject cproject = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject); IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
if (pdom != null) { if (pdom != null) {
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom); safeAddFragment(fragments, pdom);
if(!skipProvided) { if(!skipProvided) {
ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(cproject.getProject(), false); ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(cproject.getProject(), false);
@ -75,7 +75,7 @@ public class IndexFactory {
ICConfigurationDescription activeCfg= pd.getActiveConfiguration(); ICConfigurationDescription activeCfg= pd.getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg); IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) { for(int i=0; i<pFragments.length; i++) {
fragments.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]); safeAddFragment(fragments, pFragments[i]);
} }
} }
} }
@ -95,16 +95,14 @@ public class IndexFactory {
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) { for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
ICProject cproject = (ICProject) iter.next(); ICProject cproject = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject); IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
if (pdom != null) { safeAddFragment(fragments, pdom);
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
}
if(!skipProvided) { if(!skipProvided) {
ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(cproject.getProject(), false); ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(cproject.getProject(), false);
if(pd!=null) { if(pd!=null) {
ICConfigurationDescription activeCfg= pd.getActiveConfiguration(); ICConfigurationDescription activeCfg= pd.getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg); IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) { for(int i=0; i<pFragments.length; i++) {
fragments.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]); safeAddFragment(fragments, pFragments[i]);
} }
} }
} }
@ -186,13 +184,13 @@ public class IndexFactory {
ICProject p = (ICProject) iter.next(); ICProject p = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(p); IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(p);
if (pdom != null) { if (pdom != null) {
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom); safeAddFragment(fragments, (IIndexFragment) pdom);
ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(p.getProject(), false); ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(p.getProject(), false);
if(pd!=null) { if(pd!=null) {
ICConfigurationDescription activeCfg= pd.getActiveConfiguration(); ICConfigurationDescription activeCfg= pd.getActiveConfiguration();
IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg); IIndexFragment[] pFragments= m.getProvidedIndexFragments(activeCfg);
for(int i=0; i<pFragments.length; i++) { for(int i=0; i<pFragments.length; i++) {
readOnlyFrag.put(pFragments[i].getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pFragments[i]); safeAddFragment(readOnlyFrag, pFragments[i]);
} }
} }
} }
@ -203,10 +201,7 @@ public class IndexFactory {
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) { for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
ICProject cproject = (ICProject) iter.next(); ICProject cproject = (ICProject) iter.next();
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject); safeAddFragment(readOnlyFrag, (IIndexFragment) fPDOMManager.getPDOM(cproject));
if (pdom != null) {
readOnlyFrag.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
}
} }
if (fragments.isEmpty()) { if (fragments.isEmpty()) {
@ -219,4 +214,29 @@ public class IndexFactory {
return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.size()]), return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.size()]),
(IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) ); (IIndexFragment[]) roPdoms.toArray(new IIndexFragment[roPdoms.size()]) );
} }
/**
* Add an entry for the specified fragment. This copes with problems occuring when reading
* the fragment ID.
* @param id2fragment the map to add the entry to
* @param fragment the fragment or null (which will result in no action)
*/
private void safeAddFragment(Map id2fragment, IIndexFragment fragment) {
if(fragment!=null) {
try {
fragment.acquireReadLock();
try {
String id= fragment.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID);
id2fragment.put(id, fragment);
} finally {
fragment.releaseReadLock();
}
} catch(CoreException ce) {
CCorePlugin.log(ce);
} catch(InterruptedException ie) {
CCorePlugin.log(ie);
}
}
}
} }

View file

@ -16,6 +16,7 @@ public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.index.provider.messages"; //$NON-NLS-1$ 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_0;
public static String OfflinePDOMProviderBridge_UnsupportedUsage; public static String OfflinePDOMProviderBridge_UnsupportedUsage;
public static String PDOMCache_VersionTooOld;
static { static {
// initialize resource bundle // initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class); NLS.initializeMessages(BUNDLE_NAME, Messages.class);

View file

@ -11,8 +11,11 @@
package org.eclipse.cdt.internal.core.index.provider; package org.eclipse.cdt.internal.core.index.provider;
import java.io.File; import java.io.File;
import java.text.MessageFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IIndexLocationConverter; import org.eclipse.cdt.core.index.IIndexLocationConverter;
@ -25,12 +28,14 @@ import org.eclipse.core.runtime.IPath;
*/ */
class PDOMCache { class PDOMCache {
private Map/*<File, PDOM>*/ path2pdom; // gives the pdom for a particular path private Map/*<File, PDOM>*/ path2pdom; // gives the pdom for a particular path
private Set/*<File>*/ versionMismatch;
private static PDOMCache singleton; private static PDOMCache singleton;
private static Object singletonMutex = new Object(); private static Object singletonMutex = new Object();
private PDOMCache() { private PDOMCache() {
this.path2pdom = new HashMap(); this.path2pdom = new HashMap();
this.versionMismatch = new HashSet();
} }
/** /**
@ -51,24 +56,44 @@ class PDOMCache {
* then one is created using the location converter specified. * then one is created using the location converter specified.
* @param path * @param path
* @param converter * @param converter
* @return a pdom instance * @return a pdom instance or null if the pdom version was too old
*/ */
public PDOM getPDOM(IPath path, IIndexLocationConverter converter) { public PDOM getPDOM(IPath path, IIndexLocationConverter converter) {
PDOM result= null;
File file = path.toFile(); File file = path.toFile();
if(!versionMismatch.contains(file)) {
synchronized(path2pdom) { synchronized(path2pdom) {
PDOM result = null;
if(path2pdom.containsKey(file)) { if(path2pdom.containsKey(file)) {
result = (PDOM) path2pdom.get(file); result = (PDOM) path2pdom.get(file);
} }
if(result==null) { if(result==null) {
try { try {
result = new PDOM(file, converter); result = new PDOM(file, converter);
} catch(CoreException ce) {
CCorePlugin.log(ce); result.acquireReadLock();
} try {
if(result.versionMismatch()) {
versionMismatch.add(file);
String msg= MessageFormat.format(Messages.PDOMCache_VersionTooOld, new Object[] {file});
CCorePlugin.log(msg);
return null;
} else {
path2pdom.put(file, result); path2pdom.put(file, result);
} }
} finally {
result.releaseReadLock();
}
} catch(CoreException ce) {
CCorePlugin.log(ce);
} catch(InterruptedException ie) {
CCorePlugin.log(ie);
}
}
}
}
return result; return result;
} }
}
} }

View file

@ -18,6 +18,7 @@ import org.eclipse.cdt.core.index.provider.IReadOnlyPDOMProvider;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
@ -37,7 +38,10 @@ public class ReadOnlyPDOMProviderBridge implements IIndexFragmentProvider {
if(descs!=null) { if(descs!=null) {
for(int i=0; i<descs.length; i++) { for(int i=0; i<descs.length; i++) {
preresult.add(PDOMCache.getInstance().getPDOM(descs[i].getLocation(), descs[i].getIndexLocationConverter())); PDOM pdom= PDOMCache.getInstance().getPDOM(descs[i].getLocation(), descs[i].getIndexLocationConverter());
if(pdom!=null) {
preresult.add(pdom);
}
} }
} }

View file

@ -1,2 +1,3 @@
IndexProviderManager_0=Ignoring unrecognized implementation of IIndexProvider contributed by {0} IndexProviderManager_0=Ignoring unrecognized implementation of IIndexProvider contributed by {0}
OfflinePDOMProviderBridge_UnsupportedUsage=Unsupported usage of IOfflinePDOMProvider OfflinePDOMProviderBridge_UnsupportedUsage=Unsupported usage of IOfflinePDOMProvider
PDOMCache_VersionTooOld=External index (PDOM) version is not supported: {0}