diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
new file mode 100644
index 00000000000..be8467ee061
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBTest.java
@@ -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);
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
index c06c432525f..b4290abd383 100644
--- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF
@@ -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,
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICProject.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICProject.java
index 6672b929710..b56477a92a4 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICProject.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ICProject.java
@@ -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();
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
index 1b4b4e1f703..b32c8f97efd 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ITranslationUnit.java
@@ -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 (.c
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
+ * @return
*/
- IASTTranslationUnit getASTTranslationUnit();
+ ILanguage getLanguage() throws CoreException;
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java
index 2f81831cc6b..29510e377cf 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CProject.java
@@ -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());
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
index edf8d6ffab1..31e59f2bc30 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/TranslationUnit.java
@@ -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);
}
@@ -647,24 +657,43 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
return res.exists();
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)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java
index 71eb306c22b..e1c36f7dfac 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java
@@ -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.
*
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndex.java
new file mode 100644
index 00000000000..7cd3bb88979
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndex.java
@@ -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();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndexReader.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndexReader.java
new file mode 100644
index 00000000000..be345fe2592
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndexReader.java
@@ -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 {
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndexWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndexWriter.java
new file mode 100644
index 00000000000..0c8345a9e35
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IIndexWriter.java
@@ -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 {
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ILanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ILanguage.java
new file mode 100644
index 00000000000..0e66d039394
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ILanguage.java
@@ -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);
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java
index c46c430a73d..a43dea25690 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java
@@ -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);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java
new file mode 100644
index 00000000000..bc79653505d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
new file mode 100644
index 00000000000..ac8687ad4d0
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java
index 35772bb18e9..ab2474f92ca 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTranslationUnit.java
@@ -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;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
index 691b4897143..e7bccf53498 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
@@ -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));
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java
index 5a0247ef127..ee44469ea26 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java
@@ -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;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java
index b6679617de3..6267671fd76 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java
@@ -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));
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java
index 847b7a6b4ca..d46e145500e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java
@@ -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)
*/
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java
new file mode 100644
index 00000000000..c1f21c4be73
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java
new file mode 100644
index 00000000000..dc4a92449c9
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMDatabase.java
@@ -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;
+// }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
new file mode 100644
index 00000000000..2e3b478447a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUpdator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUpdator.java
new file mode 100644
index 00000000000..9478b3b8305
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUpdator.java
@@ -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);
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUtils.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUtils.java
new file mode 100644
index 00000000000..00ca46a4755
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMUtils.java
@@ -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;
+
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java
new file mode 100644
index 00000000000..e5e03da1c46
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/BTree.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
new file mode 100644
index 00000000000..4fb13bc082d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
new file mode 100644
index 00000000000..3b09c2e925f
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java
@@ -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;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeComparator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeComparator.java
new file mode 100644
index 00000000000..e418cb22e42
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeComparator.java
@@ -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;
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeVisitor.java
new file mode 100644
index 00000000000..ccbd6a29ede
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/IBTreeVisitor.java
@@ -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;
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringComparator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringComparator.java
new file mode 100644
index 00000000000..9446a149687
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringComparator.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringVisitor.java
new file mode 100644
index 00000000000..c5f990ab854
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/StringVisitor.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMBinding.java
new file mode 100644
index 00000000000..245474718b3
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMBinding.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMFile.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMFile.java
new file mode 100644
index 00000000000..f1217abf95a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMFile.java
@@ -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));
+ }
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMName.java
new file mode 100644
index 00000000000..7c62d49f80c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMName.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMNotImplementedError.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMNotImplementedError.java
new file mode 100644
index 00000000000..68c6370a6e5
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMNotImplementedError.java
@@ -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;
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMTranslationUnit.java
new file mode 100644
index 00000000000..c2da38458e8
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/pdom/dom/PDOMTranslationUnit.java
@@ -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();
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/pdom/core/PDOMCorePlugin.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/pdom/core/PDOMCorePlugin.java
new file mode 100644
index 00000000000..7b73e59b65b
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/pdom/core/PDOMCorePlugin.java
@@ -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());
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties
index af47d7cd99c..954026614a8 100644
--- a/core/org.eclipse.cdt.core/plugin.properties
+++ b/core/org.eclipse.cdt.core/plugin.properties
@@ -70,4 +70,6 @@ asmSourceName=Assembly Source File
cdt_pathentry_var.description=CDT PathEntry Variable
-PDOMProviderName=PDOM Provider
\ No newline at end of file
+PDOMProviderName=PDOM Provider
+
+language.name=Language
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml
index 4d2f7f5bbc3..294bd2483a8 100644
--- a/core/org.eclipse.cdt.core/plugin.xml
+++ b/core/org.eclipse.cdt.core/plugin.xml
@@ -44,6 +44,7 @@
+
@@ -575,6 +576,21 @@
class="org.eclipse.cdt.internal.core.SystemBuildConsole"
id="org.eclipse.cdt.core.systemConsole"/>
+
+
+
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.core/schema/language.exsd b/core/org.eclipse.cdt.core/schema/language.exsd
new file mode 100644
index 00000000000..6f2c891eabb
--- /dev/null
+++ b/core/org.eclipse.cdt.core/schema/language.exsd
@@ -0,0 +1,134 @@
+
+
+
+
+
+
+
+
+ [Enter description of this extension point.]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [Enter the first release in which this extension point appears.]
+
+
+
+
+
+
+
+
+ [Enter extension point usage example here.]
+
+
+
+
+
+
+
+
+ [Enter API information here.]
+
+
+
+
+
+
+
+
+ [Enter information about supplied implementation of this extension point.]
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
index 51edecd6a91..856dca21f79 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
@@ -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$
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/PDOM.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/PDOM.java
index 061fc828d09..9980b39fdca 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/PDOM.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/dom/PDOM.java
@@ -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();
}
/**
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties
index d2378c085a9..3938be3b6a3 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CCorePluginResources.properties
@@ -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
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java
index 0545dd321a6..1b575bbb7dc 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java
@@ -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;
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java
index 1feb13ee4cb..7ca0c6ddb81 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java
@@ -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
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java
index 7633f3d43b0..bebb9643865 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java
@@ -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)
*/
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties
index f3b5673b782..3b7457891d2 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginResources.properties
@@ -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
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java
index 1ef45b6db17..43c1106f39a 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/dialogs/IndexerBlock.java
@@ -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);
+ }
}