1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Patch for Bogdan Gheorghe:

- Here's a first take at the dependency tree service
which is needed by both the managed build and the
indexer. The service is in a really early form with no
persistance or notification mechanisms in place yet.
There is just enough in here to allow Sean to get his
makefile dependencies. I added a check box to the
indexer tab to enable the service on a per project basis.
This commit is contained in:
Doug Schaefer 2003-07-24 14:15:07 +00:00
parent 9d44e90798
commit 33b684ca91
33 changed files with 1869 additions and 6 deletions

View file

@ -0,0 +1,8 @@
#include "DepTest.h"
#include "d.h"
DepTest::DepTest()
{};
DepTest::~DepTest()
{};

View file

@ -0,0 +1,8 @@
#include "Inc1.h"
#include "a.h"
class DepTest{
public:
DepTest();
~DepTest();
};

View file

@ -0,0 +1,8 @@
#include "DepTest2.h"
#include "d.h"
DepTest2::DepTest2()
{};
DepTest2::~DepTest2()
{};

View file

@ -0,0 +1,8 @@
#include "d.h"
class DepTest2{
public:
DepTest2();
~DepTest2();
};

View file

@ -0,0 +1,8 @@
#include "c.h"
class X
{
public:
X(){};
~X(){};
};

View file

@ -0,0 +1,8 @@
#include "c.h"
class Z
{
public:
Z(){};
~Z(){};
};

View file

@ -0,0 +1,6 @@
class Y
{
public:
Y(){};
~Y(){};
};

View file

@ -0,0 +1,6 @@
class d
{
public:
d(){};
~d(){};
};

View file

@ -11,18 +11,23 @@
package org.eclipse.cdt.core.indexer.tests;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.search.ICSearchConstants;
import org.eclipse.cdt.internal.core.index.IEntryResult;
import org.eclipse.cdt.internal.core.index.IIndex;
import org.eclipse.cdt.internal.core.index.IQueryResult;
import org.eclipse.cdt.internal.core.index.impl.IFileDocument;
import org.eclipse.cdt.internal.core.search.indexing.IIndexConstants;
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.cdt.internal.core.sourcedependency.DependencyManager;
import org.eclipse.cdt.internal.core.sourcedependency.DependencyQueryJob;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
@ -80,7 +85,7 @@ public class IndexManagerTests extends TestCase {
public static Test suite() {
//TestSuite suite = new TestSuite();
//suite.addTest(new IndexManagerTests("testIndexContents"));
//suite.addTest(new IndexManagerTests("testDependencyTree"));
//return suite;
return new TestSuite(IndexManagerTests.class);
}
@ -114,7 +119,7 @@ public class IndexManagerTests extends TestCase {
return cproject;
}
private void importFile(String fileName, String resourceLocation)throws Exception{
private IFile importFile(String fileName, String resourceLocation)throws Exception{
//Obtain file handle
file = testProject.getProject().getFile(fileName);
String pluginRoot=org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile();
@ -124,6 +129,7 @@ public class IndexManagerTests extends TestCase {
file.create(new FileInputStream(pluginRoot + resourceLocation),false,monitor);
}
fileDoc = new IFileDocument(file);
return file;
}
private void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
@ -342,4 +348,79 @@ public class IndexManagerTests extends TestCase {
assertEquals(methodResultModel[i],methodresults[i].toString());
}
}
public void testDependencyTree() throws Exception{
//Add a file to the project
IFile depTest = importFile("DepTest.cpp","resources/dependency/DepTest.cpp");
importFile("DepTest.h","resources/dependency/DepTest.h");
importFile("a.h","resources/dependency/a.h");
importFile("c.h","resources/dependency/c.h");
importFile("d.h","resources/dependency/d.h");
importFile("Inc1.h","resources/dependency/Inc1.h");
importFile("DepTest2.h","resources/dependency/DepTest2.h");
IFile depTest2 = importFile("DepTest2.cpp","resources/dependency/DepTest2.cpp");
//Enable indexing on the created project
//By doing this, we force the Dependency Manager to do a g()
DependencyManager dependencyManager = CCorePlugin.getDefault().getCoreModel().getDependencyManager();
dependencyManager.setEnabled(testProject,true);
Thread.sleep(10000);
String[] depTestModel = {"\\IndexerTestProject\\d.h", "\\IndexerTestProject\\Inc1.h", "\\IndexerTestProject\\c.h", "\\IndexerTestProject\\a.h", "\\IndexerTestProject\\DepTest.h"};
String[] depTest2Model = {"\\IndexerTestProject\\d.h", "\\IndexerTestProject\\DepTest2.h"};
ArrayList includes = new ArrayList();
dependencyManager.performConcurrentJob(new DependencyQueryJob(testProject,depTest,dependencyManager,includes),ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,null);
//Thread.sleep(5000);
String[] depTestModelLocal = convertToLocalPath(depTestModel);
String[] depTestIncludes = new String[includes.size()];
Iterator includesIterator = includes.iterator();
int i=0;
while(includesIterator.hasNext()){
depTestIncludes[i] = (String) includesIterator.next();
i++;
}
if (depTestModelLocal.length != depTestIncludes.length)
fail("Number of included files differsfrom model");
for (i=0;i<depTestIncludes.length; i++)
{
assertEquals(depTestModelLocal[i],depTestIncludes[i]);
}
ArrayList includes2 = new ArrayList();
dependencyManager.performConcurrentJob(new DependencyQueryJob(testProject,depTest2,dependencyManager,includes2),ICSearchConstants.WAIT_UNTIL_READY_TO_SEARCH,null);
//Thread.sleep(5000);
String[] depTest2ModelLocal = convertToLocalPath(depTest2Model);
String[] depTest2Includes = new String[includes2.size()];
Iterator includes2Iterator = includes2.iterator();
i=0;
while(includes2Iterator.hasNext()){
depTest2Includes[i] = (String) includes2Iterator.next();
i++;
}
if (depTest2ModelLocal.length != depTest2Includes.length)
fail("Number of included files differsfrom model");
for (i=0;i<depTest2Includes.length; i++)
{
assertEquals(depTest2ModelLocal[i],depTest2Includes[i]);
}
}
/**
* @param depTestModel
* @return
*/
private String[] convertToLocalPath(String[] model) {
IPath defaultPath = Platform.getLocation();
String[] tempLocalArray = new String[model.length];
for (int i=0;i<model.length;i++){
StringBuffer buffer = new StringBuffer();
buffer.append(defaultPath.toOSString());
buffer.append(model[i]);
tempLocalArray[i]=buffer.toString();
}
return tempLocalArray;
}
}

View file

@ -16,5 +16,6 @@
<classpathentry kind="src" path="/org.eclipse.core.boot"/>
<classpathentry kind="var" path="JRE_LIB" sourcepath="JRE_SRC"/>
<classpathentry kind="src" path="search"/>
<classpathentry kind="src" path="dependency"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -420,7 +420,7 @@ public class ManagedBuildManager implements IScannerInfoProvider {
* @param resource
* @return
*/
private static IScannerInfo getScannerInfo(IResource resource) {
public static IScannerInfo getScannerInfo(IResource resource) {
return (IScannerInfo) getBuildInfo(resource, false);
}

View file

@ -0,0 +1,23 @@
2003-07-23 Bogdan Gheorghe
Added initial dependency implementation
* src/org/eclipse/cdt/internal/core/sourcedependency/AddFileToDependencyTree.java
* src/org/eclipse/cdt/internal/core/sourcedependency/DependencyManager.java
* src/org/eclipse/cdt/internal/core/sourcedependency/DenpendencyQueryJob.java
* src/org/eclipse/cdt/internal/core/sourcedependency/DependencyRequest.java
* src/org/eclipse/cdt/internal/core/sourcedependency/DependencyRequestor.java
* src/org/eclipse/cdt/internal/core/sourcedependency/DependencyTree.java
* src/org/eclipse/cdt/internal/core/sourcedependency/EntireProjectDependencyTree.java
* src/org/eclipse/cdt/internal/core/sourcedependency/IDependencyTree.java
* src/org/eclipse/cdt/internal/core/sourcedependency/IPreprocessorOutput.java
* src/org/eclipse/cdt/internal/core/sourcedependency/ISourceDependency.java
* src/org/eclipse/cdt/internal/core/sourcedependency/PreprocessorOutput.java
* src/org/eclipse/cdt/internal/core/sourcedependency/impl/IncludeEntry.java
* src/org/eclipse/cdt/internal/core/sourcedependency/impl/IncludeEntryHashedArray.java
* src/org/eclipse/cdt/internal/core/sourcedependency/impl/InMemoryTree.java
* src/org/eclipse/cdt/internal/core/sourcedependency/impl/Node.java

View file

@ -0,0 +1,112 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.io.IOException;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.index.IDocument;
import org.eclipse.cdt.internal.core.index.impl.IFileDocument;
import org.eclipse.cdt.internal.core.parser.ScannerInfo;
import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor;
import org.eclipse.cdt.internal.core.search.processing.JobManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
public class AddFileToDependencyTree extends DependencyRequest {
public static final String[] FILE_TYPES= new String[] {"cpp"}; //$NON-NLS-1$
IFile resource;
char[] contents;
IScannerInfo buildInfo;
/**
* @param path
* @param manager
*/
public AddFileToDependencyTree(
IFile resource,
IPath path,
DependencyManager manager,
IScannerInfo info) {
super(path, manager);
this.resource = resource;
this.buildInfo = info;
}
public boolean execute(IProgressMonitor progressMonitor) {
if (progressMonitor != null && progressMonitor.isCanceled()) return true;
/* ensure no concurrent write access to tree */
IDependencyTree tree = manager.getDependencyTree(this.dependencyTreePath, true, /*reuse tree file*/ true /*create if none*/);
if (tree == null) return true;
ReadWriteMonitor monitor = manager.getMonitorFor(tree);
if (monitor == null) return true; // tree got deleted since acquired
try {
monitor.enterWrite(); // ask permission to write
if (!addDocumentToTree(tree)) return false;
} catch (IOException e) {
if (JobManager.VERBOSE) {
JobManager.verbose("-> failed to calculate dependency for " + this.resource + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
e.printStackTrace();
}
return false;
} finally {
monitor.exitWrite(); // free write lock
}
return true;
}
protected boolean addDocumentToTree(IDependencyTree dTree) throws IOException {
if (!initializeContents()) return false;
//Need to create document to get string content...
IDocument document = new IFileDocument(resource, this.contents);
if (!shouldAddToTree(document)) return false;
String docPath = resource.getLocation().toOSString();
IScannerInfo newInfo = new ScannerInfo((this.buildInfo != null) ? this.buildInfo.getDefinedSymbols() : null,(this.buildInfo != null) ? this.buildInfo.getIncludePaths() : null);
dTree.add(document,docPath,newInfo);
return true;
}
public boolean initializeContents() {
if (this.contents == null) {
try {
IPath location = resource.getLocation();
if (location != null)
this.contents = org.eclipse.cdt.internal.core.search.Util.getFileCharContent(location.toFile(), null);
} catch (IOException e) {
}
}
return this.contents != null;
}
public String toString() {
return "calculating dependency for: " + this.resource.getFullPath(); //$NON-NLS-1$
}
public String[] getFileTypes(){
return FILE_TYPES;
}
public boolean shouldAddToTree(IDocument document) {
String type = document.getType();
String[] supportedTypes = this.getFileTypes();
for (int i = 0; i < supportedTypes.length; ++i) {
if (supportedTypes[i].equals(type))
return true;
}
return false;
}
}

View file

@ -0,0 +1,384 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.CRC32;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.search.CharOperation;
import org.eclipse.cdt.internal.core.search.SimpleLookupTable;
import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor;
import org.eclipse.cdt.internal.core.search.processing.JobManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.QualifiedName;
/**
* @author bgheorgh
*/
public class DependencyManager extends JobManager implements ISourceDependency {
/* number of file contents in memory */
public static int MAX_FILES_IN_MEMORY = 0;
public SimpleLookupTable projectNames = new SimpleLookupTable();
private Map dependencyTrees = new HashMap(5);
/* read write monitors */
private Map monitors = new HashMap(5);
/* need to save ? */
private boolean needToSave = false;
private static final CRC32 checksumCalculator = new CRC32();
private IPath ccorePluginLocation = null;
/* can only replace a current state if its less than the new one */
private SimpleLookupTable dTreeStates = null;
private File savedDTreesFile =
new File(getCCorePluginWorkingLocation().append("savedDTrees.txt").toOSString()); //$NON-NLS-1$
public static Integer SAVED_STATE = new Integer(0);
public static Integer UPDATING_STATE = new Integer(1);
public static Integer UNKNOWN_STATE = new Integer(2);
public static Integer REBUILDING_STATE = new Integer(3);
public String processName(){
//TODO: BOG Add name to .properties file
return "Dependency Tree"; //org.eclipse.cdt.internal.core.search.Util.bind("process.name"); //$NON-NLS-1$
}
public void reset(){
super.reset();
//Get handles on the info providers
//register yourself for updates
if (this.dependencyTrees!= null) {
this.dependencyTrees = new HashMap(5);
this.monitors = new HashMap(5);
this.dTreeStates = null;
}
this.projectNames = new SimpleLookupTable();
this.ccorePluginLocation = null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.ISourceDependency#getProjects(org.eclipse.core.resources.IFile)
*/
public IProject[] getProjects(IFile file) {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.ISourceDependency#getFileDependencies(org.eclipse.core.resources.IProject, org.eclipse.core.resources.IFile)
*/
public synchronized String[] getFileDependencies(IProject project, IFile file) {
IPath path =project.getFullPath();
IDependencyTree dTree= this.getDependencyTree(path,true,false);
try{
//dTree.printIncludeEntries();
//dTree.printIndexedFiles();
String[] files = dTree.getFileDependencies(file.getFullPath());
return files;
}
catch(Exception e){}
return null;
}
public synchronized IDependencyTree getDependencyTree(IPath path, boolean reuseExistingFile, boolean createIfMissing) {
IDependencyTree dTree = (IDependencyTree) dependencyTrees.get(path);
if (dTree == null){
String treeName = computeTreeName(path);
Object state = getTreeStates().get(treeName);
Integer currentDTreeState = state == null ? UNKNOWN_STATE : (Integer) state;
if (currentDTreeState == UNKNOWN_STATE) {
// should only be reachable for query jobs
rebuildDTree(treeName, path);
return null;
}
// tree isn't cached, consider reusing an existing tree file
if (reuseExistingFile) {
File treeFile = new File(treeName);
if (treeFile.exists()) { // check before creating tree so as to avoid creating a new empty tree if file is missing
try {
dTree = new DependencyTree(treeName, "Tree for " + path.toOSString(), true /*reuse tree file*/); //$NON-NLS-1$
dependencyTrees.put(path, dTree);
monitors.put(dTree, new ReadWriteMonitor());
return dTree;
} catch (IOException e) {
// failed to read the existing file or its no longer compatible
if (currentDTreeState != REBUILDING_STATE) { // rebuild tree if existing file is corrupt, unless the tree is already being rebuilt
if (VERBOSE)
JobManager.verbose("-> cannot reuse existing tree: "+ treeName +" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
rebuildDTree(treeName, path);
return null;
} else {
dTree = null; // will fall thru to createIfMissing & create a empty tree for the rebuild all job to populate
}
}
}
if (currentDTreeState == SAVED_STATE) { // rebuild tree if existing file is missing
rebuildDTree(treeName, path);
return null;
}
if (createIfMissing) {
try {
if (VERBOSE)
JobManager.verbose("-> create empty tree: "+treeName+" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
dTree = new DependencyTree(treeName, "Tree for " + path.toOSString(), false /*do not reuse tree file*/); //$NON-NLS-1$
dependencyTrees.put(path, dTree);
monitors.put(dTree, new ReadWriteMonitor());
return dTree;
} catch (IOException e) {
if (VERBOSE)
JobManager.verbose("-> unable to create empty tree: "+treeName+" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
// The file could not be created. Possible reason: the project has been deleted.
return null;
}
}
}
}
return dTree;
}
String computeTreeName(IPath path) {
String name = (String) projectNames.get(path);
if (name == null) {
String pathString = path.toOSString();
checksumCalculator.reset();
checksumCalculator.update(pathString.getBytes());
String fileName = Long.toString(checksumCalculator.getValue()) + ".depTree"; //$NON-NLS-1$
if (VERBOSE)
JobManager.verbose("-> dependency tree name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
name = getCCorePluginWorkingLocation().append(fileName).toOSString();
projectNames.put(path, name);
}
return name;
}
private IPath getCCorePluginWorkingLocation() {
if (this.ccorePluginLocation != null) return this.ccorePluginLocation;
return this.ccorePluginLocation = CCorePlugin.getDefault().getStateLocation();
}
/**
* DTree access is controlled through a read-write monitor so as
* to ensure there is no concurrent read and write operations
* (only concurrent reading is allowed).
*/
public ReadWriteMonitor getMonitorFor(IDependencyTree dTree){
return (ReadWriteMonitor) monitors.get(dTree);
}
private SimpleLookupTable getTreeStates() {
if (dTreeStates != null) return dTreeStates;
this.dTreeStates = new SimpleLookupTable();
char[] savedDTreeNames = readDTreeState();
if (savedDTreeNames.length > 0) {
char[][] names = CharOperation.splitOn('\n', savedDTreeNames);
for (int i = 0, l = names.length; i < l; i++) {
char[] name = names[i];
if (name.length > 0)
this.dTreeStates.put(new String(name), SAVED_STATE);
}
}
return this.dTreeStates;
}
private char[] readDTreeState() {
try {
return org.eclipse.cdt.internal.core.search.Util.getFileCharContent(savedDTreesFile, null);
} catch (IOException ignored) {
if (VERBOSE)
JobManager.verbose("Failed to read saved dTree file names"); //$NON-NLS-1$
return new char[0];
}
}
private void rebuildDTree(String treeName, IPath path) {
Object target = org.eclipse.cdt.internal.core.search.Util.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true);
if (target == null) return;
if (VERBOSE)
JobManager.verbose("-> request to rebuild dTree: "+treeName+" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
updateTreeState(treeName, REBUILDING_STATE);
DependencyRequest request = null;
if (target instanceof IProject) {
IProject p = (IProject) target;
request = new EntireProjectDependencyTree(p, this);
}
if (request != null)
request(request);
}
/**
* Trigger addition of the entire content of a project
* Note: the actual operation is performed in background
*/
public void generateEntireDependencyTree(IProject project) {
if (CCorePlugin.getDefault() == null) return;
/******
*TODO: Remove these methods once the depTree is
*fully integrated
*/
if (!isEnabled(project)) return;
// check if the same request is not already in the queue
DependencyRequest request = new EntireProjectDependencyTree(project, this);
for (int i = this.jobEnd; i > this.jobStart; i--) // NB: don't check job at jobStart, as it may have already started (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32488)
if (request.equals(this.awaitingJobs[i])) return;
this.request(request);
}
private void updateTreeState(String treeName, Integer treeState) {
getTreeStates(); // ensure the states are initialized
if (treeState != null) {
if (treeState.equals(dTreeStates.get(treeName))) return; // not changed
dTreeStates.put(treeName, treeState);
} else {
if (!dTreeStates.containsKey(treeName)) return; // did not exist anyway
dTreeStates.removeKey(treeName);
}
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(savedDTreesFile));
Object[] indexNames = dTreeStates.keyTable;
Object[] states = dTreeStates.valueTable;
for (int i = 0, l = states.length; i < l; i++) {
if (states[i] == SAVED_STATE) {
writer.write((String) indexNames[i]);
writer.write('\n');
}
}
} catch (IOException ignored) {
if (VERBOSE)
JobManager.verbose("Failed to write saved dTree file names"); //$NON-NLS-1$
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {}
}
}
if (VERBOSE) {
String state = "?"; //$NON-NLS-1$
if (treeState == SAVED_STATE) state = "SAVED"; //$NON-NLS-1$
else if (treeState == UPDATING_STATE) state = "UPDATING"; //$NON-NLS-1$
else if (treeState == UNKNOWN_STATE) state = "UNKNOWN"; //$NON-NLS-1$
else if (treeState == REBUILDING_STATE) state = "REBUILDING"; //$NON-NLS-1$
JobManager.verbose("-> dTree state updated to: " + state + " for: "+treeName); //$NON-NLS-1$ //$NON-NLS-2$
}
}
public void jobWasCancelled(IPath path) {
Object o = this.dependencyTrees.get(path);
if (o instanceof IDependencyTree) {
this.monitors.remove(o);
this.dependencyTrees.remove(path);
}
updateTreeState(computeTreeName(path), UNKNOWN_STATE);
}
/**
* Trigger removal of a resource from a tree
* Note: the actual operation is performed in background
*/
public void remove(String resourceName, IPath indexedContainer){
//request(new RemoveFromIndex(resourceName, indexedContainer, this));
}
/**
* Removes the tree for a given path.
* This is a no-op if the tree did not exist.
*/
public synchronized void removeTree(IPath path) {
if (VERBOSE)
JobManager.verbose("removing dependency tree " + path); //$NON-NLS-1$
String treeName = computeTreeName(path);
File indexFile = new File(treeName);
if (indexFile.exists())
indexFile.delete();
Object o = this.dependencyTrees.get(path);
if (o instanceof IDependencyTree)
this.monitors.remove(o);
this.dependencyTrees.remove(path);
updateTreeState(treeName, null);
}
/*************
*TODO: Remove these methods once the depTree is
*fully integrated
* START OF TEMP D-TREE ENABLE SECTION
*/
final static String DEP_MODEL_ID = CCorePlugin.PLUGIN_ID + ".dependencytree";
final static String ACTIVATION = "enable";
static QualifiedName activationKey = new QualifiedName(DEP_MODEL_ID, ACTIVATION);
public boolean isEnabled(IProject project) {
String prop = null;
try {
if (project != null) {
prop = project.getPersistentProperty(activationKey);
}
} catch (CoreException e) {
}
return ((prop != null) && prop.equalsIgnoreCase("true"));
}
public void setEnabled(IProject project, boolean on) {
try {
if (project != null) {
Boolean newValue = new Boolean(on);
Boolean oldValue = new Boolean(isEnabled(project));
if (!oldValue.equals(newValue)) {
project.setPersistentProperty(activationKey, newValue.toString());
if (on) {
generateEntireDependencyTree(project);
} else {
//remove(project);
}
}
}
} catch (CoreException e) {
}
}
/**
* @param file
* @param path
* @param info
*/
public void addSource(IFile file, IPath path, IScannerInfo info) {
if (CCorePlugin.getDefault() == null) return;
AddFileToDependencyTree job = new AddFileToDependencyTree(file, path, this, info);
if (this.awaitingJobsCount() < MAX_FILES_IN_MEMORY) {
// reduces the chance that the file is open later on, preventing it from being deleted
if (!job.initializeContents()) return;
}
request(job);
}
/************
* END OF TEMP D-TREE ENABLE SECTION
*/
}

View file

@ -0,0 +1,64 @@
/*
* Created on Jul 23, 2003
*/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.internal.core.search.processing.IJob;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author bgheorgh
*/
public class DependencyQueryJob implements IJob {
IProject project;
IFile file;
ArrayList includeFiles;
DependencyManager depManager;
public DependencyQueryJob(IProject project, IFile file, DependencyManager depMan, List includeFiles) {
this.project = project;
this.file = file;
this.depManager = depMan;
this.includeFiles = (ArrayList) includeFiles;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.search.processing.IJob#belongsTo(java.lang.String)
*/
public boolean belongsTo(String jobFamily) {
// TODO Auto-generated method stub
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.search.processing.IJob#cancel()
*/
public void cancel() {}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.search.processing.IJob#execute(org.eclipse.core.runtime.IProgressMonitor)
*/
public boolean execute(IProgressMonitor progress) {
String[] tempFiles = this.depManager.getFileDependencies(project,file);
for (int i=0; i<tempFiles.length; i++){
includeFiles.add(tempFiles[i]);
}
return true;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.search.processing.IJob#isReadyToRun()
*/
public boolean isReadyToRun() {
// TODO Auto-generated method stub
return true;
}
}

View file

@ -0,0 +1,64 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.io.IOException;
import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor;
import org.eclipse.cdt.internal.core.search.processing.IJob;
import org.eclipse.core.runtime.IPath;
public abstract class DependencyRequest implements IJob {
protected boolean isCancelled = false;
protected DependencyManager manager;
protected IPath dependencyTreePath;
public DependencyRequest(IPath path, DependencyManager manager) {
this.dependencyTreePath = path;
this.manager = manager;
}
public DependencyRequest(DependencyManager manager) {
this.manager = manager;
}
public boolean belongsTo(String projectName) {
return projectName.equals(this.dependencyTreePath.segment(0));
}
public void cancel() {
this.manager.jobWasCancelled(this.dependencyTreePath);
this.isCancelled = true;
}
public boolean isReadyToRun() {
return true;
}
/*
* This code is assumed to be invoked while monitor has read lock
*/
protected void saveIfNecessary(IDependencyTree tree, ReadWriteMonitor monitor) throws IOException {
/* if tree has changed, commit these before querying */
if (tree.hasChanged()) {
try {
monitor.exitRead(); // free read lock
monitor.enterWrite(); // ask permission to write
//this.manager.saveTree(tree);
} finally {
monitor.exitWriteEnterRead(); // finished writing and reacquire read permission
}
}
}
protected Integer updatedIndexState() {
return DependencyManager.UPDATING_STATE;
}
}

View file

@ -0,0 +1,60 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.util.LinkedList;
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
import org.eclipse.cdt.internal.core.index.IDocument;
import org.eclipse.cdt.internal.core.parser.NullSourceElementRequestor;
public class DependencyRequestor extends NullSourceElementRequestor {
PreprocessorOutput preprocessor;
IDocument document;
private IASTInclusion currentInclude = null;
private LinkedList includeStack = new LinkedList();
public DependencyRequestor(PreprocessorOutput p, IDocument doc){
this.preprocessor = p;
this.document = doc;
}
public void enterInclusion(IASTInclusion inclusion) {
//System.out.println("enterInclusion " + inclusion.getName());
//Get parent
IASTInclusion parent = peekInclude();
preprocessor.addInclude(inclusion, parent);
//Push on stack
pushInclude(inclusion);
}
public void exitInclusion(IASTInclusion inclusion) {
// TODO Auto-generated method stub
//System.out.println("Exit inclusion " + inclusion.getFullFileName());
//Pop
popInclude();
}
private void pushInclude( IASTInclusion inclusion ){
includeStack.addFirst( currentInclude );
currentInclude = inclusion;
}
private IASTInclusion popInclude(){
IASTInclusion oldInclude = currentInclude;
currentInclude = (includeStack.size() > 0 ) ? (IASTInclusion) includeStack.removeFirst() : null;
return oldInclude;
}
private IASTInclusion peekInclude(){
return currentInclude;
}
}

View file

@ -0,0 +1,174 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.core.parser.IPreprocessor;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.internal.core.index.IDocument;
import org.eclipse.cdt.internal.core.index.IQueryResult;
import org.eclipse.cdt.internal.core.index.impl.IndexedFile;
import org.eclipse.cdt.internal.core.sourcedependency.impl.InMemoryTree;
import org.eclipse.cdt.internal.core.sourcedependency.impl.IncludeEntry;
import org.eclipse.core.runtime.IPath;
public class DependencyTree implements IDependencyTree {
protected InMemoryTree addsTree;
public DependencyTree(String treeName, String string, boolean b) throws IOException{
initialize();
}
public DependencyTree() throws IOException {
initialize();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#empty()
*/
public void empty() throws IOException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#getIndexFile()
*/
public File getIndexFile() {
// TODO Auto-generated method stub
return null;
}
/**
* Returns the number of referencing files in this tree.
*/
public int getNumDocuments() throws IOException {
return addsTree.getNumFiles();
}
/**
* Returns the number of include entries in this tree.
* @return
* @throws IOException
*/
public int getNumIncludes() throws IOException {
return addsTree.getNumIncludes();
}
/**
* Returns the path corresponding to a given document number
*/
public String getPath(int documentNumber) throws IOException {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#hasChanged()
*/
public boolean hasChanged() {
// TODO Auto-generated method stub
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#query(java.lang.String)
*/
public IQueryResult[] query(String word) throws IOException {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#queryInDocumentNames(java.lang.String)
*/
public IQueryResult[] queryInDocumentNames(String word)
throws IOException {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#save()
*/
public void save() throws IOException {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#remove(java.lang.String)
*/
public void remove(String documentName) throws IOException {
// TODO Auto-generated method stub
}
/**
* Add the file that will be preprocessed to the tree, create a new
* preprocessor output and preprocess!
*/
public void add(IDocument document, String docPath, IScannerInfo newInfo) throws IOException {
IndexedFile indexedFile= addsTree.getIndexedFile(document.getName());
//if (indexedFile != null)
//remove(indexedFile, 0);
PreprocessorOutput output= new PreprocessorOutput(addsTree);
DependencyRequestor depReq = new DependencyRequestor(output,document);
output.addDocument(document);
IPreprocessor preprocessor = ParserFactory.createPreprocessor( new StringReader( document.getStringContent() ),docPath , newInfo, ParserMode.COMPLETE_PARSE,depReq);
preprocessor.process();
}
/**
* Initialises the indexGenerator.
*/
public void initialize() throws IOException {
//initialisation of addsTree
addsTree= new InMemoryTree();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.sourcedependency.IDependencyTree#getFileDepencies(int)
*/
public String[] getFileDependencies(IPath filePath) throws IOException {
List tempFileReturn = new ArrayList();
IndexedFile indexFile = addsTree.getIndexedFile(filePath.toString());
int fileNum = indexFile.getFileNumber();
IncludeEntry[] tempEntries = addsTree.getIncludeEntries();
for (int i=0; i<tempEntries.length; i++)
{
int[] fileRefs = tempEntries[i].getRefs();
for (int j=0; j<fileRefs.length; j++)
{
if (fileRefs[j] == fileNum)
{
//System.out.println(filePath.toString() + " references " + y[i].toString());
char[] tempFile = tempEntries[i].getFile();
StringBuffer tempString = new StringBuffer();
tempString.append(tempFile);
tempFileReturn.add(tempString.toString());
break;
}
}
}
return (String []) tempFileReturn.toArray(new String[tempFileReturn.size()]);
}
//TODO: BOG Debug Method Take out
public void printIncludeEntries(){
IncludeEntry[] tempEntries = addsTree.getIncludeEntries();
for (int i=0; i<tempEntries.length; i++){
System.out.println(tempEntries[i].toString());
}
}
//TODO: BOG Debug Method Take out
public void printIndexedFiles() {
IndexedFile[] tempFiles = addsTree.getIndexedFiles();
for (int i=0;i<tempFiles.length;i++){
System.out.println(tempFiles[i].toString());
}
}
}

View file

@ -0,0 +1,192 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.util.HashSet;
import org.eclipse.cdt.core.build.managed.ManagedBuildManager;
import org.eclipse.cdt.internal.core.index.IQueryResult;
import org.eclipse.cdt.internal.core.index.impl.IFileDocument;
import org.eclipse.cdt.internal.core.search.SimpleLookupTable;
import org.eclipse.cdt.internal.core.search.Util;
import org.eclipse.cdt.internal.core.search.indexing.ReadWriteMonitor;
import org.eclipse.cdt.internal.core.search.processing.JobManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
/**
* @author bgheorgh
*/
public class EntireProjectDependencyTree extends DependencyRequest {
IProject project;
public EntireProjectDependencyTree(IProject project, DependencyManager manager) {
super(project.getFullPath(), manager);
this.project = project;
}
public boolean equals(Object o) {
if (o instanceof EntireProjectDependencyTree)
return this.project.equals(((EntireProjectDependencyTree) o).project);
return false;
}
public boolean execute(IProgressMonitor progressMonitor) {
if (progressMonitor != null && progressMonitor.isCanceled()) return true;
if (!project.isAccessible()) return true; // nothing to do
IDependencyTree dTree = this.manager.getDependencyTree(this.dependencyTreePath, true, /*reuse index file*/ true /*create if none*/);
if (dTree == null) return true;
ReadWriteMonitor monitor = this.manager.getMonitorFor(dTree);
if (monitor == null) return true; // tree got deleted since acquired
try {
monitor.enterRead(); // ask permission to read
saveIfNecessary(dTree, monitor);
IQueryResult[] results = dTree.queryInDocumentNames(""); // get all file names already stored in this project //$NON-NLS-1$
int max = results == null ? 0 : results.length;
final SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11);
final String OK = "OK"; //$NON-NLS-1$
final String DELETED = "DELETED"; //$NON-NLS-1$
for (int i = 0; i < max; i++)
indexedFileNames.put(results[i].getPath(), DELETED);
final long indexLastModified = max == 0 ? 0L : dTree.getIndexFile().lastModified();
IPath cProjectPath = project.getFullPath();
IWorkspaceRoot root = this.project.getWorkspace().getRoot();
IResource sourceFolder = root.findMember(cProjectPath);
if (this.isCancelled) return false;
if (sourceFolder != null) {
//collect output locations if source is project (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32041)
final HashSet outputs = new HashSet();
final boolean hasOutputs = !outputs.isEmpty();
final char[][] patterns = null;
if (max == 0) {
sourceFolder.accept(
new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) {
if (isCancelled) return false;
switch(proxy.getType()) {
case IResource.FILE :
// TODO: BOG Put the file name checking back
//if (Util.isCCFileName(proxy.getName())) {
IResource resource = proxy.requestResource();
if (resource.getLocation() != null && (patterns == null || !Util.isExcluded(resource, patterns))) {
String name = new IFileDocument((IFile) resource).getName();
indexedFileNames.put(name, resource);
}
//}
return false;
case IResource.FOLDER :
if (patterns != null && Util.isExcluded(proxy.requestResource(), patterns))
return false;
if (hasOutputs && outputs.contains(proxy.requestFullPath())) {
return false;
}
}
return true;
}
},
IResource.NONE
);
} else {
sourceFolder.accept(
new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) {
if (isCancelled) return false;
switch(proxy.getType()) {
case IResource.FILE :
// TODO: BOG Put the file name checking back
// if (Util.isCCFileName(proxy.getName())) {
IResource resource = proxy.requestResource();
IPath path = resource.getLocation();
if (path != null && (patterns == null || !Util.isExcluded(resource, patterns))) {
String name = new IFileDocument((IFile) resource).getName();
indexedFileNames.put(name,
indexedFileNames.get(name) == null || indexLastModified < path.toFile().lastModified()
? (Object) resource
: (Object) OK);
}
//}
return false;
case IResource.FOLDER :
if (patterns != null && Util.isExcluded(proxy.requestResource(), patterns))
return false;
if (hasOutputs && outputs.contains(proxy.requestFullPath())) {
return false;
}
}
return true;
}
},
IResource.NONE
);
}
}
Object[] names = indexedFileNames.keyTable;
Object[] values = indexedFileNames.valueTable;
boolean shouldSave = false;
for (int i = 0, length = names.length; i < length; i++) {
String name = (String) names[i];
if (name != null) {
if (this.isCancelled) return false;
Object value = values[i];
if (value != OK) {
shouldSave = true;
if (value == DELETED)
this.manager.remove(name, this.dependencyTreePath);
else
this.manager.addSource((IFile) value, this.dependencyTreePath, ManagedBuildManager.getScannerInfo(project));
}
}
}
} catch (/*IO*/Exception e) {
if (JobManager.VERBOSE) {
JobManager.verbose("-> failed to generate tree " + this.project + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
e.printStackTrace();
}
this.manager.removeTree(this.dependencyTreePath);
return false;
} finally {
monitor.exitRead(); // free read lock
}
return true;
}
public int hashCode() {
return this.project.hashCode();
}
protected Integer updatedIndexState() {
return DependencyManager.REBUILDING_STATE;
}
public String toString() {
return "calculating dependency tree for project " + this.project.getFullPath(); //$NON-NLS-1$
}
}

View file

@ -0,0 +1,82 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import java.io.File;
import java.io.IOException;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.index.IDocument;
import org.eclipse.cdt.internal.core.index.IQueryResult;
import org.eclipse.core.runtime.IPath;
public interface IDependencyTree {
/**
* Adds the given document to the index.
*/
void add(IDocument document, String docPath, IScannerInfo newInfo) throws IOException;
/**
* Empties the index.
*/
void empty() throws IOException;
/**
* Returns the index file on the disk.
*/
File getIndexFile();
/**
* Returns the number of documents indexed.
*/
int getNumDocuments() throws IOException;
/**
* Returns the number of unique words indexed.
*/
int getNumIncludes() throws IOException;
/**
* Returns the path corresponding to a given document number
*/
String getPath(int documentNumber) throws IOException;
/**
* Ansers true if has some changes to save.
*/
boolean hasChanged();
/**
* Returns the paths of the documents containing the given word.
*/
IQueryResult[] query(String word) throws IOException;
/**
* Returns the paths of the documents whose names contain the given word.
*/
IQueryResult[] queryInDocumentNames(String word) throws IOException;
/**
* Removes the corresponding document from the tree.
*/
void remove(String documentName) throws IOException;
/**
* Saves the index on the disk.
*/
void save() throws IOException;
/**
* Gets the files that are included by the passed in file.
*/
String[] getFileDependencies(IPath filePath) throws IOException;
// TODO: BOG Debug Method Take out
/**
* Prints all of the IncludeEntries for this project.
*/
public void printIncludeEntries();
// TODO: BOG Debug Method Take out
/**
* Prints all of the IndexedFiles for this project.
*/
public void printIndexedFiles();
}

View file

@ -0,0 +1,20 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import org.eclipse.cdt.internal.core.index.IDocument;
public interface IPreprocessorOutput {
public void addDocument(IDocument document);
public void addRef(char[] word);
public void addRef(String word);
}

View file

@ -0,0 +1,19 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
public interface ISourceDependency {
IProject[] getProjects(IFile file);
String[] getFileDependencies(IProject project, IFile file);
}

View file

@ -0,0 +1,58 @@
/**********************************************************************
* Copyright (c) 2002,2003 Rational Software Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v0.5
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v05.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
***********************************************************************/
package org.eclipse.cdt.internal.core.sourcedependency;
import org.eclipse.cdt.core.parser.ast.IASTInclusion;
import org.eclipse.cdt.internal.core.index.IDocument;
import org.eclipse.cdt.internal.core.index.impl.IndexedFile;
import org.eclipse.cdt.internal.core.sourcedependency.impl.InMemoryTree;
public class PreprocessorOutput implements IPreprocessorOutput {
protected InMemoryTree tree;
protected IndexedFile indexedFile;
protected IDocument document;
public PreprocessorOutput(InMemoryTree tree) {
this.tree = tree;
}
public void addInclude(IASTInclusion inclusion, IASTInclusion parent){
addRef(inclusion.getFullFileName());
addRelatives(inclusion.getFullFileName(),(parent != null ) ? parent.getFullFileName() : null);
}
public void addRelatives(String inclusion, String parent) {
if (indexedFile == null) {
throw new IllegalStateException();
}
tree.addRelatives(indexedFile, inclusion, parent);
}
public void addDocument(IDocument document) {
if (indexedFile == null) {
indexedFile= tree.addDocument(document);
} else {
throw new IllegalStateException();
}
}
public void addRef(char[] word) {
if (indexedFile == null) {
throw new IllegalStateException();
}
tree.addRef(indexedFile, word);
}
public void addRef(String word) {
addRef(word.toCharArray());
}
}

View file

@ -0,0 +1,143 @@
/*******************************************************************************
* 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.sourcedependency.impl;
import org.eclipse.cdt.internal.core.index.IDocument;
import org.eclipse.cdt.internal.core.index.impl.IndexedFile;
import org.eclipse.cdt.internal.core.index.impl.IndexedFileHashedArray;
public class InMemoryTree {
/**
* hashtable of IncludeEntrys = includeFiles+numbers of the files they appear in.
*/
protected IncludeEntryHashedArray includes;
/**
* List of IndexedFiles = file name + a unique number.
*/
protected IndexedFileHashedArray files;
/**
* Size of the tree.
*/
protected long footprint;
private int lastId;
public InMemoryTree() {
init();
}
/**
* Initialises the fields of the tree
*/
public void init() {
includes= new IncludeEntryHashedArray(501);
files= new IndexedFileHashedArray(101);
footprint= 0;
lastId=0;
}
public IndexedFile addDocument(IDocument document) {
IndexedFile indexedFile= this.files.add(document);
this.footprint += indexedFile.footprint() + 4;
return indexedFile;
}
/**
* Adds the references of the include to the tree (reference = number of the file the include belongs to).
*/
protected void addRef(char[] include, int[] references) {
int size= references.length;
int i= 0;
while (i < size) {
if (references[i] != 0)
addRef(include, references[i]);
i++;
}
}
/**
* Looks if the include already exists to the tree and adds the fileNum to this include.
* If the include does not exist, it adds it to the tree.
*/
protected void addRef(char[] include, int fileNum) {
IncludeEntry entry= (IncludeEntry) this.includes.get(include);
if (entry == null) {
entry= new IncludeEntry(include, ++lastId);
entry.addRef(fileNum);
this.includes.add(entry);
} else {
this.footprint += entry.addRef(fileNum);
}
}
public void addRef(IndexedFile indexedFile, char[] include) {
addRef(include, indexedFile.getFileNumber());
}
public void addRef(IndexedFile indexedFile, String include) {
addRef(include.toCharArray(), indexedFile.getFileNumber());
}
/**
* Returns the indexed file with the given path, or null if such file does not exist.
*/
public IndexedFile getIndexedFile(String path) {
return files.get(path);
}
/**
* @see IIndex#getNumDocuments()
*/
public int getNumFiles() {
return files.size();
}
/**
* @see IIndex#getNumWords()
*/
public int getNumIncludes() {
return includes.elementSize;
}
/**
* Returns the include entry corresponding to the given include.
*/
protected IncludeEntry getIncludeEntry(char[] include) {
return (IncludeEntry) includes.get(include);
}
public void addRelatives(IndexedFile indexedFile, String inclusion, String parent) {
addRelatives(indexedFile.getFileNumber(),inclusion.toCharArray(),(parent != null ) ? parent.toCharArray() : null);
}
protected void addRelatives(int fileNumber, char[] inclusion, char[] parent) {
IncludeEntry childEntry=null;
IncludeEntry parentEntry=null;
if (inclusion != null)
childEntry= (IncludeEntry) this.includes.get(inclusion);
if (parent != null)
parentEntry= (IncludeEntry) this.includes.get(parent);
childEntry.addParent(fileNumber,(parentEntry!=null) ? parentEntry.getID() : -1);
if (parent!=null)
parentEntry.addChild(fileNumber,(childEntry!=null) ? childEntry.getID() : -1);
}
/**
* Returns the include entries contained in the hashtable of includes.
*/
public IncludeEntry[] getIncludeEntries() {
return this.includes.asArray();
}
public IndexedFile[] getIndexedFiles(){
return this.files.asArray();
}
}

View file

@ -0,0 +1,159 @@
/*******************************************************************************
* 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.sourcedependency.impl;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.cdt.internal.core.search.CharOperation;
/**
* @author bgheorgh
*/
public class IncludeEntry {
protected char[] fFile;
protected int fId;
protected int fNumRefs;
protected int[] fRefs;
//TODO: BOG Consider making these arrays...
protected ArrayList fParent;
protected ArrayList fChild;
protected int fNumParent;
protected int fNumChild;
public IncludeEntry(int id) {
this(CharOperation.NO_CHAR,id);
}
public IncludeEntry(char[] file, int id) {
fFile = file;
fNumRefs= 0;
fRefs= new int[1];
fId=id;
fParent = new ArrayList(5);
fChild = new ArrayList(5);
fNumParent = 0;
fNumChild = 0;
}
/**
* Adds a reference and records the change in footprint.
*/
public int addRef(int fileNum) {
if (fNumRefs > 0 && fRefs[fNumRefs - 1] == fileNum) {
return 0;
}
if (fNumRefs < fRefs.length) {
fRefs[fNumRefs++]= fileNum;
return 0;
}
int newSize= fNumRefs < 4 ? 4 : fNumRefs * 2; // so will start @ 1, grow to 4, 8, 16, 32, 64 etc.
System.arraycopy(fRefs, 0, fRefs= new int[newSize], 0, fNumRefs);
fRefs[fNumRefs++]= fileNum;
return (newSize - fNumRefs + 1) * 4;
}
public void addParent(int fileRef, int parentId){
Node newParent = new Node(fileRef,parentId);
fParent.add(newParent);
fNumParent++;
}
public void addChild(int fileRef, int parentId){
Node newChild = new Node(fileRef,parentId);
fChild.add(newChild);
fNumChild++;
}
/**
* Returns the number of references, e.g. the number of files this word appears in.
*/
public int getNumRefs() {
return fNumRefs;
}
/**
* returns the file number in the i position in the list of references.
*/
public int getRef(int i) {
if (i < fNumRefs) return fRefs[i];
throw new IndexOutOfBoundsException();
}
/**
* Returns the references of the includeEntry (the number of the files it appears in).
*/
public int[] getRefs() {
int[] result= new int[fNumRefs];
System.arraycopy(fRefs, 0, result, 0, fNumRefs);
return result;
}
/**
* returns the word of the includeEntry.
*/
public char[] getFile() {
return fFile;
}
/**
* Clears the includeEntry.
*/
public void reset(char[] word) {
for (int i= fNumRefs; i-- > 0;) {
fRefs[i]= 0;
}
fNumRefs= 0;
fFile= word;
}
public int getID(){
return fId;
}
public String toString() {
StringBuffer tempBuffer = new StringBuffer();
tempBuffer.append("<Name: ");
tempBuffer.append(fFile);
tempBuffer.append(", Id: ");
tempBuffer.append(fId);
tempBuffer.append(", Refs:{");
for (int i = 0; i < fRefs.length; i++){
if (i > 0) tempBuffer.append(',');
tempBuffer.append(' ');
tempBuffer.append(fRefs[i]);
}
tempBuffer.append("}, Parents:{");
Iterator x = fParent.iterator();
while (x.hasNext())
{
Node tempNode = (Node) x.next();
tempBuffer.append(tempNode.toString());
if (x.hasNext()) {
tempBuffer.append(',');
tempBuffer.append(' ');
}
}
tempBuffer.append("}, Children:{");
Iterator y = fChild.iterator();
while (y.hasNext())
{
Node tempNode = (Node) y.next();
tempBuffer.append(tempNode.toString());
if (y.hasNext()) {
tempBuffer.append(',');
tempBuffer.append(' ');
}
}
tempBuffer.append("} >");
return tempBuffer.toString();
}
}

View file

@ -0,0 +1,84 @@
/*******************************************************************************
* 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.sourcedependency.impl;
import org.eclipse.cdt.internal.core.search.CharOperation;
public final class IncludeEntryHashedArray {
public IncludeEntry elements[];
public int elementSize; // number of elements in the table
public int threshold;
public IncludeEntryHashedArray(int size) {
if (size < 7) size = 7;
this.elements = new IncludeEntry[2 * size + 1];
this.elementSize = 0;
this.threshold = size + 1; // size is the expected number of elements
}
public IncludeEntry add(IncludeEntry entry) {
int length = elements.length;
char[] word = entry.getFile();
int index = CharOperation.hashCode(word) % length;
IncludeEntry current;
while ((current = elements[index]) != null) {
if (CharOperation.equals(current.getFile(), word)) return elements[index] = entry;
if (++index == length) index = 0;
}
elements[index] = entry;
// assumes the threshold is never equal to the size of the table
if (++elementSize > threshold) grow();
return entry;
}
public IncludeEntry[] asArray() {
IncludeEntry[] array = new IncludeEntry[elementSize];
for (int i = 0, j = 0, length = elements.length; i < length; i++) {
IncludeEntry current = elements[i];
if (current != null) array[j++] = current;
}
return array;
}
public IncludeEntry get(char[] word) {
int length = elements.length;
int index = CharOperation.hashCode(word) % length;
IncludeEntry current;
while ((current = elements[index]) != null) {
if (CharOperation.equals(current.getFile(), word)) return current;
if (++index == length) index = 0;
}
return null;
}
private void grow() {
IncludeEntryHashedArray newArray = new IncludeEntryHashedArray(elementSize * 2); // double the number of expected elements
for (int i = 0, length = elements.length; i < length; i++)
if (elements[i] != null)
newArray.add(elements[i]);
this.elements = newArray.elements;
this.elementSize = newArray.elementSize;
this.threshold = newArray.threshold;
}
public String toString() {
String s = ""; //$NON-NLS-1$
IncludeEntry[] entries = asArray();
for (int i = 0, length = entries.length; i < length; i++)
s += entries[i].toString() + "\n"; //$NON-NLS-1$
return s;
}
}

View file

@ -0,0 +1,45 @@
/*******************************************************************************
* 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.sourcedependency.impl;
/**
* @author bgheorgh
*/
public class Node {
int fileRef;
int nodeId;
public Node(int file, int id){
this.fileRef = file;
this.nodeId = id;
}
public int getFileRef(){
return fileRef;
}
public int getNodeId(){
return nodeId;
}
public String toString() {
StringBuffer tempBuffer = new StringBuffer();
tempBuffer.append("[FileRef: ");
tempBuffer.append(fileRef);
tempBuffer.append(", Id: ");
tempBuffer.append(nodeId);
tempBuffer.append("]");
return tempBuffer.toString();
}
}

View file

@ -9,6 +9,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.internal.core.model.BatchOperation;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.cdt.internal.core.sourcedependency.DependencyManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
@ -226,4 +227,11 @@ public class CoreModel {
return manager.getIndexManager();
}
public void startDependencyService() {
manager.getSourceDependencyManager().reset();
}
public DependencyManager getDependencyManager(){
return manager.getSourceDependencyManager();
}
}

View file

@ -43,6 +43,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.cdt.internal.core.sourcedependency.DependencyManager;
public class CModelManager implements IResourceChangeListener {
@ -777,4 +778,8 @@ public class CModelManager implements IResourceChangeListener {
this.getIndexManager().discardJobs(project.getName());
}
public DependencyManager getSourceDependencyManager() {
return this.fDeltaProcessor.sourceDependencyManager;
}
}

View file

@ -21,6 +21,7 @@ import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.IPath;
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.cdt.internal.core.sourcedependency.DependencyManager;
/**
* This class is used by <code>CModelManager</code> to convert
@ -36,7 +37,9 @@ public class DeltaProcessor {
protected CElementDelta fCurrentDelta;
protected IndexManager indexManager = new IndexManager();
protected DependencyManager sourceDependencyManager = new DependencyManager();
/* The C element that was last created (see createElement(IResource).
* This is used as a stack of C elements (using getParent() to pop it, and
* using the various get*(...) to push it. */

View file

@ -189,6 +189,9 @@ public class CCorePlugin extends Plugin {
//Fired up the new indexer
fCoreModel.startIndexing();
//Fire up dependency manager
fCoreModel.startDependencyService();
fDescriptorManager = new CDescriptorManager();
fDescriptorManager.startup();

View file

@ -1,3 +1,7 @@
2003-07-23 Bogdan Gheorghe
Added checkbox to Indexer tab to turn on dependency tree
service
2003-07-21 Bogdan Gheorghe
Update to CSearchResultLabelProvider to ensure that search labels
show up on subsequent runs.

View file

@ -8,6 +8,7 @@ package org.eclipse.cdt.ui.wizards;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IndexModel;
import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.cdt.internal.core.sourcedependency.DependencyManager;
import org.eclipse.cdt.utils.ui.swt.IValidation;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
@ -20,6 +21,7 @@ import org.eclipse.swt.widgets.Composite;
public class IndexerBlock implements IWizardTab {
private Button indexerSwitch;
private Button indexerSwitch2;
private Button dTreeSwitch;
IProject project;
IValidation page;
@ -48,6 +50,12 @@ public class IndexerBlock implements IWizardTab {
indexerSwitch2.setAlignment(SWT.LEFT);
indexerSwitch2.setText("Enable NEW indexing service for this project");
indexerSwitch2.setSelection(false);
dTreeSwitch = new Button(composite, SWT.CHECK | SWT.RIGHT);
dTreeSwitch.setAlignment(SWT.LEFT);
dTreeSwitch.setText("Enable dependency tree service for this project");
dTreeSwitch.setSelection(false);
return composite;
}
@ -60,6 +68,9 @@ public class IndexerBlock implements IWizardTab {
IndexManager newIndexer = CCorePlugin.getDefault().getCoreModel().getIndexManager();
newIndexer.setEnabled(project, indexerSwitch2.getSelection());
DependencyManager depManager = CCorePlugin.getDefault().getCoreModel().getDependencyManager();
depManager.setEnabled(project, dTreeSwitch.getSelection());
}
@ -98,11 +109,15 @@ public class IndexerBlock implements IWizardTab {
}
if (indexerSwitch2 != null) {
//indexerSwitch.setAlignment(SWT.LEFT);
//indexerSwitch.setText("Enable indexing service for this project");
indexerSwitch2.setSelection(newIndexer.isEnabled(project));
}
DependencyManager depManager = CCorePlugin.getDefault().getCoreModel().getDependencyManager();
if (dTreeSwitch != null) {
dTreeSwitch.setSelection(depManager.isEnabled(project));
}
}