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:
parent
83d041b828
commit
f0f63b48ed
20 changed files with 553 additions and 240 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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()]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue