mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-13 19:25:38 +02:00
Changes to working copy, to be wrap in runnable Plaform
operation when commiting or destroying the working copy. Also changes to the ICElementDelta to be fired in a Workspace runnable.
This commit is contained in:
parent
2d3fadb88c
commit
1529ec129e
10 changed files with 370 additions and 187 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2004-04-29 Alain Magloire
|
||||||
|
|
||||||
|
Changes to working copy, to be wrap in runnable Plaform
|
||||||
|
operation when commiting or destroying the working copy.
|
||||||
|
Also changes to the ICElementDelta to be fired in a
|
||||||
|
Workspace runnable.
|
||||||
|
|
||||||
2004-04-28 Alain Magloire
|
2004-04-28 Alain Magloire
|
||||||
|
|
||||||
NPE in the PathEntry.
|
NPE in the PathEntry.
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.util.Locale;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.model.CModelManager;
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
import org.eclipse.core.resources.IContainer;
|
import org.eclipse.core.resources.IContainer;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.runtime.IPath;
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
@ -371,31 +371,7 @@ public class Util {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static boolean isCCFileName(String fileName) {
|
public static boolean isCCFileName(String fileName) {
|
||||||
String[] sourceExtensions = CModelManager.sourceExtensions;
|
return CoreModel.isValidTranslationUnitName(fileName);
|
||||||
String[] headerExtensions = CModelManager.headerExtensions;
|
|
||||||
|
|
||||||
int dot =fileName.lastIndexOf("."); //$NON-NLS-1$
|
|
||||||
|
|
||||||
//No extension, give benefit of doubt
|
|
||||||
if (dot == -1)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//Extract extension
|
|
||||||
String extension = ""; //$NON-NLS-1$
|
|
||||||
if (dot + 1 <= fileName.length())
|
|
||||||
extension = fileName.substring(dot + 1);
|
|
||||||
|
|
||||||
for (int i=0; i<sourceExtensions.length; i++){
|
|
||||||
if (sourceExtensions[i].equals(extension))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<headerExtensions.length; i++){
|
|
||||||
if (headerExtensions[i].equals(extension))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,6 @@ import org.eclipse.cdt.core.parser.ParserMode;
|
||||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||||
import org.eclipse.cdt.internal.core.index.IDocument;
|
import org.eclipse.cdt.internal.core.index.IDocument;
|
||||||
import org.eclipse.cdt.internal.core.model.CModelManager;
|
|
||||||
import org.eclipse.cdt.utils.TimeOut;
|
import org.eclipse.cdt.utils.TimeOut;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
|
@ -76,7 +75,7 @@ public class SourceIndexer extends AbstractIndexer {
|
||||||
* Returns the file types the <code>IIndexer</code> handles.
|
* Returns the file types the <code>IIndexer</code> handles.
|
||||||
*/
|
*/
|
||||||
public String[] getFileTypes(){
|
public String[] getFileTypes(){
|
||||||
return CModelManager.sourceExtensions;
|
return CoreModel.getDefault().getSourceExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void indexFile(IDocument document) throws IOException {
|
protected void indexFile(IDocument document) throws IOException {
|
||||||
|
@ -98,7 +97,7 @@ public class SourceIndexer extends AbstractIndexer {
|
||||||
}
|
}
|
||||||
|
|
||||||
//C or CPP?
|
//C or CPP?
|
||||||
ParserLanguage language = CoreModel.getDefault().hasCCNature(currentProject) ? ParserLanguage.CPP : ParserLanguage.C;
|
ParserLanguage language = CoreModel.hasCCNature(currentProject) ? ParserLanguage.CPP : ParserLanguage.C;
|
||||||
|
|
||||||
IParser parser = null;
|
IParser parser = null;
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,8 @@ public interface IWorkingCopy extends ITranslationUnit{
|
||||||
* The boolean argument allows to force problem detection even if the
|
* The boolean argument allows to force problem detection even if the
|
||||||
* working copy is already consistent.
|
* working copy is already consistent.
|
||||||
*/
|
*/
|
||||||
boolean reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws CModelException;
|
void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws CModelException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restores the contents of this working copy to the current contents of
|
* Restores the contents of this working copy to the current contents of
|
||||||
* this working copy's original element. Has no effect if this element
|
* this working copy's original element. Has no effect if this element
|
||||||
|
|
|
@ -9,6 +9,7 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -54,16 +55,22 @@ import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
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.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.ISafeRunnable;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
|
||||||
public class CModelManager implements IResourceChangeListener, ICDescriptorListener {
|
public class CModelManager implements IResourceChangeListener, ICDescriptorListener {
|
||||||
|
|
||||||
|
public static boolean VERBOSE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unique handle onto the CModel
|
* Unique handle onto the CModel
|
||||||
*/
|
*/
|
||||||
final CModel cModel = new CModel();
|
final CModel cModel = new CModel();
|
||||||
|
|
||||||
public static HashSet OptionNames = new HashSet(20);
|
public static HashSet OptionNames = new HashSet(20);
|
||||||
|
|
||||||
|
public static final int DEFAULT_CHANGE_EVENT = 0; // must not collide with ElementChangedEvent event masks
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to convert <code>IResourceDelta</code>s into <code>ICElementDelta</code>s.
|
* Used to convert <code>IResourceDelta</code>s into <code>ICElementDelta</code>s.
|
||||||
*/
|
*/
|
||||||
|
@ -75,6 +82,12 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe
|
||||||
*/
|
*/
|
||||||
private ArrayList fCModelDeltas = new ArrayList();
|
private ArrayList fCModelDeltas = new ArrayList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue of reconcile deltas on working copies that have yet to be fired.
|
||||||
|
* This is a table form IWorkingCopy to IJavaElementDelta
|
||||||
|
*/
|
||||||
|
HashMap reconcileDeltas = new HashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turns delta firing on/off. By default it is on.
|
* Turns delta firing on/off. By default it is on.
|
||||||
*/
|
*/
|
||||||
|
@ -119,11 +132,6 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe
|
||||||
*/
|
*/
|
||||||
private HashMap sourceMappers = new HashMap();
|
private HashMap sourceMappers = new HashMap();
|
||||||
|
|
||||||
// TODO: This should be in a preference/property page
|
|
||||||
public static final String [] sourceExtensions = {"c", "cxx", "cc", "C", "cpp"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
|
|
||||||
public static final String [] headerExtensions = {"h", "hh", "hpp", "H"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
|
||||||
public static final String [] assemblyExtensions = {"s", "S"}; //$NON-NLS-1$ //$NON-NLS-2$
|
|
||||||
|
|
||||||
public static final IWorkingCopy[] NoWorkingCopy = new IWorkingCopy[0];
|
public static final IWorkingCopy[] NoWorkingCopy = new IWorkingCopy[0];
|
||||||
|
|
||||||
static CModelManager factory = null;
|
static CModelManager factory = null;
|
||||||
|
@ -570,32 +578,6 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
public String[] getHeaderExtensions() {
|
|
||||||
return headerExtensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getSourceExtensions() {
|
|
||||||
return sourceExtensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getAssemblyExtensions() {
|
|
||||||
return assemblyExtensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getTranslationUnitExtensions() {
|
|
||||||
String[] sources = getSourceExtensions();
|
|
||||||
String[] headers = getHeaderExtensions();
|
|
||||||
String[] asm = getAssemblyExtensions();
|
|
||||||
String[] cexts = new String[headers.length + sources.length + asm.length];
|
|
||||||
System.arraycopy(sources, 0, cexts, 0, sources.length);
|
|
||||||
System.arraycopy(headers, 0, cexts, sources.length, headers.length);
|
|
||||||
System.arraycopy(asm, 0, cexts, sources.length + headers.length, asm.length);
|
|
||||||
return cexts;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public BinaryRunner getBinaryRunner(ICProject project) {
|
public BinaryRunner getBinaryRunner(ICProject project) {
|
||||||
BinaryRunner runner = null;
|
BinaryRunner runner = null;
|
||||||
synchronized(binaryRunners) {
|
synchronized(binaryRunners) {
|
||||||
|
@ -741,35 +723,114 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fire(int eventType) {
|
||||||
|
fire(null, eventType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire C Model deltas, flushing them after the fact.
|
* Fire C Model deltas, flushing them after the fact.
|
||||||
* If the firing mode has been turned off, this has no effect.
|
* If the firing mode has been turned off, this has no effect.
|
||||||
*/
|
*/
|
||||||
public synchronized void fire(int eventType) {
|
public synchronized void fire(ICElementDelta customDeltas, int eventType) {
|
||||||
if (fFire) {
|
if (fFire) {
|
||||||
mergeDeltas();
|
ICElementDelta deltaToNotify;
|
||||||
try {
|
if (customDeltas == null) {
|
||||||
Iterator iterator = fCModelDeltas.iterator();
|
deltaToNotify = this.mergeDeltas(this.fCModelDeltas);
|
||||||
while (iterator.hasNext()) {
|
} else {
|
||||||
ICElementDelta delta= (ICElementDelta) iterator.next();
|
deltaToNotify = customDeltas;
|
||||||
// Refresh internal scopes
|
}
|
||||||
fire(delta, eventType);
|
|
||||||
}
|
// Notification
|
||||||
} finally {
|
IElementChangedListener[] listeners = new IElementChangedListener[fElementChangedListeners.size()];
|
||||||
// empty the queue
|
fElementChangedListeners.toArray(listeners);
|
||||||
this.flush();
|
int listenerCount = listeners.length;
|
||||||
|
int [] listenerMask = null;
|
||||||
|
|
||||||
|
switch (eventType) {
|
||||||
|
case DEFAULT_CHANGE_EVENT:
|
||||||
|
firePreAutoBuildDelta(deltaToNotify, listeners, listenerMask, listenerCount);
|
||||||
|
firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount);
|
||||||
|
fireReconcileDelta(listeners, listenerMask, listenerCount);
|
||||||
|
break;
|
||||||
|
case ElementChangedEvent.PRE_AUTO_BUILD:
|
||||||
|
firePreAutoBuildDelta(deltaToNotify, listeners, listenerMask, listenerCount);
|
||||||
|
break;
|
||||||
|
case ElementChangedEvent.POST_CHANGE:
|
||||||
|
firePostChangeDelta(deltaToNotify, listeners, listenerMask, listenerCount);
|
||||||
|
fireReconcileDelta(listeners, listenerMask, listenerCount);
|
||||||
|
break;
|
||||||
|
case ElementChangedEvent.POST_RECONCILE:
|
||||||
|
fireReconcileDelta(listeners, listenerMask, listenerCount);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void fire(ICElementDelta delta, int eventType) {
|
private void firePreAutoBuildDelta(ICElementDelta deltaToNotify,
|
||||||
ElementChangedEvent event= new ElementChangedEvent(delta, eventType);
|
IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
|
||||||
// Clone the listeners since they could remove themselves when told about the event
|
|
||||||
// (eg. a type hierarchy becomes invalid (and thus it removes itself) when the type is removed
|
if (VERBOSE) {
|
||||||
ArrayList listeners= (ArrayList) fElementChangedListeners.clone();
|
System.out.println("FIRING PRE_AUTO_BUILD Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
for (int i= 0; i < listeners.size(); i++) {
|
System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
|
||||||
IElementChangedListener listener= (IElementChangedListener) listeners.get(i);
|
}
|
||||||
listener.elementChanged(event);
|
if (deltaToNotify != null) {
|
||||||
|
notifyListeners(deltaToNotify, ElementChangedEvent.PRE_AUTO_BUILD, listeners, listenerMask, listenerCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void firePostChangeDelta(ICElementDelta deltaToNotify, IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
|
||||||
|
|
||||||
|
// post change deltas
|
||||||
|
if (VERBOSE){
|
||||||
|
System.out.println("FIRING POST_CHANGE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (deltaToNotify != null) {
|
||||||
|
// flush now so as to keep listener reactions to post their own deltas for subsequent iteration
|
||||||
|
this.flush();
|
||||||
|
notifyListeners(deltaToNotify, ElementChangedEvent.POST_CHANGE, listeners, listenerMask, listenerCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireReconcileDelta(IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
|
||||||
|
ICElementDelta deltaToNotify = mergeDeltas(this.reconcileDeltas.values());
|
||||||
|
if (VERBOSE){
|
||||||
|
System.out.println("FIRING POST_RECONCILE Delta ["+Thread.currentThread()+"]:"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
System.out.println(deltaToNotify == null ? "<NONE>" : deltaToNotify.toString()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (deltaToNotify != null) {
|
||||||
|
// flush now so as to keep listener reactions to post their own deltas for subsequent iteration
|
||||||
|
this.reconcileDeltas = new HashMap();
|
||||||
|
notifyListeners(deltaToNotify, ElementChangedEvent.POST_RECONCILE, listeners, listenerMask, listenerCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyListeners(ICElementDelta deltaToNotify, int eventType,
|
||||||
|
IElementChangedListener[] listeners, int[] listenerMask, int listenerCount) {
|
||||||
|
|
||||||
|
final ElementChangedEvent extraEvent = new ElementChangedEvent(deltaToNotify, eventType);
|
||||||
|
for (int i= 0; i < listenerCount; i++) {
|
||||||
|
if (listenerMask == null || (listenerMask[i] & eventType) != 0) {
|
||||||
|
final IElementChangedListener listener = listeners[i];
|
||||||
|
long start = -1;
|
||||||
|
if (VERBOSE) {
|
||||||
|
System.out.print("Listener #" + (i+1) + "=" + listener.toString());//$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
start = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
// wrap callbacks with Safe runnable for subsequent listeners to be called when some are causing grief
|
||||||
|
Platform.run(new ISafeRunnable() {
|
||||||
|
public void handleException(Throwable exception) {
|
||||||
|
//CCorePlugin.log(exception, "Exception occurred in listener of C element change notification"); //$NON-NLS-1$
|
||||||
|
CCorePlugin.log(exception);
|
||||||
|
}
|
||||||
|
public void run() throws Exception {
|
||||||
|
listener.elementChanged(extraEvent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (VERBOSE) {
|
||||||
|
System.out.println(" -> " + (System.currentTimeMillis()-start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,19 +841,21 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe
|
||||||
fCModelDeltas= new ArrayList();
|
fCModelDeltas= new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private ICElementDelta mergeDeltas(Collection deltas) {
|
||||||
* Merged all awaiting deltas.
|
|
||||||
*/
|
|
||||||
private void mergeDeltas() {
|
|
||||||
if (fCModelDeltas.size() <= 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Iterator deltas = fCModelDeltas.iterator();
|
if (deltas.size() == 0)
|
||||||
|
return null;
|
||||||
|
if (deltas.size() == 1)
|
||||||
|
return (ICElementDelta)deltas.iterator().next();
|
||||||
|
if (deltas.size() <= 1)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Iterator iterator = deltas.iterator();
|
||||||
ICElement cRoot = getCModel();
|
ICElement cRoot = getCModel();
|
||||||
CElementDelta rootDelta = new CElementDelta(cRoot);
|
CElementDelta rootDelta = new CElementDelta(cRoot);
|
||||||
boolean insertedTree = false;
|
boolean insertedTree = false;
|
||||||
while (deltas.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
CElementDelta delta = (CElementDelta)deltas.next();
|
CElementDelta delta = (CElementDelta)iterator.next();
|
||||||
ICElement element = delta.getElement();
|
ICElement element = delta.getElement();
|
||||||
if (cRoot.equals(element)) {
|
if (cRoot.equals(element)) {
|
||||||
ICElementDelta[] children = delta.getAffectedChildren();
|
ICElementDelta[] children = delta.getAffectedChildren();
|
||||||
|
@ -807,10 +870,12 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (insertedTree) {
|
if (insertedTree) {
|
||||||
fCModelDeltas = new ArrayList(1);
|
//fCModelDeltas = new ArrayList(1);
|
||||||
fCModelDeltas.add(rootDelta);
|
//fCModelDeltas.add(rootDelta);
|
||||||
|
return rootDelta;
|
||||||
} else {
|
} else {
|
||||||
fCModelDeltas = new ArrayList(0);
|
//fCModelDeltas = new ArrayList(0);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ package org.eclipse.cdt.internal.core.model;
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
||||||
|
@ -14,6 +15,7 @@ import org.eclipse.cdt.core.model.ICModel;
|
||||||
import org.eclipse.cdt.core.model.ICModelStatus;
|
import org.eclipse.cdt.core.model.ICModelStatus;
|
||||||
import org.eclipse.cdt.core.model.ICModelStatusConstants;
|
import org.eclipse.cdt.core.model.ICModelStatusConstants;
|
||||||
import org.eclipse.cdt.core.model.ICProject;
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
import org.eclipse.core.resources.IContainer;
|
import org.eclipse.core.resources.IContainer;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IFolder;
|
import org.eclipse.core.resources.IFolder;
|
||||||
|
@ -157,6 +159,30 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Registers the given reconcile delta with the Java Model Manager.
|
||||||
|
*/
|
||||||
|
protected void addReconcileDelta(IWorkingCopy workingCopy, ICElementDelta delta) {
|
||||||
|
HashMap reconcileDeltas = CModelManager.getDefault().reconcileDeltas;
|
||||||
|
CElementDelta previousDelta = (CElementDelta)reconcileDeltas.get(workingCopy);
|
||||||
|
if (previousDelta != null) {
|
||||||
|
ICElementDelta[] children = delta.getAffectedChildren();
|
||||||
|
for (int i = 0, length = children.length; i < length; i++) {
|
||||||
|
CElementDelta child = (CElementDelta)children[i];
|
||||||
|
previousDelta.insertDeltaTree(child.getElement(), child);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reconcileDeltas.put(workingCopy, delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deregister the reconcile delta for the given working copy
|
||||||
|
*/
|
||||||
|
protected void removeReconcileDelta(IWorkingCopy workingCopy) {
|
||||||
|
CModelManager.getDefault().reconcileDeltas.remove(workingCopy);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see IProgressMonitor
|
* @see IProgressMonitor
|
||||||
*/
|
*/
|
||||||
|
@ -498,14 +524,14 @@ public abstract class CModelOperation implements IWorkspaceRunnable, IProgressMo
|
||||||
* @exception CoreException if the operation fails
|
* @exception CoreException if the operation fails
|
||||||
*/
|
*/
|
||||||
public void run(IProgressMonitor monitor) throws CoreException {
|
public void run(IProgressMonitor monitor) throws CoreException {
|
||||||
|
CModelManager manager= CModelManager.getDefault();
|
||||||
try {
|
try {
|
||||||
fMonitor = monitor;
|
fMonitor = monitor;
|
||||||
execute();
|
execute();
|
||||||
} finally {
|
} finally {
|
||||||
registerDeltas();
|
registerDeltas();
|
||||||
// Fire if we change somethings
|
// Fire if we change somethings
|
||||||
if (!hasModifiedResource()) {
|
if (!hasModifiedResource() || manager.reconcileDeltas.isEmpty()) {
|
||||||
CModelManager manager= CModelManager.getDefault();
|
|
||||||
manager.fire(ElementChangedEvent.POST_CHANGE);
|
manager.fire(ElementChangedEvent.POST_CHANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -590,25 +590,16 @@ public class DeltaProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateDependencies(ICElement element){
|
private void updateDependencies(ICElement element){
|
||||||
|
|
||||||
IResource resource = element.getResource();
|
IResource resource = element.getResource();
|
||||||
if (resource == null)
|
if (resource == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String fileExtension = resource.getFileExtension();
|
|
||||||
|
|
||||||
if ((fileExtension != null) &&
|
String filename = resource.getName();
|
||||||
(isValidHeader(fileExtension))){
|
|
||||||
|
if (CoreModel.isValidHeaderUnitName(filename)) {
|
||||||
indexManager.updateDependencies(resource);
|
indexManager.updateDependencies(resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidHeader(String fileExtension) {
|
|
||||||
String[] supportedTypes = CModelManager.headerExtensions;
|
|
||||||
for (int i = 0; i < supportedTypes.length; ++i) {
|
|
||||||
if (supportedTypes[i].equals(fileExtension))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2003 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.model;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a working copy (remove it from its cache if it is shared)
|
||||||
|
* and signal its removal through a delta.
|
||||||
|
*/
|
||||||
|
public class DestroyWorkingCopyOperation extends CModelOperation {
|
||||||
|
|
||||||
|
public DestroyWorkingCopyOperation(ICElement workingCopy) {
|
||||||
|
super(new ICElement[] {workingCopy});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @exception CModelException if setting the source
|
||||||
|
* of the original translation unit fails
|
||||||
|
*/
|
||||||
|
protected void executeOperation() throws CModelException {
|
||||||
|
|
||||||
|
WorkingCopy workingCopy = getWorkingCopy();
|
||||||
|
workingCopy.close();
|
||||||
|
|
||||||
|
// if original element is not on classpath flush it from the cache
|
||||||
|
ICElement originalElement = workingCopy.getOriginalElement();
|
||||||
|
if (!workingCopy.getParent().exists()) {
|
||||||
|
((TranslationUnit)originalElement).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove working copy from the cache if it is shared
|
||||||
|
CModelManager manager = CModelManager.getDefault();
|
||||||
|
|
||||||
|
// In order to be shared, working copies have to denote the same compilation unit
|
||||||
|
// AND use the same buffer factory.
|
||||||
|
// Assuming there is a little set of buffer factories, then use a 2 level Map cache.
|
||||||
|
Map sharedWorkingCopies = manager.sharedWorkingCopies;
|
||||||
|
|
||||||
|
Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(workingCopy.bufferFactory);
|
||||||
|
if (perFactoryWorkingCopies != null) {
|
||||||
|
if (perFactoryWorkingCopies.remove(originalElement) != null) {
|
||||||
|
//System.out.println("Destroying shared working copy " + workingCopy.toStringWithAncestors());//$NON-NLS-1$
|
||||||
|
//CModelManager.getDefault().fire(delta, ElementChangedEvent.POST_RECONCILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// report C deltas
|
||||||
|
CElementDelta delta = new CElementDelta(this.getCModel());
|
||||||
|
delta.removed(workingCopy);
|
||||||
|
addDelta(delta);
|
||||||
|
removeReconcileDelta(workingCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the working copy this operation is working on.
|
||||||
|
*/
|
||||||
|
protected WorkingCopy getWorkingCopy() {
|
||||||
|
return (WorkingCopy)getElementToProcess();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @see CModelOperation#isReadOnly
|
||||||
|
*/
|
||||||
|
public boolean isReadOnly() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2003 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Common Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/cpl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.model;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
import org.eclipse.cdt.core.model.ICModelStatus;
|
||||||
|
import org.eclipse.cdt.core.model.ICModelStatusConstants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reconcile a working copy and signal the changes through a delta.
|
||||||
|
*/
|
||||||
|
public class ReconcileWorkingCopyOperation extends CModelOperation {
|
||||||
|
|
||||||
|
boolean forceProblemDetection;
|
||||||
|
|
||||||
|
public ReconcileWorkingCopyOperation(ICElement workingCopy, boolean forceProblemDetection) {
|
||||||
|
super(new ICElement[] {workingCopy});
|
||||||
|
this.forceProblemDetection = forceProblemDetection;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @exception CModelException if setting the source
|
||||||
|
* of the original compilation unit fails
|
||||||
|
*/
|
||||||
|
protected void executeOperation() throws CModelException {
|
||||||
|
if (fMonitor != null){
|
||||||
|
if (fMonitor.isCanceled()) return;
|
||||||
|
fMonitor.beginTask("element.reconciling", 10); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkingCopy workingCopy = getWorkingCopy();
|
||||||
|
boolean wasConsistent = workingCopy.isConsistent();
|
||||||
|
CElementDeltaBuilder deltaBuilder = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// create the delta builder (this remembers the current content of the cu)
|
||||||
|
if (!wasConsistent){
|
||||||
|
deltaBuilder = new CElementDeltaBuilder(workingCopy);
|
||||||
|
|
||||||
|
// update the element infos with the content of the working copy
|
||||||
|
workingCopy.makeConsistent(fMonitor);
|
||||||
|
deltaBuilder.buildDeltas();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fMonitor != null) fMonitor.worked(2);
|
||||||
|
|
||||||
|
// force problem detection? - if structure was consistent
|
||||||
|
if (forceProblemDetection && wasConsistent){
|
||||||
|
if (fMonitor != null && fMonitor.isCanceled()) return;
|
||||||
|
|
||||||
|
//IProblemRequestor problemRequestor = workingCopy.problemRequestor;
|
||||||
|
//if (problemRequestor != null && problemRequestor.isActive()){
|
||||||
|
// problemRequestor.beginReporting();
|
||||||
|
// CompilationUnitProblemFinder.process(workingCopy, problemRequestor, fMonitor);
|
||||||
|
// problemRequestor.endReporting();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the deltas
|
||||||
|
if (deltaBuilder != null){
|
||||||
|
if ((deltaBuilder.delta != null) && (deltaBuilder.delta.getAffectedChildren().length > 0)) {
|
||||||
|
addReconcileDelta(workingCopy, deltaBuilder.delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (fMonitor != null) fMonitor.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the working copy this operation is working on.
|
||||||
|
*/
|
||||||
|
protected WorkingCopy getWorkingCopy() {
|
||||||
|
return (WorkingCopy)getElementToProcess();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @see CModelOperation#isReadOnly
|
||||||
|
*/
|
||||||
|
public boolean isReadOnly() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ICModelStatus verify() {
|
||||||
|
ICModelStatus status = super.verify();
|
||||||
|
if (!status.isOK()) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
WorkingCopy workingCopy = getWorkingCopy();
|
||||||
|
if (workingCopy.useCount == 0) {
|
||||||
|
return new CModelStatus(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST, workingCopy); //was destroyed
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -12,13 +12,13 @@ package org.eclipse.cdt.internal.core.model;
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.model.*;
|
|
||||||
import org.eclipse.cdt.core.model.CModelException;
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
import org.eclipse.cdt.core.model.IBuffer;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.model.ICModelStatusConstants;
|
import org.eclipse.cdt.core.model.ICModelStatusConstants;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.IMarker;
|
import org.eclipse.core.resources.IMarker;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
|
@ -113,34 +113,11 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
close();
|
DestroyWorkingCopyOperation op = new DestroyWorkingCopyOperation(this);
|
||||||
|
runOperation(op, null);
|
||||||
// if original element is not on classpath flush it from the cache
|
|
||||||
ICElement originalElement = this.getOriginalElement();
|
|
||||||
if (!this.getParent().exists()) {
|
|
||||||
((TranslationUnit)originalElement).close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove working copy from the cache
|
|
||||||
CModelManager manager = CModelManager.getDefault();
|
|
||||||
|
|
||||||
// In order to be shared, working copies have to denote the same compilation unit
|
|
||||||
// AND use the same buffer factory.
|
|
||||||
// Assuming there is a little set of buffer factories, then use a 2 level Map cache.
|
|
||||||
Map sharedWorkingCopies = manager.sharedWorkingCopies;
|
|
||||||
|
|
||||||
Map perFactoryWorkingCopies = (Map) sharedWorkingCopies.get(this.bufferFactory);
|
|
||||||
if (perFactoryWorkingCopies != null){
|
|
||||||
if (perFactoryWorkingCopies.remove(originalElement) != null) {
|
|
||||||
// report C deltas
|
|
||||||
CElementDelta delta = new CElementDelta(this.getCModel());
|
|
||||||
delta.removed(this);
|
|
||||||
CModelManager.getDefault().fire(delta, ElementChangedEvent.POST_RECONCILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (CModelException e) {
|
} catch (CModelException e) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,7 +128,6 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
|
||||||
return this.useCount != 0;
|
return this.useCount != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Answers custom buffer factory
|
* Answers custom buffer factory
|
||||||
*/
|
*/
|
||||||
|
@ -197,7 +173,6 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see IWorkingCopy
|
* @see IWorkingCopy
|
||||||
*/
|
*/
|
||||||
|
@ -294,56 +269,14 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.cdt.core.model.IWorkingCopy#reconcile(boolean, org.eclipse.core.runtime.IProgressMonitor)
|
* @see org.eclipse.cdt.core.model.IWorkingCopy#reconcile(boolean, org.eclipse.core.runtime.IProgressMonitor)
|
||||||
*/
|
*/
|
||||||
public boolean reconcile(boolean forceProblemDetection, IProgressMonitor monitor)
|
public void reconcile(boolean forceProblemDetection, IProgressMonitor monitor) throws CModelException {
|
||||||
throws CModelException {
|
|
||||||
|
|
||||||
if (this.useCount == 0) throw newNotPresentException(); //was destroyed
|
if (this.useCount == 0) throw newNotPresentException(); //was destroyed
|
||||||
|
|
||||||
if (monitor != null){
|
ReconcileWorkingCopyOperation op = new ReconcileWorkingCopyOperation(this, forceProblemDetection);
|
||||||
if (monitor.isCanceled()) return false;
|
runOperation(op, monitor);
|
||||||
monitor.beginTask("element.reconciling", 10); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean wasConsistent = isConsistent();
|
|
||||||
CElementDeltaBuilder deltaBuilder = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// create the delta builder (this remembers the current content of the cu)
|
|
||||||
if (!wasConsistent){
|
|
||||||
deltaBuilder = new CElementDeltaBuilder(this);
|
|
||||||
|
|
||||||
// update the element infos with the content of the working copy
|
|
||||||
this.makeConsistent(monitor);
|
|
||||||
deltaBuilder.buildDeltas();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (monitor != null) monitor.worked(2);
|
|
||||||
|
|
||||||
// force problem detection? - if structure was consistent
|
|
||||||
if (forceProblemDetection && wasConsistent){
|
|
||||||
if (monitor != null && monitor.isCanceled()) return (!wasConsistent);
|
|
||||||
|
|
||||||
//IProblemRequestor problemRequestor = this.getProblemRequestor();
|
|
||||||
//if (problemRequestor != null && problemRequestor.isActive()){
|
|
||||||
// problemRequestor.beginReporting();
|
|
||||||
// CompilationUnitProblemFinder.process(this, problemRequestor, monitor);
|
|
||||||
// problemRequestor.endReporting();
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fire the deltas
|
|
||||||
if (deltaBuilder != null){
|
|
||||||
if ((deltaBuilder.delta != null) && (deltaBuilder.delta.getAffectedChildren().length > 0)) {
|
|
||||||
CModelManager.getDefault().fire(deltaBuilder.delta, ElementChangedEvent.POST_RECONCILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (monitor != null) monitor.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
// An indication if something has changed
|
|
||||||
return (!wasConsistent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.cdt.core.model.IWorkingCopy#restore()
|
* @see org.eclipse.cdt.core.model.IWorkingCopy#restore()
|
||||||
*/
|
*/
|
||||||
|
@ -357,6 +290,7 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
|
||||||
updateTimeStamp(original);
|
updateTimeStamp(original);
|
||||||
makeConsistent(null);
|
makeConsistent(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.cdt.core.model.ICFile#save(IProgressMonitor, boolean)
|
* @see org.eclipse.cdt.core.model.ICFile#save(IProgressMonitor, boolean)
|
||||||
*/
|
*/
|
||||||
|
@ -367,6 +301,7 @@ public class WorkingCopy extends TranslationUnit implements IWorkingCopy {
|
||||||
// computes fine-grain deltas in case the working copy is being reconciled already (if not it would miss one iteration of deltas).
|
// computes fine-grain deltas in case the working copy is being reconciled already (if not it would miss one iteration of deltas).
|
||||||
this.reconcile();
|
this.reconcile();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param original
|
* @param original
|
||||||
* @throws CModelException
|
* @throws CModelException
|
||||||
|
|
Loading…
Add table
Reference in a new issue