mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Moved the PDOM into the Core. Started introduction of ILanguage, the mechanism of language extensibility for the CDT.
This commit is contained in:
parent
7d0a99f4e8
commit
41d26bc514
48 changed files with 3198 additions and 44 deletions
|
@ -0,0 +1,145 @@
|
|||
package org.eclipse.cdt.internal.pdom.tests;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.StringComparator;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.StringVisitor;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
||||
public class DBTest extends TestCase {
|
||||
|
||||
protected IPath getTestDir() {
|
||||
IPath path = PDOMCorePlugin.getDefault().getStateLocation().append("tests/");
|
||||
File file = path.toFile();
|
||||
if (!file.exists())
|
||||
file.mkdir();
|
||||
return path;
|
||||
}
|
||||
|
||||
public void test1() throws Exception {
|
||||
// Tests block size and simple first block
|
||||
File f = getTestDir().append("test1.dat").toFile();
|
||||
f.delete();
|
||||
Database db = new Database(f.getCanonicalPath(), 0);
|
||||
|
||||
final int realsize = 42;
|
||||
final int blocksize = (realsize / Database.MIN_SIZE + 1) * Database.MIN_SIZE;
|
||||
|
||||
int mem = db.malloc(realsize);
|
||||
assertEquals(-blocksize, db.getInt(mem - Database.INT_SIZE));
|
||||
db.free(mem);
|
||||
assertEquals(blocksize, db.getInt(mem - Database.INT_SIZE));
|
||||
assertEquals(mem - Database.INT_SIZE, db.getInt((blocksize / Database.MIN_SIZE) * Database.INT_SIZE));
|
||||
assertEquals(mem - Database.INT_SIZE + blocksize, db.getInt(((Database.CHUNK_SIZE - blocksize) / Database.MIN_SIZE) * Database.INT_SIZE));
|
||||
}
|
||||
|
||||
public void test2() throws Exception {
|
||||
// Tests free block linking
|
||||
File f = getTestDir().append("test2.dat").toFile();
|
||||
f.delete();
|
||||
Database db = new Database(f.getCanonicalPath(), 0);
|
||||
|
||||
final int realsize = 42;
|
||||
final int blocksize = (realsize / Database.MIN_SIZE + 1) * Database.MIN_SIZE;
|
||||
|
||||
int mem1 = db.malloc(realsize);
|
||||
int mem2 = db.malloc(realsize);
|
||||
db.free(mem1);
|
||||
db.free(mem2);
|
||||
assertEquals(mem2 - Database.INT_SIZE, db.getInt((blocksize / Database.MIN_SIZE) * Database.INT_SIZE));
|
||||
assertEquals(0, db.getInt(mem2));
|
||||
assertEquals(mem1 - Database.INT_SIZE, db.getInt(mem2 + Database.INT_SIZE));
|
||||
assertEquals(mem2 - Database.INT_SIZE, db.getInt(mem1));
|
||||
assertEquals(0, db.getInt(mem1 + Database.INT_SIZE));
|
||||
}
|
||||
|
||||
public void test3() throws Exception {
|
||||
//
|
||||
File f = getTestDir().append("test2.dat").toFile();
|
||||
f.delete();
|
||||
Database db = new Database(f.getCanonicalPath(), 0);
|
||||
|
||||
int mem1 = db.malloc(42);
|
||||
db.free(mem1);
|
||||
int mem2 = db.malloc(42);
|
||||
assertEquals(mem2, mem1);
|
||||
}
|
||||
|
||||
private static class FindVisitor extends StringVisitor {
|
||||
|
||||
private int record;
|
||||
|
||||
public FindVisitor(Database db, String key) {
|
||||
super(db, Database.INT_SIZE, key);
|
||||
}
|
||||
|
||||
public boolean visit(int record) throws IOException {
|
||||
this.record = record;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int findIn(BTree btree) throws IOException {
|
||||
btree.visit(this);
|
||||
return record;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testStrings() throws Exception {
|
||||
// Tests inserting and retrieving strings
|
||||
File f = getTestDir().append("testStrings.dat").toFile();
|
||||
f.delete();
|
||||
Database db = new Database(f.getCanonicalPath(), 0);
|
||||
|
||||
String[] names = {
|
||||
"ARLENE",
|
||||
"BRET",
|
||||
"CINDY",
|
||||
"DENNIS",
|
||||
"EMILY",
|
||||
"FRANKLIN",
|
||||
"GERT",
|
||||
"HARVEY",
|
||||
"IRENE",
|
||||
"JOSE",
|
||||
"KATRINA",
|
||||
"LEE",
|
||||
"MARIA",
|
||||
"NATE",
|
||||
"OPHELIA",
|
||||
"PHILIPPE",
|
||||
"RITA",
|
||||
"STAN",
|
||||
"TAMMY",
|
||||
"VINCE",
|
||||
"WILMA",
|
||||
"ALPHA",
|
||||
"BETA"
|
||||
};
|
||||
|
||||
BTree btree = new BTree(db, Database.DATA_AREA);
|
||||
for (int i = 0; i < names.length; ++i) {
|
||||
String name = names[i];
|
||||
int record = db.malloc((name.length() + 1) * Database.CHAR_SIZE + Database.INT_SIZE);
|
||||
db.putInt(record, i);
|
||||
db.putString(record + Database.INT_SIZE, name);
|
||||
btree.insert(record, new StringComparator(db, Database.INT_SIZE));
|
||||
}
|
||||
|
||||
for (int i = 0; i < names.length; ++i) {
|
||||
String name = names[i];
|
||||
int record = new FindVisitor(db, name).findIn(btree);
|
||||
assertTrue(record != 0);
|
||||
assertEquals(i, db.getInt(record));
|
||||
String rname = db.getString(record + Database.INT_SIZE);
|
||||
assertEquals(name, rname);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -55,6 +55,8 @@ Export-Package: .,
|
|||
org.eclipse.cdt.internal.core.parser.scanner2,
|
||||
org.eclipse.cdt.internal.core.parser.token,
|
||||
org.eclipse.cdt.internal.core.parser.util,
|
||||
org.eclipse.cdt.internal.core.pdom,
|
||||
org.eclipse.cdt.internal.core.pdom.db;x-friends:="org.eclipse.cdt.pdom.ui",
|
||||
org.eclipse.cdt.internal.core.search,
|
||||
org.eclipse.cdt.internal.core.search.indexing,
|
||||
org.eclipse.cdt.internal.core.search.matching,
|
||||
|
@ -63,6 +65,8 @@ Export-Package: .,
|
|||
org.eclipse.cdt.internal.core.util,
|
||||
org.eclipse.cdt.internal.errorparsers,
|
||||
org.eclipse.cdt.internal.formatter,
|
||||
org.eclipse.cdt.internal.pdom.dom,
|
||||
org.eclipse.cdt.pdom.core,
|
||||
org.eclipse.cdt.utils,
|
||||
org.eclipse.cdt.utils.coff,
|
||||
org.eclipse.cdt.utils.coff.parser,
|
||||
|
|
|
@ -13,6 +13,8 @@ package org.eclipse.cdt.core.model;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.IPDOM;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
|
@ -249,4 +251,5 @@ public interface ICProject extends IParent, IOpenable, ICElement {
|
|||
*/
|
||||
Object[] getNonCResources() throws CModelException;
|
||||
|
||||
IPDOM getIndex();
|
||||
}
|
||||
|
|
|
@ -12,8 +12,10 @@ package org.eclipse.cdt.core.model;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ILanguage;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.internal.core.model.IBufferFactory;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
/**
|
||||
* Represents an entire C translation unit (<code>.c</code> source file).
|
||||
|
@ -363,13 +365,15 @@ public interface ITranslationUnit extends ICElement, IParent, IOpenable, ISource
|
|||
/**
|
||||
* parse()
|
||||
* returns a map of all new elements and their element info
|
||||
* @deprecated this is currently only used by the core tests. It should
|
||||
* be removed from the interface.
|
||||
*/
|
||||
Map parse();
|
||||
|
||||
/**
|
||||
* Returns the root object of a DOM Abstract syntax tree.
|
||||
* Return the language for this translation unit.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
IASTTranslationUnit getASTTranslationUnit();
|
||||
ILanguage getLanguage() throws CoreException;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.cdt.core.IBinaryParser;
|
|||
import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryFile;
|
||||
import org.eclipse.cdt.core.IBinaryParser.IBinaryObject;
|
||||
import org.eclipse.cdt.core.dom.IPDOM;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.CoreModelUtil;
|
||||
|
@ -42,6 +43,7 @@ import org.eclipse.cdt.core.model.IOutputEntry;
|
|||
import org.eclipse.cdt.core.model.IPathEntry;
|
||||
import org.eclipse.cdt.core.model.ISourceEntry;
|
||||
import org.eclipse.cdt.core.model.ISourceRoot;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -695,4 +697,8 @@ public class CProject extends Openable implements ICProject {
|
|||
}
|
||||
}
|
||||
|
||||
public IPDOM getIndex() {
|
||||
return PDOMManager.getInstance().getPDOM(getProject());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ILanguage;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.IBuffer;
|
||||
|
@ -31,9 +32,17 @@ import org.eclipse.cdt.core.model.IUsing;
|
|||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.content.IContentType;
|
||||
import org.eclipse.core.runtime.content.IContentTypeManager;
|
||||
|
||||
/**
|
||||
* @see ITranslationUnit
|
||||
|
@ -41,7 +50,8 @@ import org.eclipse.core.runtime.content.IContentType;
|
|||
public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||
|
||||
IPath location = null;
|
||||
String fContentTypeID;
|
||||
String contentTypeId;
|
||||
ILanguage language;
|
||||
|
||||
/**
|
||||
* If set, this is the problem requestor which will be used to notify problems
|
||||
|
@ -594,8 +604,8 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
*/
|
||||
public boolean isHeaderUnit() {
|
||||
return (
|
||||
CCorePlugin.CONTENT_TYPE_CHEADER.equals(fContentTypeID)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(fContentTypeID)
|
||||
CCorePlugin.CONTENT_TYPE_CHEADER.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(contentTypeId)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -604,9 +614,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
*/
|
||||
public boolean isSourceUnit() {
|
||||
return (
|
||||
CCorePlugin.CONTENT_TYPE_CSOURCE.equals(fContentTypeID)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(fContentTypeID)
|
||||
|| CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(fContentTypeID)
|
||||
CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(contentTypeId)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -615,8 +625,8 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
*/
|
||||
public boolean isCLanguage() {
|
||||
return (
|
||||
CCorePlugin.CONTENT_TYPE_CSOURCE.equals(fContentTypeID)
|
||||
|| CCorePlugin.CONTENT_TYPE_CHEADER.equals(fContentTypeID)
|
||||
CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_CHEADER.equals(contentTypeId)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -625,8 +635,8 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
*/
|
||||
public boolean isCXXLanguage() {
|
||||
return (
|
||||
CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(fContentTypeID)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(fContentTypeID)
|
||||
CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_CXXHEADER.equals(contentTypeId)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -634,7 +644,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
* @see org.eclipse.cdt.core.model.ITranslationUnit#isASMLanguage()
|
||||
*/
|
||||
public boolean isASMLanguage() {
|
||||
return CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(fContentTypeID);
|
||||
return CCorePlugin.CONTENT_TYPE_ASMSOURCE.equals(contentTypeId);
|
||||
}
|
||||
|
||||
|
||||
|
@ -648,23 +658,42 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
return super.exists();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.model.ITranslationUnit#getASTTranslationUnit()
|
||||
*/
|
||||
public IASTTranslationUnit getASTTranslationUnit() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
public ILanguage getLanguage() throws CoreException {
|
||||
if (language == null) {
|
||||
// Look for the language extension registered against the
|
||||
// content type string
|
||||
IContentTypeManager manager = Platform.getContentTypeManager();
|
||||
IContentType contentType = manager.getContentType(contentTypeId);
|
||||
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, ILanguage.KEY);
|
||||
IExtension[] extensions = point.getExtensions();
|
||||
for (int i = 0; i < extensions.length; ++i) {
|
||||
IConfigurationElement[] languages = extensions[i].getConfigurationElements();
|
||||
for (int j = 0; j < languages.length; ++j) {
|
||||
IConfigurationElement language = languages[j];
|
||||
IConfigurationElement[] contentTypes = language.getChildren("contentType"); //$NON-NLS-1$
|
||||
for (int k = 0; k < contentTypes.length; ++k) {
|
||||
IContentType langContType = manager.getContentType(contentTypes[k].getAttribute("id")); //$NON-NLS-1$
|
||||
if (contentType.equals(langContType)) {
|
||||
this.language = (ILanguage)language.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
return this.language;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return language;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.model.ITranslationUnit#getContentTypeId()
|
||||
*/
|
||||
public String getContentTypeId() {
|
||||
return fContentTypeID;
|
||||
return contentTypeId;
|
||||
}
|
||||
|
||||
protected void setContentTypeID(String id) {
|
||||
fContentTypeID = id;
|
||||
contentTypeId = id;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom;
|
||||
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
|
||||
|
@ -36,6 +37,8 @@ public interface ICodeReaderFactory {
|
|||
*/
|
||||
public CodeReader createCodeReaderForTranslationUnit(String path);
|
||||
|
||||
public CodeReader createCodeReaderForTranslationUnit(ITranslationUnit tu);
|
||||
|
||||
/**
|
||||
* Create CodeReader for inclusion.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.dom;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public interface IIndex {
|
||||
|
||||
/**
|
||||
* Get the index reader. This is used by clients to get at the
|
||||
* contents of the index.
|
||||
*
|
||||
* @return index reader
|
||||
*/
|
||||
public IIndexReader getReader();
|
||||
|
||||
/**
|
||||
* Get the index writer. This is used by indexers to populate
|
||||
* the index.
|
||||
*
|
||||
* @return index writer
|
||||
*/
|
||||
public IIndexWriter getWriter();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.dom;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public interface IIndexReader {
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.dom;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public interface IIndexWriter {
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.dom;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public interface ILanguage {
|
||||
|
||||
//public static final QualifiedName KEY = new QualifiedName(CCorePlugin.PLUGIN_ID, "language"); //$NON-NLS-1$
|
||||
public static final String KEY = "language"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Style for getTranslationUnit. Use the index for resolving bindings that aren't
|
||||
* found in the AST.
|
||||
*/
|
||||
public static final int AST_USE_INDEX = 1;
|
||||
|
||||
/**
|
||||
* Style for getTranslationUnit. Don't parse header files. It's a good idea to
|
||||
* turn on AST_USE_INDEX when you do this.
|
||||
*/
|
||||
public static final int AST_SKIP_ALL_HEADERS = 2;
|
||||
|
||||
/**
|
||||
* Style for getTranslationUnit. Used by the indexer to skip over headers it
|
||||
* already has indexed.
|
||||
*/
|
||||
public static final int AST_SKIP_INDEXED_HEADERS = 4;
|
||||
|
||||
public IASTTranslationUnit getTranslationUnit(ITranslationUnit file, int style);
|
||||
|
||||
public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy, int offset);
|
||||
|
||||
}
|
|
@ -190,17 +190,17 @@ public interface IASTTranslationUnit extends IASTNode {
|
|||
public ParserLanguage getParserLanguage();
|
||||
|
||||
/**
|
||||
* Return the PDOM associated with this translation unit.
|
||||
* Return the Index associated with this translation unit.
|
||||
*
|
||||
* @return the PDOM for this translation unit
|
||||
* @return the Index for this translation unit
|
||||
*/
|
||||
public IPDOM getPDOM();
|
||||
public IPDOM getIndex();
|
||||
|
||||
/**
|
||||
* Set the PDOM to be used for this translation unit.
|
||||
* Set the Index to be used for this translation unit.
|
||||
*
|
||||
* @param pdom
|
||||
* @param index
|
||||
*/
|
||||
public void setPDOM(IPDOM pdom);
|
||||
public void setIndex(IPDOM index);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.dom.ast.gnu.c;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.dom.ILanguage;
|
||||
import org.eclipse.cdt.core.dom.PDOM;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.IScanner;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||
import org.eclipse.cdt.core.parser.ParserFactory;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.core.parser.ParserMode;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ISourceCodeParser;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.c.GCCParserExtensionConfiguration;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner2.DOMScanner;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner2.GCCScannerExtensionConfiguration;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerExtensionConfiguration;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class GCCLanguage implements ILanguage {
|
||||
|
||||
protected static final GCCScannerExtensionConfiguration C_GNU_SCANNER_EXTENSION = new GCCScannerExtensionConfiguration();
|
||||
|
||||
public IASTTranslationUnit getTranslationUnit(ITranslationUnit tu, int style) {
|
||||
IFile file = (IFile)tu.getResource();
|
||||
IProject project = file.getProject();
|
||||
IScannerInfo scanInfo = null;
|
||||
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
|
||||
if (provider != null){
|
||||
IScannerInfo buildScanInfo = provider.getScannerInformation(file);
|
||||
if (buildScanInfo != null)
|
||||
scanInfo = buildScanInfo;
|
||||
else
|
||||
scanInfo = new ScannerInfo();
|
||||
}
|
||||
|
||||
// TODO - use different factories if we are working copy, or style
|
||||
// is skip headers.
|
||||
ICodeReaderFactory fileCreator = SavedCodeReaderFactory.getInstance();
|
||||
CodeReader reader = fileCreator.createCodeReaderForTranslationUnit(tu.getElementName());
|
||||
if( reader == null )
|
||||
return null;
|
||||
|
||||
IScannerExtensionConfiguration scannerExtensionConfiguration =
|
||||
scannerExtensionConfiguration = C_GNU_SCANNER_EXTENSION;
|
||||
|
||||
IScanner scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE,
|
||||
ParserLanguage.C, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator );
|
||||
//assume GCC
|
||||
ISourceCodeParser parser = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE, ParserUtil.getParserLogService(),
|
||||
new GCCParserExtensionConfiguration() );
|
||||
|
||||
// Parse
|
||||
IASTTranslationUnit ast = parser.parse();
|
||||
|
||||
if ((style & AST_USE_INDEX) != 0)
|
||||
ast.setIndex(tu.getCProject().getIndex());
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy, int offset) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.dom.ast.gnu.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.dom.ILanguage;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.IScanner;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
|
||||
import org.eclipse.cdt.core.parser.ParserFactory;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.core.parser.ParserMode;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ISourceCodeParser;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPParserExtensionConfiguration;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner2.DOMScanner;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner2.GPPScannerExtensionConfiguration;
|
||||
import org.eclipse.cdt.internal.core.parser.scanner2.IScannerExtensionConfiguration;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class GPPLanguage implements ILanguage {
|
||||
|
||||
protected static final GPPScannerExtensionConfiguration CPP_GNU_SCANNER_EXTENSION = new GPPScannerExtensionConfiguration();
|
||||
|
||||
public IASTTranslationUnit getTranslationUnit(ITranslationUnit tu, int style) {
|
||||
IFile file = (IFile)tu.getResource();
|
||||
IProject project = file.getProject();
|
||||
IScannerInfo scanInfo = null;
|
||||
IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
|
||||
if (provider != null){
|
||||
IScannerInfo buildScanInfo = provider.getScannerInformation(file);
|
||||
if (buildScanInfo != null)
|
||||
scanInfo = buildScanInfo;
|
||||
else
|
||||
scanInfo = new ScannerInfo();
|
||||
}
|
||||
|
||||
// TODO - use different factories if we are working copy, or style
|
||||
// is skip headers.
|
||||
ICodeReaderFactory fileCreator = SavedCodeReaderFactory.getInstance();
|
||||
CodeReader reader = fileCreator.createCodeReaderForTranslationUnit(tu);
|
||||
if( reader == null )
|
||||
return null;
|
||||
|
||||
IScannerExtensionConfiguration scannerExtensionConfiguration = CPP_GNU_SCANNER_EXTENSION;
|
||||
|
||||
IScanner scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE,
|
||||
ParserLanguage.CPP, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator );
|
||||
ISourceCodeParser parser = new GNUCPPSourceParser( scanner, ParserMode.COMPLETE_PARSE, ParserUtil.getParserLogService(),
|
||||
new GPPParserExtensionConfiguration() );
|
||||
|
||||
// Parse
|
||||
IASTTranslationUnit ast = parser.parse();
|
||||
|
||||
if ((style & AST_USE_INDEX) != 0)
|
||||
ast.setIndex(tu.getCProject().getIndex());
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
||||
public ASTCompletionNode getCompletionNode(IWorkingCopy workingCopy,
|
||||
int offset) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -521,11 +521,11 @@ public class CASTTranslationUnit extends CASTNode implements
|
|||
return ParserLanguage.C;
|
||||
}
|
||||
|
||||
public IPDOM getPDOM() {
|
||||
public IPDOM getIndex() {
|
||||
return pdom;
|
||||
}
|
||||
|
||||
public void setPDOM(IPDOM pdom) {
|
||||
public void setIndex(IPDOM pdom) {
|
||||
this.pdom = pdom;
|
||||
}
|
||||
|
||||
|
|
|
@ -1300,7 +1300,7 @@ public class CVisitor {
|
|||
if( blockItem != null) {
|
||||
// We're at the end of our rope, check the PDOM if we can
|
||||
IASTTranslationUnit tu = (IASTTranslationUnit)blockItem;
|
||||
IPDOM pdom = tu.getPDOM();
|
||||
IPDOM pdom = tu.getIndex();
|
||||
binding = null;
|
||||
if (pdom != null)
|
||||
binding = pdom.resolveBinding(name);
|
||||
|
@ -1908,7 +1908,7 @@ public class CVisitor {
|
|||
|
||||
IASTTranslationUnit tu = name.getTranslationUnit();
|
||||
if (tu != null) {
|
||||
IPDOM pdom = tu.getPDOM();
|
||||
IPDOM pdom = tu.getIndex();
|
||||
if (pdom != null)
|
||||
result = (IBinding[])ArrayUtil.addAll(IBinding.class, result, pdom.resolvePrefix(name));
|
||||
}
|
||||
|
|
|
@ -573,11 +573,11 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
|
|||
return ParserLanguage.CPP;
|
||||
}
|
||||
|
||||
public IPDOM getPDOM() {
|
||||
public IPDOM getIndex() {
|
||||
return pdom;
|
||||
}
|
||||
|
||||
public void setPDOM(IPDOM pdom) {
|
||||
public void setIndex(IPDOM pdom) {
|
||||
this.pdom = pdom;
|
||||
}
|
||||
|
||||
|
|
|
@ -746,7 +746,7 @@ public class CPPSemantics {
|
|||
}
|
||||
if( binding == null ){
|
||||
// Let's try the pdom
|
||||
IPDOM pdom = name.getTranslationUnit().getPDOM();
|
||||
IPDOM pdom = name.getTranslationUnit().getIndex();
|
||||
if (pdom != null)
|
||||
binding = pdom.resolveBinding(name);
|
||||
|
||||
|
@ -3274,7 +3274,7 @@ public class CPPSemantics {
|
|||
|
||||
IASTTranslationUnit tu = name.getTranslationUnit();
|
||||
if (tu != null) {
|
||||
IPDOM pdom = tu.getPDOM();
|
||||
IPDOM pdom = tu.getIndex();
|
||||
if (pdom != null)
|
||||
result = (IBinding[])ArrayUtil.addAll(IBinding.class, result, pdom.resolvePrefix(name));
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.cdt.internal.core.parser.scanner2;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.EmptyCodeReaderCache;
|
||||
|
@ -42,6 +43,10 @@ public class FileCodeReaderFactory implements ICodeReaderFactory {
|
|||
return cache.get(path);
|
||||
}
|
||||
|
||||
public CodeReader createCodeReaderForTranslationUnit(ITranslationUnit tu) {
|
||||
return new CodeReader(tu.getPath().toOSString(), tu.getContents());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String)
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
import org.eclipse.cdt.internal.pdom.dom.PDOMFile;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class PDOMCodeReaderFactory implements ICodeReaderFactory {
|
||||
|
||||
private final PDOMDatabase pdom;
|
||||
private List workingCopies;
|
||||
|
||||
public PDOMCodeReaderFactory(PDOMDatabase pdom) {
|
||||
this.pdom = pdom;
|
||||
}
|
||||
|
||||
public PDOMCodeReaderFactory(PDOMDatabase pdom, IWorkingCopy workingCopy) {
|
||||
this(pdom);
|
||||
workingCopies = new ArrayList(1);
|
||||
workingCopies.add(workingCopy);
|
||||
}
|
||||
|
||||
public int getUniqueIdentifier() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public CodeReader createCodeReaderForTranslationUnit(String path) {
|
||||
return ParserUtil.createReader(path,
|
||||
workingCopies != null ? workingCopies.iterator() : null);
|
||||
}
|
||||
|
||||
public CodeReader createCodeReaderForTranslationUnit(ITranslationUnit tu) {
|
||||
return new CodeReader(tu.getPath().toOSString(), tu.getContents());
|
||||
}
|
||||
|
||||
public CodeReader createCodeReaderForInclusion(String path) {
|
||||
// Don't parse inclusion if it is already captured
|
||||
try {
|
||||
try {
|
||||
path = new File(path).getCanonicalPath();
|
||||
} catch (IOException e) {
|
||||
// ignore and use the path we were passed in
|
||||
}
|
||||
if (PDOMFile.find(pdom, path) != null)
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "PDOM Exception", e)));
|
||||
}
|
||||
|
||||
return ParserUtil.createReader(path, null);
|
||||
}
|
||||
|
||||
public ICodeReaderCache getCodeReaderCache() {
|
||||
// No need for cache here
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,238 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.dom.IPDOM;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.c.CASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.pdom.dom.PDOMBinding;
|
||||
import org.eclipse.cdt.internal.pdom.dom.PDOMName;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.QualifiedName;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
|
||||
/**
|
||||
* The PDOM Database.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class PDOMDatabase implements IPDOM {
|
||||
|
||||
private final IPath dbPath;
|
||||
private final Database db;
|
||||
|
||||
private static final int VERSION = 0;
|
||||
|
||||
public static final int STRING_INDEX = Database.DATA_AREA + 0 * Database.INT_SIZE;
|
||||
private BTree stringIndex;
|
||||
|
||||
public static final int FILE_INDEX = Database.DATA_AREA + 1 * Database.INT_SIZE;
|
||||
private BTree fileIndex;
|
||||
|
||||
public static final int BINDING_INDEX = Database.DATA_AREA + 2 * Database.INT_SIZE;
|
||||
private BTree bindingIndex;
|
||||
|
||||
private static final QualifiedName dbNameProperty
|
||||
= new QualifiedName(PDOMCorePlugin.ID, "dbName"); //$NON-NLS-1$
|
||||
|
||||
public PDOMDatabase(IProject project, PDOMManager manager) throws CoreException {
|
||||
String dbName = project.getPersistentProperty(dbNameProperty);
|
||||
if (dbName == null) {
|
||||
dbName = project.getName() + "_"
|
||||
+ System.currentTimeMillis() + ".pdom";
|
||||
project.setPersistentProperty(dbNameProperty, dbName);
|
||||
}
|
||||
|
||||
dbPath = PDOMCorePlugin.getDefault().getStateLocation().append(dbName);
|
||||
|
||||
try {
|
||||
db = new Database(dbPath.toOSString(), VERSION);
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "Failed to create database", e));
|
||||
}
|
||||
}
|
||||
|
||||
public Database getDB() {
|
||||
return db;
|
||||
}
|
||||
|
||||
public BTree getStringIndex() {
|
||||
if (stringIndex == null)
|
||||
stringIndex = new BTree(db, STRING_INDEX);
|
||||
return stringIndex;
|
||||
}
|
||||
|
||||
public BTree getFileIndex() {
|
||||
if (fileIndex == null)
|
||||
fileIndex = new BTree(db, FILE_INDEX);
|
||||
return fileIndex;
|
||||
}
|
||||
|
||||
public BTree getBindingIndex() {
|
||||
if (bindingIndex == null)
|
||||
bindingIndex = new BTree(db, BINDING_INDEX);
|
||||
return bindingIndex;
|
||||
}
|
||||
|
||||
public void addSymbols(IASTTranslationUnit ast) {
|
||||
ParserLanguage language = ast.getParserLanguage();
|
||||
ASTVisitor visitor;
|
||||
if (language == ParserLanguage.C)
|
||||
visitor = new CASTVisitor() {
|
||||
{
|
||||
shouldVisitNames = true;
|
||||
shouldVisitDeclarations = true;
|
||||
}
|
||||
|
||||
public int visit(IASTName name) {
|
||||
if (name.toCharArray().length > 0)
|
||||
addSymbol(name);
|
||||
return PROCESS_CONTINUE;
|
||||
};
|
||||
};
|
||||
else if (language == ParserLanguage.CPP)
|
||||
visitor = new CPPASTVisitor() {
|
||||
{
|
||||
shouldVisitNames = true;
|
||||
shouldVisitDeclarations = true;
|
||||
}
|
||||
|
||||
public int visit(IASTName name) {
|
||||
if (name.toCharArray().length > 0)
|
||||
addSymbol(name);
|
||||
return PROCESS_CONTINUE;
|
||||
};
|
||||
};
|
||||
else
|
||||
return;
|
||||
|
||||
ast.accept(visitor);
|
||||
}
|
||||
|
||||
public void addSymbol(IASTName name) {
|
||||
try {
|
||||
IBinding binding = name.resolveBinding();
|
||||
if (binding == null)
|
||||
return;
|
||||
|
||||
IScope scope = binding.getScope();
|
||||
if (scope == null)
|
||||
return;
|
||||
|
||||
IASTName scopeName = scope.getScopeName();
|
||||
|
||||
if (scopeName == null) {
|
||||
PDOMBinding pdomBinding = new PDOMBinding(this, name, binding);
|
||||
new PDOMName(this, name, pdomBinding);
|
||||
} else {
|
||||
IBinding scopeBinding = scopeName.resolveBinding();
|
||||
if (scopeBinding instanceof IType) {
|
||||
PDOMBinding pdomBinding = new PDOMBinding(this, name, binding);
|
||||
new PDOMName(this, name, pdomBinding);
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
PDOMCorePlugin.log(e);
|
||||
} catch (DOMException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "DOMException", e)));
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSymbols(ITranslationUnit ast) {
|
||||
|
||||
}
|
||||
|
||||
public void delete() throws CoreException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public ICodeReaderFactory getCodeReaderFactory() {
|
||||
return new PDOMCodeReaderFactory(this);
|
||||
}
|
||||
|
||||
public ICodeReaderFactory getCodeReaderFactory(IWorkingCopy root) {
|
||||
return new PDOMCodeReaderFactory(this, root);
|
||||
}
|
||||
|
||||
public IASTName[] getDeclarations(IBinding binding) {
|
||||
try {
|
||||
if (binding instanceof PDOMBinding) {
|
||||
PDOMName name = ((PDOMBinding)binding).getFirstDeclaration();
|
||||
if (name == null)
|
||||
return new IASTName[0];
|
||||
return new IASTName[] { name };
|
||||
}
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "getDeclarations", e)));
|
||||
}
|
||||
return new IASTName[0];
|
||||
}
|
||||
|
||||
public IBinding resolveBinding(IASTName name) {
|
||||
try {
|
||||
return new PDOMBinding(this, name, null);
|
||||
} catch (CoreException e) {
|
||||
PDOMCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IBinding[] resolvePrefix(IASTName name) {
|
||||
// try {
|
||||
final String prefix = new String(name.toCharArray());
|
||||
final ArrayList bindings = new ArrayList();
|
||||
|
||||
// getStringIndex().visit(new PDOMString.Visitor(db, prefix) {
|
||||
// public boolean visit(int record) throws IOException {
|
||||
// String value = new String(new PDOMString(PDOMDatabase.this, record).getString());
|
||||
// if (value.startsWith(prefix)) {
|
||||
// PDOMBinding pdomBinding = PDOMBinding.find(PDOMDatabase.this, record);
|
||||
// if (pdomBinding != null)
|
||||
// bindings.add(pdomBinding);
|
||||
// return true;
|
||||
// } else
|
||||
// return false;
|
||||
// }
|
||||
// });
|
||||
|
||||
return (IBinding[])bindings.toArray(new IBinding[bindings.size()]);
|
||||
// } catch (IOException e) {
|
||||
// PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
// PDOMCorePlugin.ID, 0, "resolvePrefix", e)));
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import org.eclipse.cdt.core.dom.IPDOM;
|
||||
import org.eclipse.cdt.core.dom.IPDOMProvider;
|
||||
import org.eclipse.cdt.core.model.ElementChangedEvent;
|
||||
import org.eclipse.cdt.core.model.IElementChangedListener;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.QualifiedName;
|
||||
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
|
||||
import org.eclipse.core.runtime.jobs.IJobChangeListener;
|
||||
|
||||
/**
|
||||
* The PDOM Provider. This is likely temporary since I hope
|
||||
* to integrate the PDOM directly into the core once it has
|
||||
* stabilized.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*/
|
||||
public class PDOMManager implements IPDOMProvider, IElementChangedListener, IJobChangeListener {
|
||||
|
||||
private static PDOMManager instance;
|
||||
private PDOMUpdator currJob;
|
||||
|
||||
private static final QualifiedName pdomProperty
|
||||
= new QualifiedName(PDOMCorePlugin.ID, "pdom"); //$NON-NLS-1$
|
||||
|
||||
public static PDOMManager getInstance() {
|
||||
if (instance == null)
|
||||
instance = new PDOMManager();
|
||||
return instance;
|
||||
}
|
||||
|
||||
public IPDOM getPDOM(IProject project) {
|
||||
try {
|
||||
IPDOM pdom = (IPDOM)project.getSessionProperty(pdomProperty);
|
||||
|
||||
if (pdom == null) {
|
||||
pdom = new PDOMDatabase(project, this);
|
||||
project.setSessionProperty(pdomProperty, pdom);
|
||||
}
|
||||
|
||||
return pdom;
|
||||
} catch (CoreException e) {
|
||||
PDOMCorePlugin.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void elementChanged(ElementChangedEvent event) {
|
||||
// Only respond to post change events
|
||||
if (event.getType() != ElementChangedEvent.POST_CHANGE)
|
||||
return;
|
||||
|
||||
currJob = new PDOMUpdator(event.getDelta(), currJob);
|
||||
currJob.addJobChangeListener(this);
|
||||
currJob.schedule();
|
||||
}
|
||||
|
||||
public void aboutToRun(IJobChangeEvent event) {
|
||||
}
|
||||
|
||||
public void awake(IJobChangeEvent event) {
|
||||
}
|
||||
|
||||
public synchronized void done(IJobChangeEvent event) {
|
||||
if (currJob == event.getJob())
|
||||
currJob = null;
|
||||
}
|
||||
|
||||
public void running(IJobChangeEvent event) {
|
||||
}
|
||||
|
||||
public void scheduled(IJobChangeEvent event) {
|
||||
}
|
||||
|
||||
public void sleeping(IJobChangeEvent event) {
|
||||
}
|
||||
|
||||
public void deletePDOM(IProject project) throws CoreException {
|
||||
IPDOM pdom = (IPDOM)project.getSessionProperty(pdomProperty);
|
||||
project.setSessionProperty(pdomProperty, null);
|
||||
pdom.delete();
|
||||
}
|
||||
|
||||
public IElementChangedListener getElementChangedListener() {
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ILanguage;
|
||||
import org.eclipse.cdt.core.dom.IPDOM;
|
||||
import org.eclipse.cdt.core.dom.PDOM;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ICElementDelta;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
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.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.content.IContentType;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class PDOMUpdator extends Job {
|
||||
|
||||
private PDOMUpdator prevJob;
|
||||
private ICElementDelta delta;
|
||||
private ICProject project;
|
||||
private List addedTUs;
|
||||
private List changedTUs;
|
||||
private List removedTUs;
|
||||
private int count;
|
||||
|
||||
public PDOMUpdator(ICElementDelta delta, PDOMUpdator prevJob) {
|
||||
super("PDOM Updator");
|
||||
this.prevJob = prevJob;
|
||||
this.delta = delta;
|
||||
}
|
||||
|
||||
public PDOMUpdator(ICProject project, PDOMUpdator prevJob) {
|
||||
super("PDOM Project Updator");
|
||||
this.prevJob = prevJob;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
if (prevJob != null)
|
||||
try {
|
||||
prevJob.join();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
if (delta != null)
|
||||
processDelta(delta);
|
||||
if (project != null)
|
||||
processNewProject(project);
|
||||
|
||||
if (addedTUs != null)
|
||||
for (Iterator i = addedTUs.iterator(); i.hasNext();) {
|
||||
if (monitor.isCanceled())
|
||||
return Status.CANCEL_STATUS;
|
||||
monitor.subTask("Files remaining: " + (count--));
|
||||
ITranslationUnit tu = (ITranslationUnit)i.next();
|
||||
processAddedTU(tu);
|
||||
}
|
||||
|
||||
if (changedTUs != null)
|
||||
for (Iterator i = changedTUs.iterator(); i.hasNext();) {
|
||||
if (monitor.isCanceled())
|
||||
return Status.CANCEL_STATUS;
|
||||
monitor.subTask("Files remaining: " + (count--));
|
||||
ITranslationUnit tu = (ITranslationUnit)i.next();
|
||||
processChangedTU(tu);
|
||||
}
|
||||
|
||||
if (removedTUs != null)
|
||||
for (Iterator i = removedTUs.iterator(); i.hasNext();) {
|
||||
if (monitor.isCanceled())
|
||||
return Status.CANCEL_STATUS;
|
||||
monitor.subTask("Files remaining: " + (count--));
|
||||
ITranslationUnit tu = (ITranslationUnit)i.next();
|
||||
processRemovedTU(tu);
|
||||
}
|
||||
|
||||
System.out.println("Updator Time: " + (System.currentTimeMillis() - start));
|
||||
return Status.OK_STATUS;
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
return e.getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
private void processDelta(ICElementDelta delta) {
|
||||
// process the children first
|
||||
ICElementDelta[] children = delta.getAffectedChildren();
|
||||
for (int i = 0; i < children.length; ++i)
|
||||
processDelta(children[i]);
|
||||
|
||||
// what have we got
|
||||
ICElement element = delta.getElement();
|
||||
if (element.getElementType() == ICElement.C_PROJECT) {
|
||||
switch (delta.getKind()) {
|
||||
case ICElementDelta.ADDED:
|
||||
processNewProject((ICProject)element);
|
||||
break;
|
||||
}
|
||||
} else if (element.getElementType() == ICElement.C_UNIT) {
|
||||
ITranslationUnit tu = (ITranslationUnit)element;
|
||||
if (tu.isWorkingCopy())
|
||||
// Don't care about working copies either
|
||||
return;
|
||||
|
||||
switch (delta.getKind()) {
|
||||
case ICElementDelta.ADDED:
|
||||
if (addedTUs == null)
|
||||
addedTUs = new LinkedList();
|
||||
addedTUs.add(element);
|
||||
++count;
|
||||
break;
|
||||
case ICElementDelta.CHANGED:
|
||||
if (changedTUs == null)
|
||||
changedTUs = new LinkedList();
|
||||
changedTUs.add(element);
|
||||
++count;
|
||||
break;
|
||||
case ICElementDelta.REMOVED:
|
||||
if (removedTUs == null)
|
||||
removedTUs = new LinkedList();
|
||||
removedTUs.add(element);
|
||||
++count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processNewProject(final ICProject project) {
|
||||
try {
|
||||
project.getProject().accept(new IResourceProxyVisitor() {
|
||||
public boolean visit(IResourceProxy proxy) throws CoreException {
|
||||
if (proxy.getType() == IResource.FILE) {
|
||||
String fileName = proxy.getName();
|
||||
IContentType contentType = Platform.getContentTypeManager().findContentTypeFor(fileName);
|
||||
if (contentType == null)
|
||||
return true;
|
||||
String contentTypeId = contentType.getId();
|
||||
|
||||
if (CCorePlugin.CONTENT_TYPE_CXXSOURCE.equals(contentTypeId)
|
||||
|| CCorePlugin.CONTENT_TYPE_CSOURCE.equals(contentTypeId)) {
|
||||
if (addedTUs == null)
|
||||
addedTUs = new LinkedList();
|
||||
addedTUs.add(CoreModel.getDefault().create((IFile)proxy.requestResource()));
|
||||
++count;
|
||||
}
|
||||
// TODO handle header files
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
} catch (CoreException e) {
|
||||
PDOMCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void processAddedTU(ITranslationUnit tu) throws CoreException {
|
||||
ILanguage language = tu.getLanguage();
|
||||
if (language == null)
|
||||
return;
|
||||
|
||||
IASTTranslationUnit ast = language.getTranslationUnit(tu,
|
||||
ILanguage.AST_USE_INDEX |
|
||||
ILanguage.AST_SKIP_INDEXED_HEADERS);
|
||||
|
||||
IPDOM pdom = ast.getIndex();
|
||||
if (pdom == null || !(pdom instanceof PDOMDatabase))
|
||||
return;
|
||||
|
||||
PDOMDatabase mypdom = (PDOMDatabase)pdom;
|
||||
mypdom.addSymbols(ast);
|
||||
}
|
||||
|
||||
private void processRemovedTU(ITranslationUnit tu) {
|
||||
IProject project = tu.getCProject().getProject();
|
||||
IPDOM pdom = PDOM.getPDOM(project);
|
||||
if (pdom == null || !(pdom instanceof PDOMDatabase))
|
||||
return;
|
||||
|
||||
PDOMDatabase mypdom = (PDOMDatabase)pdom;
|
||||
mypdom.removeSymbols(tu);
|
||||
}
|
||||
|
||||
private void processChangedTU(ITranslationUnit tu) throws CoreException {
|
||||
IPDOM pdom = PDOM.getPDOM(tu.getCProject().getProject());
|
||||
if (pdom == null || !(pdom instanceof PDOMDatabase))
|
||||
return;
|
||||
PDOMDatabase mypdom = (PDOMDatabase)pdom;
|
||||
|
||||
ILanguage language = tu.getLanguage();
|
||||
if (language == null)
|
||||
return;
|
||||
|
||||
IASTTranslationUnit ast = language.getTranslationUnit(tu,
|
||||
ILanguage.AST_SKIP_ALL_HEADERS |
|
||||
ILanguage.AST_USE_INDEX);
|
||||
|
||||
if (pdom != ast.getIndex())
|
||||
// weird
|
||||
return;
|
||||
|
||||
mypdom.removeSymbols(tu);
|
||||
mypdom.addSymbols(ast);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.eclipse.cdt.internal.core.pdom;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Chunk;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
|
||||
/**
|
||||
* @author dschaefer
|
||||
*
|
||||
*/
|
||||
public class PDOMUtils {
|
||||
|
||||
public static int stringCompare(Database db, int record1, int record2) throws IOException {
|
||||
Chunk chunk1 = db.getChunk(record1);
|
||||
Chunk chunk2 = db.getChunk(record2);
|
||||
|
||||
int i1 = record1;
|
||||
int i2 = record2;
|
||||
char c1 = chunk1.getChar(i1);
|
||||
char c2 = chunk2.getChar(i2);
|
||||
|
||||
while (c1 != 0 && c2 != 0) {
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
i2 += 2;
|
||||
c1 = chunk1.getChar(i1);
|
||||
c2 = chunk2.getChar(i2);
|
||||
}
|
||||
|
||||
if (c1 == c2)
|
||||
return 0;
|
||||
else if (c1 == 0)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static int stringCompare(Database db, int record1, char[] record2) throws IOException {
|
||||
Chunk chunk1 = db.getChunk(record1);
|
||||
|
||||
int i1 = record1;
|
||||
int i2 = 0;
|
||||
char c1 = chunk1.getChar(i1);
|
||||
char c2 = i2 < record2.length ? record2[i2] : 0;
|
||||
|
||||
while (c1 != 0 && c2 != 0) {
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
++i2;
|
||||
c1 = chunk1.getChar(i1);
|
||||
c2 = i2 < record2.length ? record2[i2] : 0;
|
||||
}
|
||||
|
||||
if (c1 == c2)
|
||||
return 0;
|
||||
else if (c1 == 0)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,326 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class BTree {
|
||||
|
||||
protected Database db;
|
||||
protected int rootPointer;
|
||||
|
||||
protected static final int NUM_RECORDS = 15;
|
||||
protected static final int MEDIAN_RECORD = NUM_RECORDS / 2;
|
||||
protected static final int NUM_CHILDREN = NUM_RECORDS + 1;
|
||||
protected static final int OFFSET_CHILDREN = NUM_RECORDS * Database.INT_SIZE;
|
||||
|
||||
/**
|
||||
* Contructor.
|
||||
*
|
||||
* @param db the database containing the btree
|
||||
* @param root offset into database of the pointer to the root node
|
||||
*/
|
||||
public BTree(Database db, int rootPointer) {
|
||||
this.db = db;
|
||||
this.rootPointer = rootPointer;
|
||||
}
|
||||
|
||||
protected int getRoot() throws IOException {
|
||||
return db.getInt(rootPointer);
|
||||
}
|
||||
|
||||
protected final void putRecord(Chunk chunk, int node, int index, int record) {
|
||||
chunk.putInt(node + index * Database.INT_SIZE, record);
|
||||
}
|
||||
|
||||
protected final int getRecord(Chunk chunk, int node, int index) {
|
||||
return chunk.getInt(node + index * Database.INT_SIZE);
|
||||
}
|
||||
|
||||
protected final void putChild(Chunk chunk, int node, int index, int child) {
|
||||
chunk.putInt(node + OFFSET_CHILDREN + index * Database.INT_SIZE, child);
|
||||
}
|
||||
|
||||
protected final int getChild(Chunk chunk, int node, int index) {
|
||||
return chunk.getInt(node + OFFSET_CHILDREN + index * Database.INT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the record into the b-tree. We don't insert if the
|
||||
* key was already there, in which case we return the record
|
||||
* that matched. In other cases, we just return the record back.
|
||||
*
|
||||
* @param offset of the record
|
||||
* @return
|
||||
*/
|
||||
public int insert(int record, IBTreeComparator comparator) throws IOException {
|
||||
int root = getRoot();
|
||||
|
||||
// is this our first time in
|
||||
if (root == 0) {
|
||||
firstInsert(record);
|
||||
return record;
|
||||
}
|
||||
|
||||
return insert(null, 0, 0, root, record, comparator);
|
||||
}
|
||||
|
||||
private int insert(Chunk pChunk, int parent, int iParent, int node, int record, IBTreeComparator comparator) throws IOException {
|
||||
Chunk chunk = db.getChunk(node);
|
||||
|
||||
// if this node is full (last record isn't null), split it
|
||||
if (getRecord(chunk, node, NUM_RECORDS - 1) != 0) {
|
||||
int median = getRecord(chunk, node, MEDIAN_RECORD);
|
||||
if (median == record)
|
||||
// found it, never mind
|
||||
return median;
|
||||
else {
|
||||
// split it
|
||||
// create the new node and move the larger records over
|
||||
int newnode = allocateNode();
|
||||
Chunk newchunk = db.getChunk(newnode);
|
||||
for (int i = 0; i < MEDIAN_RECORD; ++i) {
|
||||
putRecord(newchunk, newnode, i, getRecord(chunk, node, MEDIAN_RECORD + 1 + i));
|
||||
putRecord(chunk, node, MEDIAN_RECORD + 1 + i, 0);
|
||||
putChild(newchunk, newnode, i, getChild(chunk, node, MEDIAN_RECORD + 1 + i));
|
||||
putChild(chunk, node, MEDIAN_RECORD + 1 + i, 0);
|
||||
}
|
||||
putChild(newchunk, newnode, MEDIAN_RECORD, getChild(chunk, node, NUM_RECORDS));
|
||||
putChild(chunk, node, NUM_RECORDS, 0);
|
||||
|
||||
if (parent == 0) {
|
||||
// create a new root
|
||||
parent = allocateNode();
|
||||
pChunk = db.getChunk(parent);
|
||||
db.putInt(rootPointer, parent);
|
||||
putChild(pChunk, parent, 0, node);
|
||||
} else {
|
||||
// insert the median into the parent
|
||||
for (int i = NUM_RECORDS - 2; i >= iParent; --i) {
|
||||
int r = getRecord(pChunk, parent, i);
|
||||
if (r != 0) {
|
||||
putRecord(pChunk, parent, i + 1, r);
|
||||
putChild(pChunk, parent, i + 2, getChild(pChunk, parent, i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
putRecord(pChunk, parent, iParent, median);
|
||||
putChild(pChunk, parent, iParent + 1, newnode);
|
||||
|
||||
putRecord(chunk, node, MEDIAN_RECORD, 0);
|
||||
|
||||
// set the node to the correct one to follow
|
||||
if (comparator.compare(record, median) > 0) {
|
||||
node = newnode;
|
||||
chunk = newchunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search to find the insert point
|
||||
int i;
|
||||
for (i = 0; i < NUM_RECORDS; ++i) {
|
||||
int record1 = getRecord(chunk, node, i);
|
||||
if (record1 == 0) {
|
||||
// past the end
|
||||
break;
|
||||
} else {
|
||||
int compare = comparator.compare(record1, record);
|
||||
if (compare == 0)
|
||||
// found it, no insert, just return the record
|
||||
return record;
|
||||
else if (compare > 0)
|
||||
// past it
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int child = getChild(chunk, node, i);
|
||||
if (child != 0) {
|
||||
// visit the children
|
||||
return insert(chunk, node, i, child, record, comparator);
|
||||
} else {
|
||||
// were at the leaf, add us in.
|
||||
// first copy everything after over one
|
||||
for (int j = NUM_RECORDS - 2; j >= i; --j) {
|
||||
int r = getRecord(chunk, node, j);
|
||||
if (r != 0)
|
||||
putRecord(chunk, node, j + 1, r);
|
||||
}
|
||||
putRecord(chunk, node, i, record);
|
||||
return record;
|
||||
}
|
||||
}
|
||||
|
||||
private void firstInsert(int record) throws IOException {
|
||||
// create the node and save it as root
|
||||
int root = allocateNode();
|
||||
db.putInt(rootPointer, root);
|
||||
// put the record in the first slot of the node
|
||||
putRecord(db.getChunk(root), root, 0, record);
|
||||
}
|
||||
|
||||
private int allocateNode() throws IOException {
|
||||
return db.malloc((2 * NUM_RECORDS - 1) * Database.INT_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the record from the b-tree.
|
||||
*
|
||||
* @param offset of the record
|
||||
*/
|
||||
public void delete(int record) {
|
||||
// TODO some day
|
||||
}
|
||||
|
||||
/**
|
||||
* Visit all nodes beginning when the visitor comparator
|
||||
* returns >= 0 until the visitor visit returns falls.
|
||||
*
|
||||
* @param visitor
|
||||
*/
|
||||
public void visit(IBTreeVisitor visitor) throws IOException {
|
||||
visit(db.getInt(rootPointer), visitor, false);
|
||||
}
|
||||
|
||||
private boolean visit(int node, IBTreeVisitor visitor, boolean found) throws IOException {
|
||||
// if found is false, we are still in search mode
|
||||
// once found is true visit everything
|
||||
// return false when ready to quit
|
||||
if (node == 0)
|
||||
return visitor.visit(0);
|
||||
|
||||
Chunk chunk = db.getChunk(node);
|
||||
|
||||
if (found) {
|
||||
int child = getChild(chunk, node, 0);
|
||||
if (child != 0)
|
||||
if (!visit(child, visitor, true))
|
||||
return false;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < NUM_RECORDS; ++i) {
|
||||
int record = getRecord(chunk, node, i);
|
||||
if (record == 0)
|
||||
break;
|
||||
|
||||
if (found) {
|
||||
if (!visitor.visit(record))
|
||||
return false;
|
||||
if (!visit(getChild(chunk, node, i + 1), visitor, true))
|
||||
return false;
|
||||
} else {
|
||||
int compare = visitor.compare(record);
|
||||
if (compare > 0) {
|
||||
// start point is to the left
|
||||
if (!visit(getChild(chunk, node, i), visitor, false))
|
||||
return false;
|
||||
if (!visitor.visit(record))
|
||||
return false;
|
||||
if (!visit(getChild(chunk, node, i + 1), visitor, true))
|
||||
return false;
|
||||
found = true;
|
||||
} else if (compare == 0) {
|
||||
if (!visitor.visit(record))
|
||||
return false;
|
||||
if (!visit(getChild(chunk, node, i + 1), visitor, true))
|
||||
return false;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return visit(getChild(chunk, node, i), visitor, found);
|
||||
}
|
||||
|
||||
public int getHeight() throws IOException {
|
||||
int root = getRoot();
|
||||
|
||||
if (root == 0)
|
||||
return 0;
|
||||
|
||||
return getHeight(root);
|
||||
}
|
||||
|
||||
private int getHeight(int node) throws IOException {
|
||||
int height = 0;
|
||||
Chunk chunk = db.getChunk(node);
|
||||
|
||||
for (int i = 0; i < NUM_CHILDREN; ++i) {
|
||||
int child = getChild(chunk, node, i);
|
||||
if (child == 0)
|
||||
break;
|
||||
int n = getHeight(child);
|
||||
if (n == -1)
|
||||
return -1;
|
||||
if (height != 0 && height != n)
|
||||
return -1;
|
||||
height = n;
|
||||
}
|
||||
|
||||
return height + 1;
|
||||
}
|
||||
|
||||
public int getRecordCount() throws IOException {
|
||||
int root = getRoot();
|
||||
|
||||
if (root == 0)
|
||||
return 0;
|
||||
|
||||
return getRecordCount(root);
|
||||
}
|
||||
|
||||
private int getRecordCount(int node) throws IOException {
|
||||
Chunk chunk = db.getChunk(node);
|
||||
|
||||
int count;
|
||||
for (count = 0; count < NUM_RECORDS; ++count)
|
||||
if (getRecord(chunk, node, count) == 0)
|
||||
break;
|
||||
|
||||
for (int i = 0; i < NUM_CHILDREN; ++i) {
|
||||
int child = getChild(chunk, node, i);
|
||||
if (child != 0)
|
||||
count += getRecordCount(child);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public int getNodeCount() throws IOException {
|
||||
int root = getRoot();
|
||||
|
||||
if (root == 0)
|
||||
return 0;
|
||||
|
||||
return getNodeCount(root);
|
||||
}
|
||||
|
||||
private int getNodeCount(int node) throws IOException {
|
||||
Chunk chunk = db.getChunk(node);
|
||||
|
||||
int count = 1;
|
||||
|
||||
for (int i = 0; i < NUM_CHILDREN; ++i) {
|
||||
int child = getChild(chunk, node, i);
|
||||
if (child != 0)
|
||||
count += getNodeCount(child);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel.MapMode;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class Chunk {
|
||||
|
||||
private MappedByteBuffer buffer;
|
||||
|
||||
// Cache info
|
||||
private Database db;
|
||||
int index;
|
||||
private Chunk prevChunk;
|
||||
private Chunk nextChunk;
|
||||
|
||||
Chunk(RandomAccessFile file, int offset) throws IOException {
|
||||
index = offset / Database.CHUNK_SIZE;
|
||||
buffer = file.getChannel().map(MapMode.READ_WRITE, offset, Database.CHUNK_SIZE);
|
||||
}
|
||||
|
||||
public void putInt(int offset, int value) {
|
||||
buffer.putInt(offset % Database.CHUNK_SIZE, value);
|
||||
}
|
||||
|
||||
public int getInt(int offset) {
|
||||
return buffer.getInt(offset % Database.CHUNK_SIZE);
|
||||
}
|
||||
|
||||
public void putChar(int offset, char value) {
|
||||
buffer.putChar(offset % Database.CHUNK_SIZE, value);
|
||||
}
|
||||
|
||||
public char getChar(int offset) {
|
||||
return buffer.getChar(offset % Database.CHUNK_SIZE);
|
||||
}
|
||||
|
||||
public void putChars(int offset, char[] value) {
|
||||
buffer.position(offset % Database.CHUNK_SIZE);
|
||||
for (int i = 0; i < value.length; ++i)
|
||||
buffer.putChar(value[i]);
|
||||
buffer.putChar((char)0);
|
||||
}
|
||||
|
||||
public char[] getChars(int offset) {
|
||||
buffer.position(offset % Database.CHUNK_SIZE);
|
||||
int n = 0;
|
||||
for (char c = buffer.getChar(); c != 0; c = buffer.getChar())
|
||||
++n;
|
||||
|
||||
buffer.position(offset % Database.CHUNK_SIZE);
|
||||
char[] chars = new char[n];
|
||||
int i = 0;
|
||||
for (char c = buffer.getChar(); c != 0; c = buffer.getChar())
|
||||
chars[i++] = c;
|
||||
return chars;
|
||||
}
|
||||
|
||||
public void putString(int offset, String value) {
|
||||
buffer.position(offset % Database.CHUNK_SIZE);
|
||||
int n = value.length();
|
||||
for (int i = 0; i < n; ++i)
|
||||
buffer.putChar(value.charAt(i));
|
||||
buffer.putChar((char)0);
|
||||
}
|
||||
|
||||
public String getString(int offset) {
|
||||
return new String(getChars(offset));
|
||||
}
|
||||
|
||||
Chunk getNextChunk() {
|
||||
return nextChunk;
|
||||
}
|
||||
|
||||
void setNextChunk(Chunk nextChunk) {
|
||||
this.nextChunk = nextChunk;
|
||||
}
|
||||
|
||||
Chunk getPrevChunk() {
|
||||
return prevChunk;
|
||||
}
|
||||
|
||||
void setPrevChunk(Chunk prevChunk) {
|
||||
this.prevChunk = prevChunk;
|
||||
}
|
||||
|
||||
void free() {
|
||||
// nextChunk should be null
|
||||
db.toc[index] = null;
|
||||
db.lruChunk = prevChunk;
|
||||
prevChunk.nextChunk = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class Database {
|
||||
|
||||
private final RandomAccessFile file;
|
||||
Chunk[] toc;
|
||||
Chunk mruChunk;
|
||||
Chunk lruChunk;
|
||||
|
||||
private int loadedChunks;
|
||||
|
||||
// public for tests only, you shouldn't need these
|
||||
public static final int VERSION_OFFSET = 0;
|
||||
public static final int CHUNK_SIZE = 4096;
|
||||
public static final int CACHE_SIZE = 10000; // Should be configable
|
||||
public static final int MIN_SIZE = 16;
|
||||
public static final int INT_SIZE = 4;
|
||||
public static final int CHAR_SIZE = 2;
|
||||
public static final int PREV_OFFSET = INT_SIZE;
|
||||
public static final int NEXT_OFFSET = INT_SIZE * 2;
|
||||
public static final int DATA_AREA = CHUNK_SIZE / MIN_SIZE * INT_SIZE + INT_SIZE;
|
||||
|
||||
public Database(String filename, int version) throws IOException {
|
||||
file = new RandomAccessFile(filename, "rw"); //$NON-NLS-1$
|
||||
|
||||
// Allocate chunk table, make sure we have at least one
|
||||
long nChunks = file.length() / CHUNK_SIZE;
|
||||
if (nChunks == 0) {
|
||||
create();
|
||||
++nChunks;
|
||||
}
|
||||
|
||||
toc = new Chunk[(int)nChunks];
|
||||
|
||||
// Load in the magic chunk zero
|
||||
toc[0] = new Chunk(file, 0);
|
||||
int oldversion = toc[0].getInt(0);
|
||||
if (oldversion != version) {
|
||||
// Conversion?
|
||||
toc[0].putInt(0, version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the database, including chunk zero and the b-trees.
|
||||
*/
|
||||
private void create() throws IOException {
|
||||
file.seek(0);
|
||||
file.write(new byte[CHUNK_SIZE]); // the header chunk
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Chunk that contains the given offset.
|
||||
*
|
||||
* @param offset
|
||||
* @return
|
||||
*/
|
||||
public Chunk getChunk(int offset) throws IOException {
|
||||
int index = offset / CHUNK_SIZE;
|
||||
Chunk chunk = toc[index];
|
||||
if (chunk == null) {
|
||||
if (loadedChunks == CACHE_SIZE)
|
||||
// cache is full, free lruChunk
|
||||
lruChunk.free();
|
||||
|
||||
chunk = toc[index] = new Chunk(file, index * CHUNK_SIZE);
|
||||
}
|
||||
|
||||
// insert into cache
|
||||
// TODO We can move this into the chunks
|
||||
Chunk prevChunk = chunk.getPrevChunk();
|
||||
Chunk nextChunk = chunk.getNextChunk();
|
||||
if (prevChunk != null)
|
||||
prevChunk.setNextChunk(nextChunk);
|
||||
if (nextChunk != null)
|
||||
nextChunk.setPrevChunk(prevChunk);
|
||||
if (mruChunk != null) {
|
||||
chunk.setNextChunk(mruChunk);
|
||||
mruChunk.setPrevChunk(chunk);
|
||||
}
|
||||
mruChunk = chunk;
|
||||
chunk.setPrevChunk(null);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate a block out of the database.
|
||||
*
|
||||
* @param size
|
||||
* @return
|
||||
*/
|
||||
public int malloc(int size) throws IOException {
|
||||
// Which block size
|
||||
int freeblock = 0;
|
||||
int blocksize;
|
||||
int matchsize = 0;
|
||||
for (blocksize = MIN_SIZE; blocksize <= CHUNK_SIZE; blocksize += MIN_SIZE) {
|
||||
if (blocksize - INT_SIZE >= size) {
|
||||
if (matchsize == 0) // our real size
|
||||
matchsize = blocksize;
|
||||
freeblock = getFirstBlock(blocksize);
|
||||
if (freeblock != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get the block
|
||||
Chunk chunk;
|
||||
if (freeblock == 0) {
|
||||
// Out of memory, allocate a new chunk
|
||||
int i = createChunk();
|
||||
chunk = toc[i];
|
||||
freeblock = i * CHUNK_SIZE;
|
||||
blocksize = CHUNK_SIZE;
|
||||
} else {
|
||||
chunk = getChunk(freeblock);
|
||||
removeBlock(chunk, blocksize, freeblock);
|
||||
}
|
||||
|
||||
if (blocksize != matchsize) {
|
||||
// Add in the unused part of our block
|
||||
addBlock(chunk, blocksize - matchsize, freeblock + matchsize);
|
||||
}
|
||||
|
||||
// Make our size negative to show in use
|
||||
chunk.putInt(freeblock, - matchsize);
|
||||
|
||||
return freeblock + INT_SIZE;
|
||||
}
|
||||
|
||||
private int createChunk() throws IOException {
|
||||
int offset = (int)file.length();
|
||||
file.seek(offset);
|
||||
file.write(new byte[CHUNK_SIZE]);
|
||||
Chunk[] oldtoc = toc;
|
||||
int i = oldtoc.length;
|
||||
toc = new Chunk[i + 1];
|
||||
System.arraycopy(oldtoc, 0, toc, 0, i);
|
||||
toc[i] = new Chunk(file, offset);
|
||||
return i;
|
||||
}
|
||||
|
||||
private int getFirstBlock(int blocksize) {
|
||||
return toc[0].getInt((blocksize / MIN_SIZE) * INT_SIZE);
|
||||
}
|
||||
|
||||
private void setFirstBlock(int blocksize, int block) {
|
||||
toc[0].putInt((blocksize / MIN_SIZE) * INT_SIZE, block);
|
||||
}
|
||||
|
||||
private void removeBlock(Chunk chunk, int blocksize, int block) throws IOException {
|
||||
int prevblock = chunk.getInt(block + PREV_OFFSET);
|
||||
int nextblock = chunk.getInt(block + NEXT_OFFSET);
|
||||
if (prevblock != 0)
|
||||
putInt(prevblock + NEXT_OFFSET, nextblock);
|
||||
else // we were the head
|
||||
setFirstBlock(blocksize, nextblock);
|
||||
|
||||
if (nextblock != 0)
|
||||
putInt(nextblock + PREV_OFFSET, prevblock);
|
||||
}
|
||||
|
||||
private void addBlock(Chunk chunk, int blocksize, int block) throws IOException {
|
||||
// Mark our size
|
||||
chunk.putInt(block, blocksize);
|
||||
|
||||
// Add us to the head of the list
|
||||
int prevfirst = getFirstBlock(blocksize);
|
||||
chunk.putInt(block + PREV_OFFSET, 0);
|
||||
chunk.putInt(block + NEXT_OFFSET, prevfirst);
|
||||
if (prevfirst != 0)
|
||||
putInt(prevfirst + PREV_OFFSET, block);
|
||||
setFirstBlock(blocksize, block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free an allocate block.
|
||||
*
|
||||
* @param offset
|
||||
*/
|
||||
public void free(int offset) throws IOException {
|
||||
// TODO - look for opportunities to merge blocks
|
||||
int block = offset - INT_SIZE;
|
||||
Chunk chunk = getChunk(block);
|
||||
int blocksize = - chunk.getInt(block);
|
||||
addBlock(chunk, blocksize, block);
|
||||
}
|
||||
|
||||
public void putInt(int offset, int value) throws IOException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
chunk.putInt(offset, value);
|
||||
}
|
||||
|
||||
public int getInt(int offset) throws IOException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
return chunk.getInt(offset);
|
||||
}
|
||||
|
||||
public void putChars(int offset, char[] value) throws IOException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
chunk.putChars(offset, value);
|
||||
}
|
||||
|
||||
public char[] getChars(int offset) throws IOException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
return chunk.getChars(offset);
|
||||
}
|
||||
|
||||
public void putString(int offset, String value) throws IOException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
chunk.putString(offset, value);
|
||||
}
|
||||
|
||||
public String getString(int offset) throws IOException {
|
||||
Chunk chunk = getChunk(offset);
|
||||
return chunk.getString(offset);
|
||||
}
|
||||
|
||||
public int getNumChunks() {
|
||||
return toc.length;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public interface IBTreeComparator {
|
||||
|
||||
/**
|
||||
* Compare two records. Used for insert.
|
||||
*
|
||||
* @param record1
|
||||
* @param record2
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract int compare(int record1, int record2) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
* The visitor walks through the tree until the compare returns
|
||||
* >= 0, i.e. we reach the first record that meets the criteria.
|
||||
*
|
||||
* It then continues until the visit returns false.
|
||||
*
|
||||
*/
|
||||
public interface IBTreeVisitor {
|
||||
|
||||
/**
|
||||
* Compare the record against an internally held key.
|
||||
* Used for visiting.
|
||||
*
|
||||
* @param record
|
||||
* @return -1 if record < key, 0 if record == key, 1 if record > key
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract int compare(int record) throws IOException;
|
||||
|
||||
/**
|
||||
* Visit a given record and return whether to continue or not.
|
||||
*
|
||||
* @param record
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract boolean visit(int record) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class StringComparator implements IBTreeComparator {
|
||||
|
||||
protected Database db;
|
||||
protected int offset;
|
||||
|
||||
public StringComparator(Database db, int offset) {
|
||||
this.db = db;
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public int compare(int record1, int record2) throws IOException {
|
||||
Chunk chunk1 = db.getChunk(record1);
|
||||
Chunk chunk2 = db.getChunk(record2);
|
||||
|
||||
int i1 = record1 + offset;
|
||||
int i2 = record2 + offset;
|
||||
char c1 = chunk1.getChar(i1);
|
||||
char c2 = chunk2.getChar(i2);
|
||||
|
||||
while (c1 != 0 && c2 != 0) {
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
i2 += 2;
|
||||
c1 = chunk1.getChar(i1);
|
||||
c2 = chunk2.getChar(i2);
|
||||
}
|
||||
|
||||
if (c1 == c2)
|
||||
return 0;
|
||||
else if (c1 == 0)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.db;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public abstract class StringVisitor implements IBTreeVisitor {
|
||||
|
||||
public final Database db;
|
||||
private final int offset;
|
||||
private final String key;
|
||||
|
||||
public StringVisitor(Database db, int offset, String key) {
|
||||
this.db = db;
|
||||
this.offset = offset;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public int compare(int record) throws IOException {
|
||||
Chunk chunk = db.getChunk(record);
|
||||
int i1 = record + offset;
|
||||
int i2 = 0;
|
||||
int n2 = key.length();
|
||||
char c1 = chunk.getChar(i1);
|
||||
char c2 = i2 < n2 ? key.charAt(i2) : 0;
|
||||
|
||||
while (c1 != 0 && c2 != 0) {
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
|
||||
i1 += 2;
|
||||
i2 += 1;
|
||||
c1 = chunk.getChar(i1);
|
||||
c2 = i2 < n2 ? key.charAt(i2) : 0;
|
||||
}
|
||||
|
||||
if (c1 == c2)
|
||||
return 0;
|
||||
else if (c1 == 0)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.pdom.dom;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMDatabase;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMUtils;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class PDOMBinding implements IBinding {
|
||||
|
||||
protected final PDOMDatabase pdom;
|
||||
protected int record;
|
||||
|
||||
private static final int STRING_REC_OFFSET = 0; // size 4
|
||||
private static final int FIRST_DECL_OFFSET = 4; // size 4
|
||||
private static final int FIRST_DEF_OFFSET = 8; // size 4
|
||||
private static final int FIRST_REF_OFFSET = 12; // size 4
|
||||
private static final int LANGUAGE_OFFSET = 16; // size 2
|
||||
private static final int TYPE_OFFSET = 18; // size 2
|
||||
|
||||
protected int getRecordSize() {
|
||||
return 20;
|
||||
}
|
||||
|
||||
public static class Comparator implements IBTreeComparator {
|
||||
|
||||
private Database db;
|
||||
|
||||
public Comparator(Database db) {
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public int compare(int record1, int record2) throws IOException {
|
||||
int string1 = db.getInt(record1 + STRING_REC_OFFSET);
|
||||
int string2 = db.getInt(record2 + STRING_REC_OFFSET);
|
||||
|
||||
return PDOMUtils.stringCompare(db, string1, string2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public abstract static class Visitor implements IBTreeVisitor {
|
||||
|
||||
private Database db;
|
||||
private char[] key;
|
||||
|
||||
public Visitor(Database db, char[] key) {
|
||||
this.db = db;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public int compare(int record1) throws IOException {
|
||||
int string1 = db.getInt(record1 + STRING_REC_OFFSET);
|
||||
|
||||
return PDOMUtils.stringCompare(db, string1, key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FindVisitor extends Visitor {
|
||||
|
||||
private int record;
|
||||
|
||||
public FindVisitor(Database db, char[] stringKey) {
|
||||
super(db, stringKey);
|
||||
}
|
||||
|
||||
public boolean visit(int record) throws IOException {
|
||||
this.record = record;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int findIn(BTree btree) throws IOException {
|
||||
btree.visit(this);
|
||||
return record;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public PDOMBinding(PDOMDatabase pdom, IASTName name, IBinding binding) throws CoreException {
|
||||
try {
|
||||
this.pdom = pdom;
|
||||
|
||||
char[] namechars = name.toCharArray();
|
||||
|
||||
BTree index = pdom.getBindingIndex();
|
||||
record = new FindVisitor(pdom.getDB(), namechars).findIn(index);
|
||||
|
||||
if (record == 0) {
|
||||
Database db = pdom.getDB();
|
||||
record = db.malloc(getRecordSize());
|
||||
|
||||
int stringRecord = db.malloc((namechars.length + 1) * Database.CHAR_SIZE);
|
||||
db.putChars(stringRecord, namechars);
|
||||
|
||||
db.putInt(record + STRING_REC_OFFSET, stringRecord);
|
||||
pdom.getBindingIndex().insert(record, new Comparator(db));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "Failed to allocate binding", e));
|
||||
}
|
||||
}
|
||||
|
||||
public PDOMBinding(PDOMDatabase pdom, int bindingRecord) {
|
||||
this.pdom = pdom;
|
||||
this.record = bindingRecord;
|
||||
}
|
||||
|
||||
public int getRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
public void addDeclaration(PDOMName name) throws IOException {
|
||||
PDOMName firstDeclaration = getFirstDeclaration();
|
||||
if (firstDeclaration != null) {
|
||||
firstDeclaration.setPrevInBinding(name);
|
||||
name.setNextInBinding(firstDeclaration);
|
||||
}
|
||||
pdom.getDB().putInt(record + FIRST_DECL_OFFSET, name.getRecord());
|
||||
}
|
||||
|
||||
public PDOMName getFirstDeclaration() throws IOException {
|
||||
int firstDeclRec = pdom.getDB().getInt(record + FIRST_DECL_OFFSET);
|
||||
return firstDeclRec != 0 ? new PDOMName(pdom, firstDeclRec) : null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
try {
|
||||
Database db = pdom.getDB();
|
||||
int stringRecord = db.getInt(record + STRING_REC_OFFSET);
|
||||
return db.getString(stringRecord);
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "PDOMString", e)));
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public char[] getNameCharArray() {
|
||||
try {
|
||||
Database db = pdom.getDB();
|
||||
int stringRecord = db.getInt(record + STRING_REC_OFFSET);
|
||||
return db.getChars(stringRecord);
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "PDOMString", e)));
|
||||
return new char[0];
|
||||
}
|
||||
}
|
||||
|
||||
public IScope getScope() throws DOMException {
|
||||
// TODO implement this
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PDOMBinding find(PDOMDatabase pdom, char[] name) throws IOException {
|
||||
BTree index = pdom.getBindingIndex();
|
||||
int bindingRecord = new FindVisitor(pdom.getDB(), name).findIn(index);
|
||||
if (bindingRecord != 0)
|
||||
return new PDOMBinding(pdom, bindingRecord);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.pdom.dom;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMDatabase;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.BTree;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.StringComparator;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.StringVisitor;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* Represents a file containing names.
|
||||
*
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class PDOMFile {
|
||||
|
||||
private PDOMDatabase pdom;
|
||||
private int record;
|
||||
|
||||
private static final int FIRST_NAME_OFFSET = 0;
|
||||
private static final int FILE_NAME_OFFSET = Database.INT_SIZE;
|
||||
|
||||
public static class Comparator extends StringComparator {
|
||||
|
||||
public Comparator(Database db) {
|
||||
super(db, FILE_NAME_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class Visitor extends StringVisitor {
|
||||
|
||||
public Visitor(Database db, String key) {
|
||||
super(db, FILE_NAME_OFFSET, key);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FindVisitor extends Visitor {
|
||||
|
||||
private int record;
|
||||
|
||||
public FindVisitor(Database db, String key) {
|
||||
super(db, key);
|
||||
}
|
||||
|
||||
public boolean visit(int record) throws IOException {
|
||||
this.record = record;
|
||||
return false;
|
||||
}
|
||||
|
||||
public int findIn(BTree btree) throws IOException {
|
||||
btree.visit(this);
|
||||
return record;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static PDOMFile insert(PDOMDatabase pdom, String filename) throws IOException {
|
||||
BTree index = pdom.getFileIndex();
|
||||
PDOMFile pdomFile = find(pdom, filename);
|
||||
if (pdomFile == null) {
|
||||
Database db = pdom.getDB();
|
||||
int record = db.malloc(FILE_NAME_OFFSET + (filename.length() + 1) * Database.CHAR_SIZE);
|
||||
db.putInt(record + FIRST_NAME_OFFSET, 0);
|
||||
db.putString(record + FILE_NAME_OFFSET, filename);
|
||||
index.insert(record, new Comparator(db));
|
||||
pdomFile = new PDOMFile(pdom, record);
|
||||
}
|
||||
return pdomFile;
|
||||
}
|
||||
|
||||
public static PDOMFile find(PDOMDatabase pdom, String filename) throws IOException {
|
||||
BTree index = pdom.getFileIndex();
|
||||
int record = new FindVisitor(pdom.getDB(), filename).findIn(index);
|
||||
return (record != 0) ? new PDOMFile(pdom, record) : null;
|
||||
}
|
||||
|
||||
public PDOMFile(PDOMDatabase pdom, int record) {
|
||||
this.pdom = pdom;
|
||||
this.record = record;
|
||||
}
|
||||
|
||||
public int getRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
public String getFileName() throws IOException {
|
||||
return pdom.getDB().getString(record + FILE_NAME_OFFSET);
|
||||
}
|
||||
|
||||
public int getFirstName() throws IOException {
|
||||
return pdom.getDB().getInt(record + FIRST_NAME_OFFSET);
|
||||
}
|
||||
|
||||
public void setFirstName(int firstName) throws IOException {
|
||||
pdom.getDB().putInt(record + FIRST_NAME_OFFSET, firstName);
|
||||
}
|
||||
|
||||
public void free() throws CoreException {
|
||||
try {
|
||||
pdom.getDB().free(record);
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "Failed to free string", e));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.pdom.dom;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope2;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMDatabase;
|
||||
import org.eclipse.cdt.internal.core.pdom.db.Database;
|
||||
import org.eclipse.cdt.pdom.core.PDOMCorePlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class PDOMName implements IASTName, IASTFileLocation {
|
||||
|
||||
private final PDOMDatabase pdom;
|
||||
private final int record;
|
||||
|
||||
private static final int FILE_REC_OFFSET = 0 * Database.INT_SIZE;
|
||||
private static final int FILE_PREV_OFFSET = 1 * Database.INT_SIZE;
|
||||
private static final int FILE_NEXT_OFFSET = 2 * Database.INT_SIZE;
|
||||
private static final int BINDING_REC_OFFET = 3 * Database.INT_SIZE;
|
||||
private static final int BINDING_PREV_OFFSET = 4 * Database.INT_SIZE;
|
||||
private static final int BINDING_NEXT_OFFSET = 5 * Database.INT_SIZE;
|
||||
private static final int NODE_OFFSET_OFFSET = 6 * Database.INT_SIZE;
|
||||
private static final int NODE_LENGTH_OFFSET = 7 * Database.INT_SIZE;
|
||||
|
||||
private static final int RECORD_SIZE = 8 * Database.INT_SIZE;
|
||||
|
||||
public PDOMName(PDOMDatabase pdom, IASTName name, PDOMBinding binding) throws CoreException {
|
||||
try {
|
||||
this.pdom = pdom;
|
||||
Database db = pdom.getDB();
|
||||
record = db.malloc(RECORD_SIZE);
|
||||
|
||||
// Hook us up to the binding
|
||||
if (binding != null) {
|
||||
db.putInt(record + BINDING_REC_OFFET, binding.getRecord());
|
||||
if (name.isDeclaration())
|
||||
binding.addDeclaration(this);
|
||||
}
|
||||
|
||||
// Hook us up the the liked name list from file
|
||||
IASTFileLocation fileloc = name.getFileLocation();
|
||||
String filename = fileloc.getFileName();
|
||||
PDOMFile pdomFile = PDOMFile.insert(pdom, filename);
|
||||
db.putInt(record + FILE_REC_OFFSET, pdomFile.getRecord());
|
||||
int firstName = pdomFile.getFirstName();
|
||||
if (firstName != 0) {
|
||||
db.putInt(record + FILE_NEXT_OFFSET, firstName);
|
||||
db.putInt(firstName + FILE_PREV_OFFSET, record);
|
||||
}
|
||||
pdomFile.setFirstName(record);
|
||||
|
||||
db.putInt(record + NODE_OFFSET_OFFSET, fileloc.getNodeOffset());
|
||||
db.putInt(record + NODE_LENGTH_OFFSET, fileloc.getNodeLength());
|
||||
} catch (IOException e) {
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "Failed to allocate name", e));
|
||||
}
|
||||
}
|
||||
|
||||
public PDOMName(PDOMDatabase pdom, int nameRecord) throws IOException {
|
||||
this.pdom = pdom;
|
||||
this.record = nameRecord;
|
||||
}
|
||||
|
||||
public int getRecord() {
|
||||
return record;
|
||||
}
|
||||
|
||||
public void setBinding(PDOMBinding binding) throws IOException {
|
||||
pdom.getDB().putInt(record + BINDING_REC_OFFET, binding.getRecord());
|
||||
}
|
||||
|
||||
public void setPrevInBinding(PDOMName prevName) throws IOException {
|
||||
pdom.getDB().putInt(record + BINDING_PREV_OFFSET, prevName.getRecord());
|
||||
}
|
||||
|
||||
public void setNextInBinding(PDOMName nextName) throws IOException {
|
||||
pdom.getDB().putInt(record + BINDING_NEXT_OFFSET, nextName.getRecord());
|
||||
}
|
||||
|
||||
public IBinding resolveBinding() {
|
||||
try {
|
||||
int bindingRecord = pdom.getDB().getInt(record + BINDING_REC_OFFET);
|
||||
return new PDOMBinding(pdom, bindingRecord);
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "Failed to allocate name", e)));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public IBinding getBinding() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public void setBinding(IBinding binding) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IBinding[] resolvePrefix() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public char[] toCharArray() {
|
||||
try {
|
||||
Database db = pdom.getDB();
|
||||
int bindingRec = db.getInt(record + BINDING_REC_OFFET);
|
||||
if (bindingRec == 0)
|
||||
return null;
|
||||
|
||||
return new PDOMBinding(pdom, bindingRec).getNameCharArray();
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "Failed to allocate name", e)));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDeclaration() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public boolean isReference() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public boolean isDefinition() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getTranslationUnit() {
|
||||
// TODO Bug 115367 this is dumb - only need for validation checks
|
||||
return new PDOMTranslationUnit();
|
||||
}
|
||||
|
||||
public IASTNodeLocation[] getNodeLocations() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTFileLocation getFileLocation() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getContainingFilename() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTNode getParent() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public void setParent(IASTNode node) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public ASTNodeProperty getPropertyInParent() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public void setPropertyInParent(ASTNodeProperty property) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public boolean accept(ASTVisitor visitor) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public String getRawSignature() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public int getEndingLineNumber() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
try {
|
||||
return new PDOMFile(pdom, pdom.getDB().getInt(record + FILE_REC_OFFSET)).getFileName();
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "PDOM Exception", e)));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int getStartingLineNumber() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTFileLocation asFileLocation() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public int getNodeLength() {
|
||||
try {
|
||||
return pdom.getDB().getInt(record + NODE_LENGTH_OFFSET);
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "PDOM Exception", e)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getNodeOffset() {
|
||||
try {
|
||||
return pdom.getDB().getInt(record + NODE_OFFSET_OFFSET);
|
||||
} catch (IOException e) {
|
||||
PDOMCorePlugin.log(new CoreException(new Status(IStatus.ERROR,
|
||||
PDOMCorePlugin.ID, 0, "PDOM Exception", e)));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public IScope2 getScope(IASTNode child, ASTNodeProperty childProperty) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.pdom.dom;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
*/
|
||||
public class PDOMNotImplementedError extends Error {
|
||||
|
||||
public static final long serialVersionUID = 0;
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* QNX - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.pdom.dom;
|
||||
|
||||
import org.eclipse.cdt.core.dom.IPDOM;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope2;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
*
|
||||
* This is really a dummy translation unit that is necessary for names
|
||||
* to be valid.
|
||||
*/
|
||||
public class PDOMTranslationUnit implements IASTTranslationUnit {
|
||||
|
||||
public IASTDeclaration[] getDeclarations() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public void addDeclaration(IASTDeclaration declaration) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IScope getScope() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTName[] getDeclarations(IBinding binding) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTName[] getDefinitions(IBinding binding) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTName[] getReferences(IBinding binding) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTNodeLocation[] getLocationInfo(int offset, int length) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTNode selectNodeForLocation(String path, int offset, int length) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTPreprocessorMacroDefinition[] getMacroDefinitions() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTPreprocessorIncludeStatement[] getIncludeDirectives() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTPreprocessorStatement[] getAllPreprocessorStatements() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTProblem[] getPreprocessorProblems() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public String getUnpreprocessedSignature(IASTNodeLocation[] locations) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTFileLocation flattenLocationsToFile(
|
||||
IASTNodeLocation[] nodeLocations) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IDependencyTree getDependencyTree() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public String getContainingFilename(int offset) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public ParserLanguage getParserLanguage() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IPDOM getIndex() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public void setIndex(IPDOM pdom) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getTranslationUnit() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTNodeLocation[] getNodeLocations() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTFileLocation getFileLocation() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public String getContainingFilename() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IASTNode getParent() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public void setParent(IASTNode node) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public ASTNodeProperty getPropertyInParent() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public void setPropertyInParent(ASTNodeProperty property) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public boolean accept(ASTVisitor visitor) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public String getRawSignature() {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
public IScope2 getScope(IASTNode child, ASTNodeProperty childProperty) {
|
||||
throw new PDOMNotImplementedError();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package org.eclipse.cdt.pdom.core;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The main plugin class to be used in the desktop.
|
||||
*/
|
||||
public class PDOMCorePlugin extends Plugin {
|
||||
|
||||
public static final String ID = "org.eclipse.cdt.pdom.core"; //$NON-NLS-1$
|
||||
|
||||
//The shared instance.
|
||||
private static PDOMCorePlugin plugin;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public PDOMCorePlugin() {
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called upon plug-in activation
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the plug-in is stopped
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
super.stop(context);
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance.
|
||||
*/
|
||||
public static PDOMCorePlugin getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public static void log(CoreException e) {
|
||||
plugin.getLog().log(e.getStatus());
|
||||
}
|
||||
|
||||
}
|
|
@ -71,3 +71,5 @@ asmSourceName=Assembly Source File
|
|||
cdt_pathentry_var.description=CDT PathEntry Variable
|
||||
|
||||
PDOMProviderName=PDOM Provider
|
||||
|
||||
language.name=Language
|
|
@ -44,6 +44,7 @@
|
|||
<extension-point id="CodeFormatter" name="%CodeFormatter.name" schema="schema/CodeFormatter.exsd"/>
|
||||
<extension-point id="CIndexer" name="C/C++ Indexer" schema="schema/CIndexer.exsd"/>
|
||||
<extension-point id="PDOMProvider" name="%PDOMProviderName" schema="schema/PDOMProvider.exsd"/>
|
||||
<extension-point id="language" name="%language.name" schema="schema/language.exsd"/>
|
||||
<!-- =================================================================================== -->
|
||||
<!-- Define the list of the Binary Parser provided by the CDT -->
|
||||
<!-- =================================================================================== -->
|
||||
|
@ -575,6 +576,21 @@
|
|||
class="org.eclipse.cdt.internal.core.SystemBuildConsole"
|
||||
id="org.eclipse.cdt.core.systemConsole"/>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.language">
|
||||
<language
|
||||
class="org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage"
|
||||
id="gcc"
|
||||
name="GNU C">
|
||||
<contentType id="org.eclipse.cdt.core.cSource"/>
|
||||
</language>
|
||||
<language
|
||||
class="org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage"
|
||||
id="g++"
|
||||
name="GNU C++">
|
||||
<contentType id="org.eclipse.cdt.core.cxxSource"/>
|
||||
</language>
|
||||
</extension>
|
||||
|
||||
<!-- =================================================================================== -->
|
||||
<!-- Dynamic Variables -->
|
||||
|
|
134
core/org.eclipse.cdt.core/schema/language.exsd
Normal file
134
core/org.eclipse.cdt.core/schema/language.exsd
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Schema file written by PDE -->
|
||||
<schema targetNamespace="org.eclipse.cdt.core">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="org.eclipse.cdt.core" id="language" name="%language.name"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter description of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref="language"/>
|
||||
</sequence>
|
||||
<attribute name="point" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute translatable="true"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="language">
|
||||
<complexType>
|
||||
<sequence>
|
||||
<element ref="contentType"/>
|
||||
</sequence>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="class" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute kind="java" basedOn="org.eclipse.cdt.core.dom.ILanguage"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="contentType">
|
||||
<complexType>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="since"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter the first release in which this extension point appears.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="examples"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter extension point usage example here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="apiInfo"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter API information here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="implementation"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter information about supplied implementation of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="copyright"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
</schema>
|
|
@ -87,6 +87,7 @@ public class CCorePlugin extends Plugin {
|
|||
public static final String INDEXER_SIMPLE_ID = "CIndexer"; //$NON-NLS-1$
|
||||
public static final String INDEXER_UNIQ_ID = PLUGIN_ID + "." + INDEXER_SIMPLE_ID; //$NON-NLS-1$
|
||||
public final static String PREF_INDEXER = "indexer"; //$NON-NLS-1$
|
||||
public final static String USE_PDOM_PREF = "usePDOM"; //$NON-NLS-1$
|
||||
public final static String DEFAULT_INDEXER_SIMPLE_ID = "domsourceindexer"; //$NON-NLS-1$
|
||||
public final static String NULL_INDEXER_SIMPLE_ID = "nullindexer"; //$NON-NLS-1$
|
||||
public final static String NULL_INDEXER_UNIQUE_ID = PLUGIN_ID + "." + NULL_INDEXER_SIMPLE_ID ; //$NON-NLS-1$
|
||||
|
|
|
@ -10,15 +10,21 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.IElementChangedListener;
|
||||
import org.eclipse.cdt.internal.core.dom.NullPDOMProvider;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ProjectScope;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||
import org.osgi.service.prefs.BackingStoreException;
|
||||
|
||||
/**
|
||||
* @author Doug Schaefer
|
||||
|
@ -56,6 +62,37 @@ public class PDOM {
|
|||
return pdomProvider;
|
||||
}
|
||||
|
||||
private static final String PDOM_NODE = CCorePlugin.PLUGIN_ID + ".pdom"; //$NON-NLS-1$
|
||||
private static final String ENABLED_KEY = "enabled"; //$NON-NLS-1$
|
||||
|
||||
private static IEclipsePreferences getPreferences(IProject project) {
|
||||
IScopeContext projectScope = new ProjectScope(project);
|
||||
if (projectScope == null)
|
||||
return null;
|
||||
else
|
||||
return projectScope.getNode(PDOM_NODE);
|
||||
}
|
||||
|
||||
public static boolean isEnabled(IProject project) {
|
||||
IEclipsePreferences prefs = getPreferences(project);
|
||||
if (prefs == null)
|
||||
return false;
|
||||
else
|
||||
return prefs.getBoolean(ENABLED_KEY, false);
|
||||
}
|
||||
|
||||
public static void setEnabled(IProject project, boolean enabled) {
|
||||
IEclipsePreferences prefs = getPreferences(project);
|
||||
if (prefs == null)
|
||||
return;
|
||||
|
||||
prefs.putBoolean(ENABLED_KEY, enabled);
|
||||
try {
|
||||
prefs.flush();
|
||||
} catch (BackingStoreException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PDOM for the given project.
|
||||
*
|
||||
|
@ -63,11 +100,15 @@ public class PDOM {
|
|||
* @return the PDOM for the project
|
||||
*/
|
||||
public static IPDOM getPDOM(IProject project) {
|
||||
return getPDOMProvider().getPDOM(project);
|
||||
if (isEnabled(project))
|
||||
return PDOMManager.getInstance().getPDOM(project);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void deletePDOM(IProject project) throws CoreException {
|
||||
getPDOMProvider().getPDOM(project).delete();
|
||||
if (isEnabled(project))
|
||||
getPDOMProvider().getPDOM(project).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -68,3 +68,5 @@ PathEntryVariableResolver.0=CDT PathEntry variable not specified
|
|||
CTagsIndexMarker.fileMissing=CTags output file missing
|
||||
CTagsIndexMarker.CTagsMissing=CTags not installed or not in path
|
||||
DOMIndexerMarker.EmptyScannerInfo=File not indexed because it was not built
|
||||
|
||||
dom.languageError=Language not found
|
||||
|
|
|
@ -171,7 +171,7 @@ public class InternalASTServiceProvider implements IASTServiceProvider {
|
|||
// Parse
|
||||
IASTTranslationUnit tu = parser.parse();
|
||||
// Set the PDOM if we can find one
|
||||
tu.setPDOM(PDOM.getPDOM(project));
|
||||
tu.setIndex(PDOM.getPDOM(project));
|
||||
return tu;
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ public class InternalASTServiceProvider implements IASTServiceProvider {
|
|||
parser.parse();
|
||||
ASTCompletionNode node = parser.getCompletionNode();
|
||||
if (node != null) {
|
||||
node.getTranslationUnit().setPDOM(PDOM.getPDOM(project));
|
||||
node.getTranslationUnit().setIndex(PDOM.getPDOM(project));
|
||||
node.count = scanner.getCount();
|
||||
}
|
||||
return node;
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Iterator;
|
|||
import org.eclipse.cdt.core.browser.IWorkingCopyProvider;
|
||||
import org.eclipse.cdt.core.dom.CDOM;
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||
|
@ -51,6 +52,10 @@ public class PartialWorkingCopyCodeReaderFactory
|
|||
return checkWorkingCopyThenCache(path);
|
||||
}
|
||||
|
||||
public CodeReader createCodeReaderForTranslationUnit(ITranslationUnit tu) {
|
||||
return new CodeReader(tu.getPath().toOSString(), tu.getContents());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param path
|
||||
* @return
|
||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom;
|
|||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.CDOM;
|
||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.CodeReaderCache;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
|
@ -77,6 +78,10 @@ public class SavedCodeReaderFactory implements ICodeReaderFactory {
|
|||
return cache.get(path);
|
||||
}
|
||||
|
||||
public CodeReader createCodeReaderForTranslationUnit(ITranslationUnit tu) {
|
||||
return new CodeReader(tu.getPath().toOSString(), tu.getContents());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String)
|
||||
*/
|
||||
|
|
|
@ -45,6 +45,7 @@ ErrorParserBlock.desc=Set the error parsers for this project
|
|||
BinaryParserBlock.label=Binary Parser
|
||||
BinaryParserBlock.desc=Set required binary parser for this project
|
||||
|
||||
BaseIndexerBlock.usePDOM=Use PDOM
|
||||
BaseIndexerBlock.label=C/C++ Indexer
|
||||
BaseIndexerBlock.desc=C/C++ Indexer setting for this project.
|
||||
BaseIndexerBlock.comboLabel=Available indexers
|
||||
|
|
|
@ -18,7 +18,9 @@ import java.util.List;
|
|||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.ICDescriptor;
|
||||
import org.eclipse.cdt.core.ICDescriptorOperation;
|
||||
import org.eclipse.cdt.core.dom.PDOM;
|
||||
import org.eclipse.cdt.internal.core.index.domsourceindexer.DOMSourceIndexer;
|
||||
import org.eclipse.cdt.internal.core.index.nullindexer.NullIndexer;
|
||||
import org.eclipse.cdt.internal.ui.CUIMessages;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.index.AbstractIndexerPage;
|
||||
|
@ -34,11 +36,14 @@ import org.eclipse.core.runtime.Platform;
|
|||
import org.eclipse.core.runtime.QualifiedName;
|
||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
|
@ -65,8 +70,9 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
private static final String INDEXER_LABEL = CUIPlugin.getResourceString("BaseIndexerBlock.label" ); //$NON-NLS-1$
|
||||
private static final String INDEXER_DESCRIPTION = CUIPlugin.getResourceString("BaseIndexerBlock.desc"); //$NON-NLS-1$
|
||||
private static final String INDEXER_COMBO_LABEL = CUIPlugin.getResourceString("BaseIndexerBlock.comboLabel"); //$NON-NLS-1$
|
||||
private static final String INDEXER_USE_PDOM = CUIPlugin.getResourceString("BaseIndexerBlock.usePDOM"); //$NON-NLS-1$
|
||||
|
||||
|
||||
private Button indexerUsePDOM;
|
||||
private Combo indexersComboBox;
|
||||
private HashMap indexerPageMap;
|
||||
private List indexerPageList;
|
||||
|
@ -74,6 +80,8 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
private Composite parentComposite;
|
||||
private ICOptionPage currentPage;
|
||||
|
||||
int nullIndexerIndex;
|
||||
|
||||
String initialSelected;
|
||||
private IPreferenceStore prefStore=CUIPlugin.getDefault().getPreferenceStore();
|
||||
|
||||
|
@ -200,6 +208,23 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
* @return
|
||||
*/
|
||||
private boolean createIndexerControls(Composite parent) {
|
||||
// PDOM selection
|
||||
indexerUsePDOM = new Button(parent, SWT.CHECK);
|
||||
indexerUsePDOM.setText(INDEXER_USE_PDOM);
|
||||
indexerUsePDOM.addSelectionListener(new SelectionListener() {
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
}
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
if (indexerUsePDOM.getSelection()) {
|
||||
indexersComboBox.select(nullIndexerIndex);
|
||||
setPage();
|
||||
indexersComboBox.setEnabled(false);
|
||||
} else
|
||||
indexersComboBox.setEnabled(true);
|
||||
}
|
||||
});
|
||||
indexerUsePDOM.setSelection(prefStore.getBoolean(CCorePlugin.USE_PDOM_PREF));
|
||||
|
||||
//TODO: Put in some logic to deal with old CDT project: upgrade old projects
|
||||
//to use the Classic CDT Indexer
|
||||
|
||||
|
@ -260,6 +285,8 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
for (int i = 0; i < infos.length; i++) {
|
||||
if (infos[i].getName().equals("indexerUI")) { //$NON-NLS-1$
|
||||
String id = infos[i].getAttribute("indexerID"); //$NON-NLS-1$
|
||||
if (NullIndexer.ID.equals(id))
|
||||
nullIndexerIndex = i;
|
||||
indexerPageMap.put(id, new IndexerPageConfiguration(infos[i]));
|
||||
indexerPageList.add(id);
|
||||
}
|
||||
|
@ -362,6 +389,7 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
}
|
||||
|
||||
if ( project != null) {
|
||||
PDOM.setEnabled(project, indexerUsePDOM.isEnabled());
|
||||
ICDescriptorOperation op = new ICDescriptorOperation() {
|
||||
|
||||
public void execute(ICDescriptor descriptor, IProgressMonitor monitor) throws CoreException {
|
||||
|
@ -388,6 +416,7 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
if (initialSelected == null || !selected.equals(initialSelected)) {
|
||||
|
||||
if (prefStore != null) {
|
||||
prefStore.setValue(CCorePlugin.USE_PDOM_PREF, indexerUsePDOM.getEnabled());
|
||||
//First clean out the old indexer settings
|
||||
String indexerId=prefStore.getString(CCorePlugin.PREF_INDEXER);
|
||||
ICOptionPage tempPage = getIndexerPage(indexerId);
|
||||
|
@ -450,6 +479,7 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
* @param project
|
||||
*/
|
||||
public void setIndexerID(String indexerID, IProject project) {
|
||||
indexerUsePDOM.setSelection(PDOM.isEnabled(project));
|
||||
//Get the corresponding text for the given indexer id
|
||||
selectedIndexerId = getIndexerPageName(indexerID);
|
||||
//Store the currently selected indexer id
|
||||
|
@ -483,4 +513,21 @@ public class IndexerBlock extends AbstractCOptionPage {
|
|||
return indexerID;
|
||||
}
|
||||
|
||||
public IProject getProject() {
|
||||
ICOptionContainer container = getContainer();
|
||||
if (container != null){
|
||||
return container.getProject();
|
||||
} else {
|
||||
return ((AbstractIndexerPage)currentPage).getCurrentProject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean getUsePDOM() {
|
||||
IProject project = getProject();
|
||||
if (project == null)
|
||||
return false;
|
||||
|
||||
return PDOM.isEnabled(project);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue