mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 01:35:39 +02:00
229989: apply fix: GeneratePDOM should not export PDOM's which are not sync'ed to project content
This commit is contained in:
parent
c81305c4cf
commit
8d6cd53eb4
6 changed files with 130 additions and 24 deletions
|
@ -10,6 +10,7 @@
|
|||
* Markus Schorn (Wind River Systems)
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Sergey Prigogin (Google)
|
||||
* Tim Kelly (Nokia)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
|
@ -29,6 +30,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CCorePreferenceConstants;
|
||||
|
@ -37,9 +39,13 @@ import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
|
|||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexChangeListener;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.index.IIndexLocationConverter;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.index.IIndexerStateListener;
|
||||
import org.eclipse.cdt.core.index.IndexLocationFactory;
|
||||
import org.eclipse.cdt.core.index.IndexerSetupParticipant;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
|
@ -69,7 +75,9 @@ import org.eclipse.cdt.internal.core.pdom.indexer.PDOMNullIndexer;
|
|||
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMRebuildTask;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.PDOMUpdateTask;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.TranslationUnitCollector;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.TriggerNotificationTask;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
|
@ -82,7 +90,9 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
import org.eclipse.core.runtime.ISafeRunnable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.ListenerList;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.OperationCanceledException;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Preferences;
|
||||
import org.eclipse.core.runtime.QualifiedName;
|
||||
|
@ -1379,4 +1389,74 @@ public class PDOMManager implements IWritableIndexManager, IListener {
|
|||
public boolean isProjectRegistered(ICProject project) {
|
||||
return getIndexer(project) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cproject the project to check
|
||||
* @return whether the content in the project fragment of the specified project's index
|
||||
* is complete (contains all sources) and up to date.
|
||||
* @throws CoreException
|
||||
*/
|
||||
public boolean isProjectContentSynced(ICProject cproject) throws CoreException {
|
||||
Set<ITranslationUnit> sources= new HashSet<ITranslationUnit>();
|
||||
cproject.accept(new TranslationUnitCollector(sources, null, new NullProgressMonitor()));
|
||||
|
||||
try {
|
||||
IIndex index= getIndex(cproject);
|
||||
index.acquireReadLock();
|
||||
try {
|
||||
for(ITranslationUnit tu : sources) {
|
||||
IResource resource= tu.getResource();
|
||||
if(resource instanceof IFile) {
|
||||
IIndexFileLocation location= IndexLocationFactory.getWorkspaceIFL((IFile)resource);
|
||||
if(!areSynchronized(index, resource, location)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
} catch(InterruptedException ie) {
|
||||
CCorePlugin.log(ie);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively checks that the specified file, and its include are up-to-date.
|
||||
* @param index the index to check against
|
||||
* @param resource the resource to check from the workspace
|
||||
* @param location the location to check from the index
|
||||
* @return whether the specified file, and its includes are up-to-date.
|
||||
* @throws CoreException
|
||||
*/
|
||||
private static boolean areSynchronized(IIndex index, IResource resource, IIndexFileLocation location) throws CoreException {
|
||||
IIndexFile[] file= index.getFiles(location);
|
||||
|
||||
// pre-includes may be listed twice (191989)
|
||||
if(file.length < 1 || file.length > 2)
|
||||
return false;
|
||||
|
||||
if(resource.getLocalTimeStamp() != file[0].getTimestamp())
|
||||
return false;
|
||||
|
||||
// if it is up-to-date, the includes have not changed and may
|
||||
// be read from the index.
|
||||
IIndexInclude[] includes= index.findIncludes(file[0]);
|
||||
for(IIndexInclude inc : includes) {
|
||||
IIndexFileLocation newLocation= inc.getIncludesLocation();
|
||||
if(newLocation != null) {
|
||||
String path= newLocation.getFullPath();
|
||||
if(path != null) {
|
||||
IResource newResource= ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(path));
|
||||
if(!areSynchronized(index, newResource, newLocation)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,9 @@ import org.eclipse.cdt.internal.core.CCoreInternals;
|
|||
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.ISafeRunnable;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* An ISafeRunnable which
|
||||
|
@ -36,7 +37,7 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
|||
* <li>Writes new properties to the PDOM
|
||||
* <ul>
|
||||
*/
|
||||
public class GeneratePDOM implements ISafeRunnable {
|
||||
public class GeneratePDOM {
|
||||
protected IExportProjectProvider pm;
|
||||
protected String[] applicationArguments;
|
||||
protected File targetLocation;
|
||||
|
@ -59,13 +60,21 @@ public class GeneratePDOM implements ISafeRunnable {
|
|||
this.deleteOnExit= deleteOnExit;
|
||||
}
|
||||
|
||||
public final void run() throws CoreException {
|
||||
/**
|
||||
* Executes the PDOM generation
|
||||
* @return {@link IStatus#OK} if the generated content is complete, {@link IStatus#ERROR} otherwise.
|
||||
* @throws CoreException if an internal or invalid configuration error occurs
|
||||
*/
|
||||
public final IStatus run() throws CoreException {
|
||||
boolean isContentSynced= false;
|
||||
|
||||
// create the project
|
||||
pm.setApplicationArguments(applicationArguments);
|
||||
final ICProject cproject = pm.createProject();
|
||||
if(cproject==null) {
|
||||
fail(MessageFormat.format(Messages.GeneratePDOM_ProjectProviderReturnedNullCProject,
|
||||
new Object [] {pm.getClass().getName()}));
|
||||
return; // cannot be reached, inform the compiler
|
||||
return null; // cannot be reached, inform the compiler
|
||||
}
|
||||
|
||||
IIndexLocationConverter converter= pm.getLocationConverter(cproject);
|
||||
|
@ -89,21 +98,30 @@ public class GeneratePDOM implements ISafeRunnable {
|
|||
Thread.sleep(200);
|
||||
}
|
||||
|
||||
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, targetLocation, converter);
|
||||
WritablePDOM exportedPDOM= new WritablePDOM(targetLocation, converter, LanguageManager.getInstance().getPDOMLinkageFactoryMappings());
|
||||
exportedPDOM.acquireWriteLock(0);
|
||||
try {
|
||||
Map<String,String> exportProperties= pm.getExportProperties();
|
||||
if(exportProperties!=null) {
|
||||
for(Map.Entry<String,String> entry : exportProperties.entrySet()) {
|
||||
exportedPDOM.setProperty(entry.getKey(), entry.getValue());
|
||||
// check status
|
||||
isContentSynced= CCoreInternals.getPDOMManager().isProjectContentSynced(cproject);
|
||||
|
||||
if(isContentSynced) {
|
||||
// export a .pdom file
|
||||
CCoreInternals.getPDOMManager().exportProjectPDOM(cproject, targetLocation, converter);
|
||||
|
||||
// write properties to exported PDOM
|
||||
WritablePDOM exportedPDOM= new WritablePDOM(targetLocation, converter, LanguageManager.getInstance().getPDOMLinkageFactoryMappings());
|
||||
exportedPDOM.acquireWriteLock(0);
|
||||
try {
|
||||
Map<String,String> exportProperties= pm.getExportProperties();
|
||||
if(exportProperties!=null) {
|
||||
for(Map.Entry<String,String> entry : exportProperties.entrySet()) {
|
||||
exportedPDOM.setProperty(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
exportedPDOM.close();
|
||||
}
|
||||
finally {
|
||||
exportedPDOM.releaseWriteLock();
|
||||
}
|
||||
exportedPDOM.close();
|
||||
}
|
||||
finally {
|
||||
exportedPDOM.releaseWriteLock();
|
||||
}
|
||||
|
||||
} catch(InterruptedException ie) {
|
||||
String msg= MessageFormat.format(Messages.GeneratePDOM_GenericGenerationFailed, new Object[] {ie.getMessage()});
|
||||
throw new CoreException(CCorePlugin.createStatus(msg, ie));
|
||||
|
@ -112,10 +130,10 @@ public class GeneratePDOM implements ISafeRunnable {
|
|||
cproject.getProject().delete(true, new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void handleException(Throwable exception) {
|
||||
CCorePlugin.log(exception);
|
||||
|
||||
return isContentSynced ?
|
||||
new Status(IStatus.OK, CCorePlugin.PLUGIN_ID, Messages.GeneratePDOM_Success)
|
||||
: new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, Messages.GeneratePDOM_Incomplete);
|
||||
}
|
||||
|
||||
private void fail(String message) throws CoreException {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 Symbian Software Systems and others.
|
||||
* Copyright (c) 2007, 2008 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
|
||||
|
@ -116,7 +116,11 @@ public class GeneratePDOMApplication implements IApplication {
|
|||
|
||||
GeneratePDOM generate = new GeneratePDOM(pprovider, appArgs, targetLocation, indexerID);
|
||||
output(Messages.GeneratePDOMApplication_GenerationStarts);
|
||||
generate.run();
|
||||
try {
|
||||
generate.run();
|
||||
} catch(CoreException ce) {
|
||||
CCorePlugin.log(ce);
|
||||
}
|
||||
output(Messages.GeneratePDOMApplication_GenerationEnds);
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -15,8 +15,10 @@ import org.eclipse.osgi.util.NLS;
|
|||
public class Messages extends NLS {
|
||||
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.pdom.export.messages"; //$NON-NLS-1$
|
||||
public static String GeneratePDOM_GenericGenerationFailed;
|
||||
public static String GeneratePDOM_Incomplete;
|
||||
public static String GeneratePDOM_NullLocationConverter;
|
||||
public static String GeneratePDOM_ProjectProviderReturnedNullCProject;
|
||||
public static String GeneratePDOM_Success;
|
||||
public static String GeneratePDOMApplication_CouldNotFindInitializer;
|
||||
public static String GeneratePDOMApplication_GenerationEnds;
|
||||
public static String GeneratePDOMApplication_GenerationStarts;
|
||||
|
|
|
@ -10,9 +10,11 @@
|
|||
###############################################################################
|
||||
GeneratePDOMApplication_Initializing=== Initializing
|
||||
GeneratePDOM_GenericGenerationFailed=Generation failed: {0}
|
||||
GeneratePDOM_Incomplete=Pre-built index content is incomplete or out of date
|
||||
GeneratePDOM_NullLocationConverter=IExportProjectProvider implementation of getLocationConverter() returned null ({0})
|
||||
GeneratePDOMApplication_CouldNotFindInitializer=Could not find IExportProjectProvider: {0}
|
||||
GeneratePDOM_ProjectProviderReturnedNullCProject=IExportProjectProvider implementation of createProject() returned null ({0})
|
||||
GeneratePDOM_Success=Pre-built index content successfully generated
|
||||
GeneratePDOMApplication_CouldNotFindInitializer=Could not find IExportProjectProvider: {0}
|
||||
GeneratePDOMApplication_UsingDefaultProjectProvider=-pprovider not specified - defaulting to {0}
|
||||
GeneratePDOMApplication_GenerationStarts=== Generation starts
|
||||
GeneratePDOMApplication_InvalidIndexerID={0} takes zero or one argument
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
final class TranslationUnitCollector implements ICElementVisitor {
|
||||
final public class TranslationUnitCollector implements ICElementVisitor {
|
||||
private final Collection<ITranslationUnit> fSources;
|
||||
private final Collection<ITranslationUnit> fHeaders;
|
||||
private final IProgressMonitor fProgressMonitor;
|
||||
|
|
Loading…
Add table
Reference in a new issue