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

Fix for 162168, storing enclosing definition in index.

This commit is contained in:
Markus Schorn 2006-11-16 16:21:02 +00:00
parent 83d041b828
commit f0f63b48ed
20 changed files with 553 additions and 240 deletions

View file

@ -0,0 +1,227 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
import java.io.IOException;
import java.util.regex.Pattern;
import junit.framework.TestSuite;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
public class EnclosingNamesTest extends BaseTestCase {
private static final IProgressMonitor NPM = new NullProgressMonitor();
private ICProject fCProject;
protected IIndex fIndex;
public EnclosingNamesTest(String name) {
super(name);
}
public static TestSuite suite() {
return suite(EnclosingNamesTest.class);
}
protected void setUp() throws CoreException {
fCProject= CProjectHelper.createCCProject("__encNamesTest__", "bin", IPDOMManager.ID_FAST_INDEXER);
CCoreInternals.getPDOMManager().reindex(fCProject);
fIndex= CCorePlugin.getIndexManager().getIndex(fCProject);
}
protected void tearDown() throws CoreException {
if (fCProject != null) {
CProjectHelper.delete(fCProject);
}
}
protected IProject getProject() {
return fCProject.getProject();
}
protected StringBuffer[] getContentsForTest(int blocks) throws IOException {
return TestSourceReader.getContentsForTest(
CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), blocks);
}
protected IFile createFile(IContainer container, String fileName, String contents) throws Exception {
return TestSourceReader.createFile(container, new Path(fileName), contents);
}
protected void waitForIndexer() {
assertTrue(CCorePlugin.getIndexManager().joinIndexer(10000, NPM));
}
protected Pattern[] getPattern(String qname) {
String[] parts= qname.split("::");
Pattern[] result= new Pattern[parts.length];
for (int i = 0; i < result.length; i++) {
result[i]= Pattern.compile(parts[i]);
}
return result;
}
protected void waitUntilFileIsIndexed(IFile file, int time) throws Exception {
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, time);
}
// void func();
// int var;
//
// void main() {
// func();
// var=1;
// };
public void testNestingWithFunction() throws Exception {
waitForIndexer();
String content= getContentsForTest(1)[0].toString();
IFile file= createFile(getProject().getProject(), "test.cpp", content);
waitUntilFileIsIndexed(file, 4000);
fIndex.acquireReadLock();
try {
IIndexBinding[] mainBS= fIndex.findBindings(getPattern("main"), true, IndexFilter.ALL, NPM);
assertLength(1, mainBS);
IIndexBinding mainB= mainBS[0];
IIndexName[] names= fIndex.findDefinitions(mainB);
assertLength(1, names);
IIndexName main= names[0];
assertNull(main.getEnclosingDefinition());
IIndexName[] enclosed= main.getEnclosedNames();
assertLength(2, enclosed);
assertName("func", enclosed[0]);
assertName("var", enclosed[1]);
IIndexName enclosing= enclosed[0].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("main", enclosing);
enclosing= enclosed[1].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("main", enclosing);
}
finally {
fIndex.releaseReadLock();
}
}
private void assertName(String name, IIndexName iname) {
assertEquals(name, new String(iname.toCharArray()));
}
private void assertLength(int length, Object[] array) {
assertNotNull(array);
assertEquals(length, array.length);
}
// class C {
// public:
// void func();
// int var;
// };
//
// void main() {
// C c;
// c.func();
// c.var=1;
// };
// void C::func() {
// func();
// var=1;
// };
public void testNestingWithMethod() throws Exception {
waitForIndexer();
String content= getContentsForTest(1)[0].toString();
IFile file= createFile(getProject().getProject(), "test.cpp", content);
waitUntilFileIsIndexed(file, 4000);
fIndex.acquireReadLock();
try {
IIndexBinding[] mainBS= fIndex.findBindings(getPattern("main"), true, IndexFilter.ALL, NPM);
assertLength(1, mainBS);
IIndexBinding mainB= mainBS[0];
IIndexName[] names= fIndex.findDefinitions(mainB);
assertLength(1, names);
IIndexName main= names[0];
assertNull(main.getEnclosingDefinition());
IIndexName[] enclosed= main.getEnclosedNames();
assertLength(3, enclosed);
assertName("C", enclosed[0]);
assertName("func", enclosed[1]);
assertName("var", enclosed[2]);
IIndexName enclosing= enclosed[0].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("main", enclosing);
enclosing= enclosed[1].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("main", enclosing);
enclosing= enclosed[2].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("main", enclosing);
IIndexBinding funcB= fIndex.findBinding(enclosed[1]);
assertNotNull(funcB);
names= fIndex.findDefinitions(funcB);
assertLength(1, names);
IIndexName funcdef= names[0];
assertNull(funcdef.getEnclosingDefinition());
enclosed= funcdef.getEnclosedNames();
assertLength(3, enclosed);
assertName("C", enclosed[0]);
assertName("func", enclosed[1]);
assertName("var", enclosed[2]);
enclosing= enclosed[0].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("func", enclosing);
enclosing= enclosed[1].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("func", enclosing);
enclosing= enclosed[2].getEnclosingDefinition();
assertNotNull(enclosing);
assertName("func", enclosing);
}
finally {
fIndex.releaseReadLock();
}
}
}

View file

@ -74,8 +74,9 @@ public class IndexBugsTests extends BaseTestCase {
return fCProject.getProject();
}
protected String readTaggedComment(final String tag) throws IOException {
return TestSourceReader.readTaggedComment(CTestPlugin.getDefault().getBundle(), "parser", getClass(), tag);
protected StringBuffer[] getContentsForTest(int blocks) throws IOException {
return TestSourceReader.getContentsForTest(
CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), blocks);
}
protected IFile createFile(IContainer container, String fileName, String contents) throws Exception {
@ -99,7 +100,6 @@ public class IndexBugsTests extends BaseTestCase {
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, time);
}
// {bug162011}
// namespace ns162011 {
// class Class162011 {
// friend void function162011(Class162011);
@ -107,7 +107,7 @@ public class IndexBugsTests extends BaseTestCase {
// void function162011(Class162011 x){};
// }
public void testBug162011() throws Exception {
String content = readTaggedComment("bug162011");
String content = getContentsForTest(1)[0].toString();
String fileName = "bug162011.cpp";
String funcName = "function162011";
String nsName = "ns162011";
@ -247,13 +247,12 @@ public class IndexBugsTests extends BaseTestCase {
}
}
// {test164500}
// #define macro164500 1
// #undef macro164500
// #define macro164500 2
public void test164500() throws Exception {
waitForIndexer();
String content= readTaggedComment("test164500");
String content= getContentsForTest(1)[0].toString();
IFile file= TestSourceReader.createFile(fCProject.getProject(), "test164500.cpp", content);
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, 4000);

View file

@ -7,6 +7,7 @@
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@ -108,4 +109,12 @@ public interface IASTNode {
*/
public String getRawSignature();
/**
* Returns whether this node contains the given one. The decision is made
* purly on location information and therefore the method is fast.
* @param node the node to check
* @return whether this node contains the given one.
* @since 4.0
*/
public boolean contains(IASTNode node);
}

View file

@ -51,4 +51,20 @@ public interface IIndexName extends IName {
* Returns the length of the name.
*/
public int getNodeLength();
/**
* Returns the name of the definition that contains this name.
* May return <code>null</code>.
* Currently this is implemented for function and method definitions, only.
*/
public IIndexName getEnclosingDefinition() throws CoreException;
/**
* Returns the names of the references contained in this definition.
* Returns <code>null</code>, if the name is not a definition.
*
* Currently the method works with function definitions, only.
*/
public IIndexName[] getEnclosedNames() throws CoreException;
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* IBM Rational Software - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -112,4 +113,12 @@ public abstract class ASTNode implements IASTNode {
return true;
}
public boolean contains(IASTNode node) {
if (node instanceof ASTNode) {
ASTNode astNode= (ASTNode) node;
return offset <= astNode.offset &&
astNode.offset+astNode.length <= offset+length;
}
return false;
}
}

View file

@ -35,7 +35,7 @@ public interface IWritableIndex extends IIndex {
*/
void setFileContent(IIndexFragmentFile sourceFile,
IASTPreprocessorIncludeStatement[] includes,
IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException;
IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException;
/**
* Clears the entire index.

View file

@ -41,7 +41,7 @@ public interface IWritableIndexFragment extends IIndexFragment {
*/
void addFileContent(IIndexFragmentFile sourceFile,
IASTPreprocessorIncludeStatement[] includes, IIndexFragmentFile[] destFiles,
IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException;
IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException;
/**
* Acquires a write lock, while giving up a certain amount of read locks.

View file

@ -57,7 +57,7 @@ public class WritableCIndex extends CIndex implements IWritableIndex {
public void setFileContent(IIndexFragmentFile file,
IASTPreprocessorIncludeStatement[] includes,
IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException {
IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException {
IIndexFragment indexFragment = file.getIndexFragment();
assert isWritableFragment(indexFragment);

View file

@ -64,7 +64,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
private Database db;
public static final int VERSION = 16;
public static final int VERSION = 17;
// 0 - the beginning of it all
// 1 - first change to kick off upgrades
// 2 - added file inclusions
@ -82,6 +82,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
// 14 - added timestamps for files (bug 149571)
// 15 - fixed offsets for pointer types and qualifier types and PDOMCPPVariable (bug 160540).
// 16 - have PDOMCPPField store type information, and PDOMCPPNamespaceAlias store what it is aliasing
// 17 - use single linked list for names in file, adds a link to enclosing defintion name.
public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4;
@ -460,7 +461,7 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
}
}
public void releaseWriteLock() {
final public void releaseWriteLock() {
releaseWriteLock(0);
}

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.core.runtime.CoreException;
@ -35,22 +36,14 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public void addFileContent(IIndexFragmentFile sourceFile,
IASTPreprocessorIncludeStatement[] includes, IIndexFragmentFile[] destFiles,
IASTPreprocessorMacroDefinition[] macros, IASTName[] names) throws CoreException {
IASTPreprocessorMacroDefinition[] macros, IASTName[][] names) throws CoreException {
assert sourceFile.getIndexFragment() == this;
assert includes.length == destFiles.length;
PDOMFile pdomFile = (PDOMFile) sourceFile;
pdomFile.addIncludesTo(destFiles, includes);
pdomFile.addMacros(macros);
for (int i = 0; i < names.length; i++) {
IASTName name= names[i];
PDOMLinkage linkage= createLinkage(name.getLinkage().getID());
if (linkage == null) {
CCorePlugin.log(MessageFormat.format(Messages.WritablePDOM_error_unknownLinkage, new Object[]{name.getLinkage()}));
}
else {
linkage.addName(name, pdomFile);
}
}
pdomFile.addNames(names);
}
public void clearFile(IIndexFragmentFile file) throws CoreException {
@ -61,4 +54,16 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
public void clear() throws CoreException {
super.clear();
}
public PDOMBinding addBinding(IASTName name) throws CoreException {
PDOMBinding result= null;
PDOMLinkage linkage= createLinkage(name.getLinkage().getID());
if (linkage == null) {
CCorePlugin.log(MessageFormat.format(Messages.WritablePDOM_error_unknownLinkage, new Object[]{name.getLinkage()}));
}
else {
result= linkage.addBinding(name);
}
return result;
}
}

View file

@ -12,8 +12,10 @@
package org.eclipse.cdt.internal.core.pdom.dom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.index.IIndexInclude;
@ -22,6 +24,7 @@ import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.WritablePDOM;
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;
@ -149,15 +152,6 @@ public class PDOMFile implements IIndexFragmentFile {
pdom.getDB().putInt(record + FIRST_NAME, namerec);
}
public void addName(PDOMName name) throws CoreException {
PDOMName firstName = getFirstName();
if (firstName != null) {
name.setNextInFile(firstName);
firstName.setPrevInFile(name);
}
setFirstName(name);
}
public PDOMInclude getFirstInclude() throws CoreException {
int increc = pdom.getDB().getInt(record + FIRST_INCLUDE);
return increc != 0 ? new PDOMInclude(pdom, increc) : null;
@ -205,6 +199,36 @@ public class PDOMFile implements IIndexFragmentFile {
}
}
public void addNames(IASTName[][] names) throws CoreException {
assert getFirstName() == null;
HashMap nameCache= new HashMap();
PDOMName lastName= null;
for (int i = 0; i < names.length; i++) {
IASTName[] name = names[i];
PDOMName caller= (PDOMName) nameCache.get(name[1]);
PDOMName pdomName = createPDOMName(name[0], caller);
if (pdomName != null) {
nameCache.put(name[0], pdomName);
if (lastName == null) {
setFirstName(pdomName);
}
else {
lastName.setNextInFile(pdomName);
}
lastName= pdomName;
}
}
}
private PDOMName createPDOMName(IASTName name, PDOMName caller) throws CoreException {
PDOMName result= null;
PDOMBinding binding= ((WritablePDOM) pdom).addBinding(name);
if (binding != null) {
result= new PDOMName(pdom, name, this, binding, caller);
}
return result;
}
public void clear() throws CoreException {
// Remove the includes
PDOMInclude include = getFirstInclude();

View file

@ -168,7 +168,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IBindingIdent
};
}
public abstract PDOMBinding addName(IASTName name, PDOMFile file) throws CoreException;
public abstract PDOMBinding addBinding(IASTName name) throws CoreException;
public abstract PDOMBinding adaptBinding(IBinding binding) throws CoreException;

View file

@ -11,10 +11,13 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
import java.util.ArrayList;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
import org.eclipse.cdt.internal.core.index.IIndexProxyBinding;
@ -32,23 +35,23 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
private final int record;
private static final int FILE_REC_OFFSET = 0;
private static final int FILE_PREV_OFFSET = 4;
private static final int FILE_NEXT_OFFSET = 8;
private static final int FILE_NEXT_OFFSET = 4;
private static final int CALLER_REC_OFFSET = 8;
private static final int BINDING_REC_OFFSET = 12;
private static final int BINDING_PREV_OFFSET = 16;
private static final int BINDING_NEXT_OFFSET = 20;
private static final int NODE_OFFSET_OFFSET = 24;
private static final int NODE_LENGTH_OFFSET = 28;
private static final int FLAGS = 32;
private static final int NODE_LENGTH_OFFSET = 28; // short
private static final int FLAGS = 30; // byte
private static final int RECORD_SIZE = 33;
private static final int RECORD_SIZE = 31;
private static final int IS_DECLARATION = 1;
private static final int IS_DEFINITION = 2;
private static final int IS_REFERENCE = 3;
public PDOMName(PDOM pdom, IASTName name, PDOMFile file, PDOMBinding binding) throws CoreException {
public PDOMName(PDOM pdom, IASTName name, PDOMFile file, PDOMBinding binding, PDOMName caller) throws CoreException {
this.pdom = pdom;
Database db = pdom.getDB();
record = db.malloc(RECORD_SIZE);
@ -80,14 +83,15 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
db.putInt(record + BINDING_REC_OFFSET, binding.getRecord());
}
// Hook us up the the liked name list from file
db.putInt(record + FILE_REC_OFFSET, file.getRecord());
file.addName(this);
if (caller != null) {
db.putInt(record + CALLER_REC_OFFSET, caller.getRecord());
}
// Record our location in the file
IASTFileLocation fileloc = name.getFileLocation();
db.putInt(record + NODE_OFFSET_OFFSET, fileloc.getNodeOffset());
db.putInt(record + NODE_LENGTH_OFFSET, fileloc.getNodeLength());
db.putShort(record + NODE_LENGTH_OFFSET, (short) fileloc.getNodeLength());
}
public PDOMName(PDOM pdom, int nameRecord) {
@ -147,6 +151,15 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
int filerec = pdom.getDB().getInt(record + FILE_REC_OFFSET);
return filerec != 0 ? new PDOMFile(pdom, filerec) : null;
}
public IIndexName getEnclosingDefinition() throws CoreException {
int namerec = getEnclosingDefinitionRecord();
return namerec != 0 ? new PDOMName(pdom, namerec) : null;
}
private int getEnclosingDefinitionRecord() throws CoreException {
return pdom.getDB().getInt(record + CALLER_REC_OFFSET);
}
public PDOMName getNextInFile() throws CoreException {
return getNameField(FILE_NEXT_OFFSET);
@ -155,15 +168,7 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public void setNextInFile(PDOMName name) throws CoreException {
setNameField(FILE_NEXT_OFFSET, name);
}
public PDOMName getPrevInFile() throws CoreException {
return getNameField(FILE_PREV_OFFSET);
}
public void setPrevInFile(PDOMName name) throws CoreException {
setNameField(FILE_PREV_OFFSET, name);
}
public PDOMBinding resolveBinding() {
try {
int bindingRecord = pdom.getDB().getInt(record + BINDING_REC_OFFSET);
@ -248,7 +253,7 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public int getNodeLength() {
try {
return pdom.getDB().getInt(record + NODE_LENGTH_OFFSET);
return pdom.getDB().getShort(record + NODE_LENGTH_OFFSET);
} catch (CoreException e) {
CCorePlugin.log(e);
return 0;
@ -298,4 +303,16 @@ public class PDOMName implements IIndexFragmentName, IASTFileLocation {
public IIndexProxyBinding getBinding() throws CoreException {
return getPDOMBinding();
}
public IIndexName[] getEnclosedNames() throws CoreException {
ArrayList result= new ArrayList();
PDOMName name= getNextInFile();
while (name != null) {
if (name.getEnclosingDefinitionRecord() == record) {
result.add(name);
}
name= name.getNextInFile();
}
return (IIndexName[]) result.toArray(new IIndexName[result.size()]);
}
}

View file

@ -43,9 +43,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.FindBindingByLinkageConstant;
import org.eclipse.cdt.internal.core.pdom.dom.FindEquivalentBinding;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Status;
@ -85,9 +83,7 @@ class PDOMCLinkage extends PDOMLinkage {
return new GCCLanguage();
}
public PDOMBinding addName(IASTName name, PDOMFile file) throws CoreException {
public PDOMBinding addBinding(IASTName name) throws CoreException {
if (name == null)
return null;
@ -149,10 +145,6 @@ class PDOMCLinkage extends PDOMLinkage {
} catch (DOMException e) {
throw new CoreException(Util.createStatus(e));
}
if (pdomBinding != null)
new PDOMName(pdom, name, file, pdomBinding);
return pdomBinding;
}

View file

@ -316,7 +316,9 @@ ICPPClassScope, IPDOMMemberOwner {
}
}
public void addChild(PDOMNode member) throws CoreException {addMember(member);}
public void addChild(PDOMNode member) throws CoreException {
addMember(member);
}
public ICPPConstructor[] getConstructors() throws DOMException {
// TODO

View file

@ -15,7 +15,6 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
@ -69,9 +68,7 @@ import org.eclipse.cdt.internal.core.pdom.dom.FindBindingByLinkageConstant;
import org.eclipse.cdt.internal.core.pdom.dom.FindEquivalentBinding;
import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNotImplementedError;
import org.eclipse.core.runtime.CoreException;
@ -120,8 +117,7 @@ class PDOMCPPLinkage extends PDOMLinkage {
return new GPPLanguage();
}
public PDOMBinding addName(IASTName name, PDOMFile file) throws CoreException {
public PDOMBinding addBinding(IASTName name) throws CoreException {
if (name == null || name instanceof ICPPASTQualifiedName)
return null;
@ -198,9 +194,6 @@ class PDOMCPPLinkage extends PDOMLinkage {
// final processing
if (pdomBinding != null) {
// Add in the name
new PDOMName(pdom, name, file, pdomBinding);
// Check if is a base specifier
if (pdomBinding instanceof ICPPClassType && name.getParent() instanceof ICPPASTBaseSpecifier) {
ICPPASTBaseSpecifier baseNode = (ICPPASTBaseSpecifier)name.getParent();
@ -297,8 +290,6 @@ class PDOMCPPLinkage extends PDOMLinkage {
}
private PDOMBinding _resolveBinding(IASTName name) throws CoreException, DOMException {
// mstodo revisit
IBinding origBinding = name.getBinding();
if (origBinding != null)
return adaptBinding(origBinding);
@ -398,7 +389,7 @@ class PDOMCPPLinkage extends PDOMLinkage {
PDOMBinding pdomFOB = adaptBinding( (ICompositeType) type);
FindBindingByLinkageConstant visitor = new FindBindingByLinkageConstant(this, name.toCharArray(), PDOMCPPLinkage.CPPFIELD);
try {
((PDOMBinding)pdomFOB).accept(visitor);
pdomFOB.accept(visitor);
} catch (CoreException e) {
if (e.getStatus().equals(Status.OK_STATUS)) {
return visitor.getResult();

View file

@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.indexer;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
abstract public class IndexerASTVisitor extends ASTVisitor {
private IASTName fDefinitionName;
private IASTNode fDefinition;
public IndexerASTVisitor() {
shouldVisitNames = true;
shouldVisitDeclarations = true;
}
abstract public void visit(IASTName name, IASTName definitionName);
final public int visit(IASTName name) {
if (!(name instanceof ICPPASTQualifiedName)) {
if (fDefinition != null) {
if (!fDefinition.contains(name)) {
fDefinition= null;
fDefinitionName= null;
}
}
if (name != fDefinitionName) {
visit(name, fDefinitionName);
}
}
return PROCESS_CONTINUE;
}
public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
fDefinition= decl;
fDefinitionName= fdef.getDeclarator().getName();
if (fDefinitionName instanceof ICPPASTQualifiedName) {
fDefinitionName= ((ICPPASTQualifiedName) fDefinitionName).getLastName();
}
visit(fDefinitionName, null);
}
return PROCESS_CONTINUE;
}
}

View file

@ -14,15 +14,21 @@ package org.eclipse.cdt.internal.core.pdom.indexer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexInclude;
@ -240,7 +246,90 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
return fCompletedSources;
}
protected IIndexFragmentFile addToIndex(IWritableIndex index, String location, ArrayList[] lists) throws CoreException {
/**
* Extracts a map of names from the ast and returns an array defining the order in
* which the symbols should be added to the index.
* @since 4.0
*/
protected String[] extractSymbols(IASTTranslationUnit ast, Set legalPaths, final LinkedHashMap symbolMap) {
// includes
final String astFilePath = ast.getFilePath();
IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
for (int i = includes.length-1; i >= 0; --i) {
IASTPreprocessorIncludeStatement include = includes[i];
IASTFileLocation sourceLoc = include.getFileLocation();
String path= sourceLoc != null ? sourceLoc.getFileName() : astFilePath; // command-line includes
if (legalPaths.contains(path)) {
prepareInMap(symbolMap, path);
addToMap(symbolMap, 0, path, include);
}
path= include.getPath();
if (legalPaths.contains(path)) {
prepareInMap(symbolMap, path);
}
}
if (legalPaths.contains(astFilePath)) {
prepareInMap(symbolMap, ast.getFilePath());
}
// macros
IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
for (int i = 0; i < macros.length; ++i) {
IASTPreprocessorMacroDefinition macro = macros[i];
IASTFileLocation sourceLoc = macro.getFileLocation();
if (sourceLoc != null) { // skip built-ins and command line macros
String path = sourceLoc.getFileName();
addToMap(symbolMap, 1, path, macro);
}
}
// names
ast.accept(new IndexerASTVisitor() {
public void visit(IASTName name, IASTName caller) {
IASTFileLocation nameLoc = name.getFileLocation();
if (nameLoc != null) {
addToMap(symbolMap, 2, nameLoc.getFileName(), new IASTName[]{name, caller});
}
}
});
Collection temp= symbolMap.keySet();
int size= temp.size();
String[] result= new String[temp.size()];
for (Iterator iter = temp.iterator(); iter.hasNext();) {
result[--size]= (String) iter.next();
}
return result;
}
private void addToMap(HashMap map, int idx, String path, Object thing) {
List[] lists= (List[]) map.get(path);
if (lists != null)
lists[idx].add(thing);
}
private boolean prepareInMap(Map map, String path) {
if (map.get(path) == null) {
Object lists= new ArrayList[]{new ArrayList(), new ArrayList(), new ArrayList()};
map.put(path, lists);
}
return false;
}
protected void prepareIndexInsertion(String path, Map symbolMap) {
ArrayList[] arrayLists = ((ArrayList[]) symbolMap.get(path));
// reverse the includes
Collections.reverse(arrayLists[0]);
// resolve the names
ArrayList names= arrayLists[2];
for (int j=0; j<names.size(); j++) {
((IASTName[]) names.get(j))[0].resolveBinding();
}
}
protected IIndexFragmentFile addToIndex(IWritableIndex index, String location, Map symbolMap) throws CoreException {
// Remove the old symbols in the tu
Path path= new Path(location);
IIndexFragmentFile file= (IIndexFragmentFile) index.getFile(path);
@ -251,13 +340,14 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask {
file= index.addFile(path);
}
file.setTimestamp(path.toFile().lastModified());
ArrayList[] lists= (ArrayList[]) symbolMap.get(location);
if (lists != null) {
ArrayList list= lists[0];
IASTPreprocessorIncludeStatement[] includes= (IASTPreprocessorIncludeStatement[]) list.toArray(new IASTPreprocessorIncludeStatement[list.size()]);
list= lists[1];
IASTPreprocessorMacroDefinition[] macros= (IASTPreprocessorMacroDefinition[]) list.toArray(new IASTPreprocessorMacroDefinition[list.size()]);
list= lists[2];
IASTName[] names= (IASTName[]) list.toArray(new IASTName[list.size()]);
IASTName[][] names= (IASTName[][]) list.toArray(new IASTName[list.size()][]);
index.setFileContent(file, includes, macros, names);
}

View file

@ -12,22 +12,15 @@
package org.eclipse.cdt.internal.core.pdom.indexer.fast;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
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.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.ILanguage;
import org.eclipse.cdt.core.model.ITranslationUnit;
@ -92,7 +85,7 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
return;
}
LinkedHashSet paths= new LinkedHashSet();
HashSet paths= new HashSet();
paths.add(path.toOSString());
codeReaderFactory.setPathCollector(paths);
index.acquireReadLock();
@ -114,71 +107,27 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
}
}
protected void addSymbols(Collection paths, IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
protected void addSymbols(HashSet paths, IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
// Add in the includes
final HashMap symbolMap= new HashMap();
final LinkedHashMap symbolMap= new LinkedHashMap();
String[] orderedPaths= extractSymbols(ast, paths, symbolMap);
// includes
IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
for (int i = 0; i < includes.length; ++i) {
IASTPreprocessorIncludeStatement include = includes[i];
IASTFileLocation sourceLoc = include.getFileLocation();
String path= sourceLoc != null ? sourceLoc.getFileName() : ast.getFilePath(); // command-line includes
addToMap(symbolMap, 0, path, include);
}
// macros
IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
for (int i = 0; i < macros.length; ++i) {
IASTPreprocessorMacroDefinition macro = macros[i];
IASTFileLocation sourceLoc = macro.getFileLocation();
if (sourceLoc != null) { // skip built-ins and command line macros
String path = sourceLoc.getFileName();
addToMap(symbolMap, 1, path, macro);
}
}
// names
ast.accept(new ASTVisitor() {
{
shouldVisitNames = true;
shouldVisitDeclarations = true;
}
public int visit(IASTName name) {
try {
IASTFileLocation nameLoc = name.getFileLocation();
if (nameLoc != null) {
addToMap(symbolMap, 2, nameLoc.getFileName(), name);
}
return PROCESS_CONTINUE;
} catch (Throwable e) {
CCorePlugin.log(e);
return ++fErrorCount > MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE;
}
}
});
for (Iterator iter = symbolMap.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled()) {
return;
}
String path= (String) entry.getKey();
String path= orderedPaths[i];
FileInfo info= codeReaderFactory.createFileInfo(path);
// file is requested or is not yet indexed.
if (info.isRequested() || info.fFile == null) {
// resolve the names
ArrayList names= ((ArrayList[]) entry.getValue())[2];
for (int i=0; i<names.size(); i++) {
((IASTName) names.get(i)).resolveBinding();
}
prepareIndexInsertion(path, symbolMap);
}
else {
if (fTrace) {
System.out.println("Indexer: skipping " + path); //$NON-NLS-1$
}
iter.remove();
orderedPaths[i]= null;
}
}
@ -186,29 +135,31 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
boolean isFirstAddition= true;
index.acquireWriteLock(1);
try {
for (Iterator iter = paths.iterator(); iter.hasNext();) {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled())
return;
String path = (String) iter.next();
FileInfo info= codeReaderFactory.createFileInfo(path);
if (info.isRequested()) {
info.setRequested(false);
String path = orderedPaths[i];
if (path != null) {
FileInfo info= codeReaderFactory.createFileInfo(path);
if (info.isRequested()) {
info.setRequested(false);
if (isFirstRequest)
isFirstRequest= false;
else
fTotalSourcesEstimate--;
}
if (fTrace) {
System.out.println("Indexer: adding " + path); //$NON-NLS-1$
}
info.fFile= addToIndex(index, path, (ArrayList[]) symbolMap.get(path));
if (isFirstRequest)
isFirstRequest= false;
else
fTotalSourcesEstimate--;
}
if (fTrace) {
System.out.println("Indexer: adding " + path); //$NON-NLS-1$
}
info.fFile= addToIndex(index, path, symbolMap);
if (isFirstAddition)
isFirstAddition= false;
else
fCompletedHeaders++;
if (isFirstAddition)
isFirstAddition= false;
else
fCompletedHeaders++;
}
}
} finally {
index.releaseWriteLock(1);
@ -216,14 +167,6 @@ abstract class PDOMFastIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
fCompletedSources++;
}
private void addToMap(HashMap map, int idx, String path, Object thing) {
List[] lists= (List[]) map.get(path);
if (lists == null) {
lists= new ArrayList[]{new ArrayList(), new ArrayList(), new ArrayList()};
map.put(path, lists);
}
lists[idx].add(thing);
}
protected void parseTUs(List sources, List headers, IProgressMonitor monitor) throws CoreException, InterruptedException {
// sources first

View file

@ -12,22 +12,15 @@
package org.eclipse.cdt.internal.core.pdom.indexer.full;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMIndexer;
import org.eclipse.cdt.core.dom.IPDOMIndexerTask;
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.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.core.index.IWritableIndex;
@ -137,74 +130,26 @@ abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
protected void addSymbols(IASTTranslationUnit ast, IProgressMonitor pm) throws InterruptedException, CoreException {
// Add in the includes
final LinkedHashMap symbolMap= new LinkedHashMap(); // makes bugs reproducible
prepareInMap(symbolMap, ast.getFilePath());
final LinkedHashMap symbolMap= new LinkedHashMap();
String[] orderedPaths= extractSymbols(ast, filePathsToParse.keySet(), symbolMap);
// includes
IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives();
for (int i = 0; i < includes.length; ++i) {
IASTPreprocessorIncludeStatement include = includes[i];
IASTFileLocation sourceLoc = include.getFileLocation();
String path= sourceLoc != null ? sourceLoc.getFileName() : ast.getFilePath(); // command-line includes
addToMap(symbolMap, 0, path, include);
path= include.getPath();
if (path != null) {
prepareInMap(symbolMap, include.getPath());
}
}
// macros
IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions();
for (int i = 0; i < macros.length; ++i) {
IASTPreprocessorMacroDefinition macro = macros[i];
IASTFileLocation sourceLoc = macro.getFileLocation();
if (sourceLoc != null) { // skip built-ins and command line macros
String path = sourceLoc.getFileName();
addToMap(symbolMap, 1, path, macro);
}
}
// names
ast.accept(new ASTVisitor() {
{
shouldVisitNames = true;
shouldVisitDeclarations = true;
}
public int visit(IASTName name) {
try {
IASTFileLocation nameLoc = name.getFileLocation();
if (nameLoc != null) {
addToMap(symbolMap, 2, nameLoc.getFileName(), name);
}
return PROCESS_CONTINUE;
} catch (Throwable e) {
CCorePlugin.log(e);
return ++fErrorCount > MAX_ERRORS ? PROCESS_ABORT : PROCESS_CONTINUE;
}
}
});
for (Iterator iter = symbolMap.values().iterator(); iter.hasNext();) {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled()) {
return;
}
// resolve the names
ArrayList names= ((ArrayList[]) iter.next())[2];
for (int i=0; i<names.size(); i++) {
((IASTName) names.get(i)).resolveBinding();
}
String path= orderedPaths[i];
prepareIndexInsertion(path, symbolMap);
}
boolean isFirstRequest= true;
boolean isFirstAddition= true;
index.acquireWriteLock(0);
try {
for (Iterator iter = symbolMap.entrySet().iterator(); iter.hasNext();) {
for (int i=0; i<orderedPaths.length; i++) {
if (pm.isCanceled())
return;
Map.Entry entry = (Map.Entry) iter.next();
String path= (String) entry.getKey();
String path = orderedPaths[i];
Boolean required= (Boolean) filePathsToParse.remove(path);
if (required != null) {
if (required.booleanValue()) {
@ -217,7 +162,7 @@ abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
if (fTrace)
System.out.println("Indexer: adding " + path); //$NON-NLS-1$
addToIndex(index, path, (ArrayList[]) entry.getValue());
addToIndex(index, path, symbolMap);
if (isFirstAddition)
isFirstAddition= false;
@ -230,20 +175,4 @@ abstract class PDOMFullIndexerJob extends PDOMIndexerTask implements IPDOMIndexe
}
fCompletedSources++;
}
private void prepareInMap(Map map, String path) {
if (filePathsToParse.get(path) != null) {
if (map.get(path) == null) {
Object lists= new ArrayList[]{new ArrayList(), new ArrayList(), new ArrayList()};
map.put(path, lists);
}
}
}
private void addToMap(HashMap map, int idx, String path, Object thing) {
List[] lists= (List[]) map.get(path);
if (lists != null) {
lists[idx].add(thing);
}
}
}