mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
178998: apply fix for controlled behaviour on prebuilt pdom version mismatch
This commit is contained in:
parent
bcb116eda7
commit
6ddba293ac
7 changed files with 163 additions and 39 deletions
|
@ -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.model.ICProject;
|
||||
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.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.cdt.internal.core.pdom.WritablePDOM;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
@ -212,4 +214,70 @@ public class PDOMProviderTests extends PDOMTestBase {
|
|||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class BaseTestCase extends TestCase {
|
|||
|
||||
private boolean fExpectFailure= false;
|
||||
private int fBugnumber= 0;
|
||||
private boolean allowsCoreLogErrors= false;
|
||||
private int fExpectedLoggedNonOK= 0;
|
||||
|
||||
public BaseTestCase() {
|
||||
super();
|
||||
|
@ -111,16 +111,19 @@ public class BaseTestCase extends TestCase {
|
|||
try {
|
||||
super.runBare();
|
||||
|
||||
if(!allowsCoreLogErrors && !statusLog.isEmpty()) {
|
||||
StringBuffer msg= new StringBuffer("Non-OK Status was logged to CCorePlugin: \n");
|
||||
if(statusLog.size()!=fExpectedLoggedNonOK) {
|
||||
StringBuffer msg= new StringBuffer("Expected number ("+fExpectedLoggedNonOK+") of ");
|
||||
msg.append("non-OK status objects differs from actual ("+statusLog.size()+").\n");
|
||||
Throwable cause= null;
|
||||
for(Iterator i= statusLog.iterator(); i.hasNext(); ) {
|
||||
IStatus status= (IStatus) i.next();
|
||||
if(cause==null) {
|
||||
cause= status.getException();
|
||||
if(!statusLog.isEmpty()) {
|
||||
for(Iterator i= statusLog.iterator(); i.hasNext(); ) {
|
||||
IStatus status= (IStatus) i.next();
|
||||
if(cause==null) {
|
||||
cause= status.getException();
|
||||
}
|
||||
Throwable t= status.getException();
|
||||
msg.append("\t"+status.getMessage()+" "+(t!=null?t.getMessage():"")+"\n");
|
||||
}
|
||||
Throwable t= status.getException();
|
||||
msg.append("\t"+status.getMessage()+" "+(t!=null?t.getMessage():"")+"\n");
|
||||
}
|
||||
AssertionFailedError afe= new AssertionFailedError(msg.toString());
|
||||
afe.initCause(cause);
|
||||
|
@ -168,10 +171,12 @@ public class BaseTestCase extends TestCase {
|
|||
/**
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
public void setAllowCCorePluginLogErrors(boolean value) {
|
||||
allowsCoreLogErrors= value;
|
||||
public void setExpectedNumberOfLoggedNonOKStatusObjects(int count) {
|
||||
fExpectedLoggedNonOK= count;
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ public class IndexFactory {
|
|||
ICProject cproject = (ICProject) iter.next();
|
||||
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
|
||||
if (pdom != null) {
|
||||
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
|
||||
safeAddFragment(fragments, pdom);
|
||||
|
||||
if(!skipProvided) {
|
||||
ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(cproject.getProject(), false);
|
||||
|
@ -75,7 +75,7 @@ public class IndexFactory {
|
|||
ICConfigurationDescription activeCfg= pd.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]);
|
||||
safeAddFragment(fragments, pFragments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,16 +95,14 @@ public class IndexFactory {
|
|||
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
|
||||
ICProject cproject = (ICProject) iter.next();
|
||||
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
|
||||
if (pdom != null) {
|
||||
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
|
||||
}
|
||||
safeAddFragment(fragments, pdom);
|
||||
if(!skipProvided) {
|
||||
ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(cproject.getProject(), false);
|
||||
if(pd!=null) {
|
||||
ICConfigurationDescription activeCfg= pd.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]);
|
||||
safeAddFragment(fragments, pFragments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,13 +184,13 @@ public class IndexFactory {
|
|||
ICProject p = (ICProject) iter.next();
|
||||
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(p);
|
||||
if (pdom != null) {
|
||||
fragments.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
|
||||
safeAddFragment(fragments, (IIndexFragment) pdom);
|
||||
ICProjectDescription pd= CoreModel.getDefault().getProjectDescription(p.getProject(), false);
|
||||
if(pd!=null) {
|
||||
ICConfigurationDescription activeCfg= pd.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]);
|
||||
safeAddFragment(readOnlyFrag, pFragments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,10 +201,7 @@ public class IndexFactory {
|
|||
|
||||
for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) {
|
||||
ICProject cproject = (ICProject) iter.next();
|
||||
IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject);
|
||||
if (pdom != null) {
|
||||
readOnlyFrag.put(pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID), pdom);
|
||||
}
|
||||
safeAddFragment(readOnlyFrag, (IIndexFragment) fPDOMManager.getPDOM(cproject));
|
||||
}
|
||||
|
||||
if (fragments.isEmpty()) {
|
||||
|
@ -219,4 +214,29 @@ public class IndexFactory {
|
|||
return new WritableCIndex((IWritableIndexFragment[]) pdoms.toArray(new IWritableIndexFragment[pdoms.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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$
|
||||
public static String IndexProviderManager_0;
|
||||
public static String OfflinePDOMProviderBridge_UnsupportedUsage;
|
||||
public static String PDOMCache_VersionTooOld;
|
||||
static {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
|
||||
|
|
|
@ -11,8 +11,11 @@
|
|||
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;
|
||||
|
@ -25,12 +28,14 @@ import org.eclipse.core.runtime.IPath;
|
|||
*/
|
||||
class PDOMCache {
|
||||
private Map/*<File, PDOM>*/ path2pdom; // gives the pdom for a particular path
|
||||
|
||||
private Set/*<File>*/ versionMismatch;
|
||||
|
||||
private static PDOMCache singleton;
|
||||
private static Object singletonMutex = new Object();
|
||||
|
||||
private PDOMCache() {
|
||||
this.path2pdom = new HashMap();
|
||||
this.versionMismatch = new HashSet();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,24 +56,44 @@ class PDOMCache {
|
|||
* then one is created using the location converter specified.
|
||||
* @param path
|
||||
* @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) {
|
||||
PDOM result= null;
|
||||
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);
|
||||
|
||||
if(!versionMismatch.contains(file)) {
|
||||
synchronized(path2pdom) {
|
||||
if(path2pdom.containsKey(file)) {
|
||||
result = (PDOM) path2pdom.get(file);
|
||||
}
|
||||
path2pdom.put(file, result);
|
||||
if(result==null) {
|
||||
try {
|
||||
result = new PDOM(file, converter);
|
||||
|
||||
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);
|
||||
}
|
||||
} finally {
|
||||
result.releaseReadLock();
|
||||
}
|
||||
} catch(CoreException ce) {
|
||||
CCorePlugin.log(ce);
|
||||
} catch(InterruptedException ie) {
|
||||
CCorePlugin.log(ie);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ 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.cdt.internal.core.pdom.PDOM;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
/**
|
||||
|
@ -37,7 +38,10 @@ public class ReadOnlyPDOMProviderBridge implements IIndexFragmentProvider {
|
|||
|
||||
if(descs!=null) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
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}
|
||||
|
|
Loading…
Add table
Reference in a new issue