mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Implementation of an heuristics to resolve include files, bug 213562
This commit is contained in:
parent
ddd10d64c3
commit
a359eb6090
38 changed files with 1560 additions and 120 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
|
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -23,7 +23,7 @@ import org.eclipse.jface.text.Region;
|
||||||
|
|
||||||
public class PositionTrackerTests extends TestCase {
|
public class PositionTrackerTests extends TestCase {
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
return new TestSuite(PositionTrackerTests.class, "PositionTrackerTests");
|
return new TestSuite(PositionTrackerTests.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInitialFailures() {
|
public void testInitialFailures() {
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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.core.internal.tests;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IFolder;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||||
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
|
public class ResourceLookupTests extends TestCase {
|
||||||
|
public static Test suite() {
|
||||||
|
return new TestSuite(ResourceLookupTests.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IProject fProject;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() {
|
||||||
|
final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||||
|
fProject= root.getProject("reslookup");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception {
|
||||||
|
fProject.delete(true, new NullProgressMonitor());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IFolder createFolder(IProject project, String filename) throws CoreException {
|
||||||
|
IFolder folder= project.getFolder(filename);
|
||||||
|
folder.create(true, false, new NullProgressMonitor());
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IFile createFile(IProject project, String filename) throws CoreException {
|
||||||
|
IFile file= project.getFile(filename);
|
||||||
|
file.create(new InputStream() {
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
return -1;
|
||||||
|
}}, true, new NullProgressMonitor());
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNameLookup() throws CoreException {
|
||||||
|
IProject[] prjs= new IProject[]{fProject};
|
||||||
|
|
||||||
|
fProject.create(new NullProgressMonitor());
|
||||||
|
fProject.open(new NullProgressMonitor());
|
||||||
|
createFolder(fProject, "folder1");
|
||||||
|
createFolder(fProject, "folder2");
|
||||||
|
createFile(fProject, "abc.h");
|
||||||
|
createFile(fProject, "folder1/abc.h");
|
||||||
|
createFile(fProject, "folder2/abC.h");
|
||||||
|
|
||||||
|
IFile[] files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, false);
|
||||||
|
assertEquals(2, files.length);
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("bla/../abc.h"), prjs, false);
|
||||||
|
assertEquals(2, files.length);
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("../abc.h"), prjs, false);
|
||||||
|
assertEquals(2, files.length);
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("../../abc.h"), prjs, false);
|
||||||
|
assertEquals(2, files.length);
|
||||||
|
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(3, files.length);
|
||||||
|
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("folder1/abc.h"), prjs, false);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("folder1/abC.h"), prjs, false);
|
||||||
|
assertEquals(0, files.length);
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("fOlder1/abc.h"), prjs, false);
|
||||||
|
assertEquals(0, files.length);
|
||||||
|
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("folder1/abc.h"), prjs, true);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("folder1/abC.h"), prjs, true);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("fOlder1/abc.h"), prjs, true);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("bla/../abc.h"), prjs, true);
|
||||||
|
assertEquals(3, files.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testResourceDelta() throws CoreException {
|
||||||
|
IProject[] prjs= new IProject[]{fProject};
|
||||||
|
fProject.create(new NullProgressMonitor());
|
||||||
|
fProject.open(new NullProgressMonitor());
|
||||||
|
|
||||||
|
IFile[] files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(0, files.length);
|
||||||
|
|
||||||
|
IFolder f1= createFolder(fProject, "folder1");
|
||||||
|
createFolder(fProject, "folder2");
|
||||||
|
IFile f2= createFile(fProject, "abc.h");
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
|
||||||
|
createFile(fProject, "folder1/abc.h");
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(2, files.length);
|
||||||
|
|
||||||
|
createFile(fProject, "folder2/abC.h");
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(3, files.length);
|
||||||
|
|
||||||
|
f1.delete(true, new NullProgressMonitor());
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(2, files.length);
|
||||||
|
|
||||||
|
f2.delete(true, new NullProgressMonitor());
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeref() throws CoreException {
|
||||||
|
IProject[] prjs= new IProject[]{fProject};
|
||||||
|
|
||||||
|
fProject.create(new NullProgressMonitor());
|
||||||
|
fProject.open(new NullProgressMonitor());
|
||||||
|
createFolder(fProject, "folder1");
|
||||||
|
createFolder(fProject, "folder2");
|
||||||
|
createFile(fProject, "abc.h");
|
||||||
|
IFile[] files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
|
||||||
|
ResourceLookup.unrefNodeMap();
|
||||||
|
createFile(fProject, "folder1/abc.h");
|
||||||
|
createFile(fProject, "folder2/abC.h");
|
||||||
|
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(3, files.length);
|
||||||
|
|
||||||
|
ResourceLookup.unrefNodeMap();
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(3, files.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCollected() throws CoreException {
|
||||||
|
IProject[] prjs= new IProject[]{fProject};
|
||||||
|
|
||||||
|
fProject.create(new NullProgressMonitor());
|
||||||
|
fProject.open(new NullProgressMonitor());
|
||||||
|
createFolder(fProject, "folder1");
|
||||||
|
createFolder(fProject, "folder2");
|
||||||
|
createFile(fProject, "abc.h");
|
||||||
|
IFile[] files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
|
||||||
|
ResourceLookup.simulateNodeMapCollection();
|
||||||
|
createFile(fProject, "folder1/abc.h");
|
||||||
|
createFile(fProject, "folder2/abC.h");
|
||||||
|
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(3, files.length);
|
||||||
|
|
||||||
|
ResourceLookup.simulateNodeMapCollection();
|
||||||
|
files= ResourceLookup.findFilesByName(new Path("abc.h"), prjs, true);
|
||||||
|
assertEquals(3, files.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFindFilesByLocation() throws Exception {
|
||||||
|
IProject[] prjs= new IProject[]{fProject};
|
||||||
|
|
||||||
|
fProject.create(new NullProgressMonitor());
|
||||||
|
fProject.open(new NullProgressMonitor());
|
||||||
|
createFolder(fProject, "folder1");
|
||||||
|
createFolder(fProject, "folder2");
|
||||||
|
IFile file= createFile(fProject, "abc.h");
|
||||||
|
createFile(fProject, "folder1/abc.h");
|
||||||
|
createFile(fProject, "folder2/abC.h");
|
||||||
|
|
||||||
|
URI uri= file.getLocationURI();
|
||||||
|
IFile[] files= ResourceLookup.findFilesForLocation(uri, prjs);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
|
||||||
|
if (new File("a").equals(new File("A"))) {
|
||||||
|
URI upperCase= new URI(uri.getScheme(), uri.getSchemeSpecificPart().toUpperCase(), uri.getFragment());
|
||||||
|
files= ResourceLookup.findFilesForLocation(upperCase, prjs);
|
||||||
|
assertEquals(1, files.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ import junit.framework.TestSuite;
|
||||||
|
|
||||||
public class StringBuilderTest extends TestCase {
|
public class StringBuilderTest extends TestCase {
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
return new TestSuite(StringBuilderTest.class, "StringBuilderTest");
|
return new TestSuite(StringBuilderTest.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSafe() {
|
public void testSafe() {
|
||||||
|
|
|
@ -334,8 +334,8 @@ public class LocationMapTests extends BaseTestCase {
|
||||||
|
|
||||||
public void testIncludes() {
|
public void testIncludes() {
|
||||||
init(DIGITS);
|
init(DIGITS);
|
||||||
fLocationMap.encounterPoundInclude(0, 0, 0, 0, "n1".toCharArray(), null, true, false);
|
fLocationMap.encounterPoundInclude(0, 0, 0, 0, "n1".toCharArray(), null, true, false, false);
|
||||||
fLocationMap.encounterPoundInclude(0, 1, 3, 16, "n2".toCharArray(), "f2", false , true);
|
fLocationMap.encounterPoundInclude(0, 1, 3, 16, "n2".toCharArray(), "f2", false , true, false);
|
||||||
IASTPreprocessorIncludeStatement[] includes= fLocationMap.getIncludeDirectives();
|
IASTPreprocessorIncludeStatement[] includes= fLocationMap.getIncludeDirectives();
|
||||||
assertEquals(2, includes.length);
|
assertEquals(2, includes.length);
|
||||||
checkInclude(includes[0], "", "", "n1", "", true, false, FN, 0, 0, 1, 0, 0);
|
checkInclude(includes[0], "", "", "n1", "", true, false, FN, 0, 0, 1, 0, 0);
|
||||||
|
@ -495,11 +495,11 @@ public class LocationMapTests extends BaseTestCase {
|
||||||
assertEquals(FN, fLocationMap.getCurrentFilePath());
|
assertEquals(FN, fLocationMap.getCurrentFilePath());
|
||||||
fLocationMap.encounteredComment(0,2,true);
|
fLocationMap.encounteredComment(0,2,true);
|
||||||
// number: [6,15)[25,26)
|
// number: [6,15)[25,26)
|
||||||
ILocationCtx i1= fLocationMap.pushInclusion(0, 2, 4, 6, "b1b2b3b4b5".toCharArray(), "pre1", "pre1".toCharArray(), false);
|
ILocationCtx i1= fLocationMap.pushInclusion(0, 2, 4, 6, "b1b2b3b4b5".toCharArray(), "pre1", "pre1".toCharArray(), false, false);
|
||||||
assertEquals("pre1", fLocationMap.getCurrentFilePath());
|
assertEquals("pre1", fLocationMap.getCurrentFilePath());
|
||||||
fLocationMap.encounteredComment(2,4,true);
|
fLocationMap.encounteredComment(2,4,true);
|
||||||
// number: [15,25)
|
// number: [15,25)
|
||||||
ILocationCtx i2= fLocationMap.pushInclusion(6, 7, 8, 9, "c1c2c3c4c5".toCharArray(), "pre11", "pre11".toCharArray(), false);
|
ILocationCtx i2= fLocationMap.pushInclusion(6, 7, 8, 9, "c1c2c3c4c5".toCharArray(), "pre11", "pre11".toCharArray(), false, false);
|
||||||
assertEquals("pre11", fLocationMap.getCurrentFilePath());
|
assertEquals("pre11", fLocationMap.getCurrentFilePath());
|
||||||
fLocationMap.encounteredComment(2,6,true);
|
fLocationMap.encounteredComment(2,6,true);
|
||||||
fLocationMap.popContext(i2);
|
fLocationMap.popContext(i2);
|
||||||
|
@ -512,7 +512,7 @@ public class LocationMapTests extends BaseTestCase {
|
||||||
fLocationMap.popContext(pre2);
|
fLocationMap.popContext(pre2);
|
||||||
assertEquals(FN, fLocationMap.getCurrentFilePath());
|
assertEquals(FN, fLocationMap.getCurrentFilePath());
|
||||||
// number [36, 46)
|
// number [36, 46)
|
||||||
ILocationCtx i3= fLocationMap.pushInclusion(0, 2, 4, 6, "d1d2d3d4d5".toCharArray(), "pre2", "pre2".toCharArray(), false);
|
ILocationCtx i3= fLocationMap.pushInclusion(0, 2, 4, 6, "d1d2d3d4d5".toCharArray(), "pre2", "pre2".toCharArray(), false, false);
|
||||||
assertEquals("pre2", fLocationMap.getCurrentFilePath());
|
assertEquals("pre2", fLocationMap.getCurrentFilePath());
|
||||||
fLocationMap.encounteredComment(0,2,true);
|
fLocationMap.encounteredComment(0,2,true);
|
||||||
fLocationMap.popContext(i3);
|
fLocationMap.popContext(i3);
|
||||||
|
|
|
@ -1350,4 +1350,53 @@ public class IndexBugsTests extends BaseTestCase {
|
||||||
fIndex.releaseReadLock();
|
fIndex.releaseReadLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #include <header.h>
|
||||||
|
// #define _CONCAT(x,y) x##y
|
||||||
|
// #define CONCAT(x,y) _CONCAT(x,y)
|
||||||
|
public void testIncludeHeuristics_Bug213562() throws Exception {
|
||||||
|
String contents= getContentsForTest(1)[0];
|
||||||
|
final IIndexManager indexManager = CCorePlugin.getIndexManager();
|
||||||
|
TestSourceReader.createFile(fCProject.getProject(), "f1/g/header.h", "#define ID one\n");
|
||||||
|
TestSourceReader.createFile(fCProject.getProject(), "f2/header.h", "#define ID two\n");
|
||||||
|
TestSourceReader.createFile(fCProject.getProject(), "f1/g/h/header.h", "#define ID three\n");
|
||||||
|
TestSourceReader.createFile(fCProject.getProject(), "f1/g/source.cpp", contents + "int CONCAT(one, ID);\n");
|
||||||
|
TestSourceReader.createFile(fCProject.getProject(), "f2/g/source.cpp", contents + "int CONCAT(two, ID);\n");
|
||||||
|
TestSourceReader.createFile(fCProject.getProject(), "f1/g/h/source.cpp", contents + "int CONCAT(three, ID);\n");
|
||||||
|
indexManager.reindex(fCProject);
|
||||||
|
waitForIndexer();
|
||||||
|
fIndex.acquireReadLock();
|
||||||
|
try {
|
||||||
|
IIndexBinding[] bindings= fIndex.findBindings("oneone".toCharArray(), IndexFilter.ALL_DECLARED, new NullProgressMonitor());
|
||||||
|
assertEquals(1, bindings.length);
|
||||||
|
bindings= fIndex.findBindings("twotwo".toCharArray(), IndexFilter.ALL_DECLARED, new NullProgressMonitor());
|
||||||
|
assertEquals(1, bindings.length);
|
||||||
|
bindings= fIndex.findBindings("threethree".toCharArray(), IndexFilter.ALL_DECLARED, new NullProgressMonitor());
|
||||||
|
assertEquals(1, bindings.length);
|
||||||
|
} finally {
|
||||||
|
fIndex.releaseReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIncludeHeuristicsFlag_Bug213562() throws Exception {
|
||||||
|
final IIndexManager indexManager = CCorePlugin.getIndexManager();
|
||||||
|
TestSourceReader.createFile(fCProject.getProject(), "f1/header.h", "");
|
||||||
|
IFile f1= TestSourceReader.createFile(fCProject.getProject(), "source1.cpp", "#include \"header.h\"\n");
|
||||||
|
IFile f2= TestSourceReader.createFile(fCProject.getProject(), "source2.cpp", "#include \"f1/header.h\"\n");
|
||||||
|
indexManager.reindex(fCProject);
|
||||||
|
waitForIndexer();
|
||||||
|
fIndex.acquireReadLock();
|
||||||
|
try {
|
||||||
|
IIndexFile f= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f1));
|
||||||
|
IIndexInclude i= f.getIncludes()[0];
|
||||||
|
assertTrue(i.isResolvedByHeuristics());
|
||||||
|
|
||||||
|
f= fIndex.getFile(ILinkage.CPP_LINKAGE_ID, IndexLocationFactory.getWorkspaceIFL(f2));
|
||||||
|
i= f.getIncludes()[0];
|
||||||
|
assertFalse(i.isResolvedByHeuristics());
|
||||||
|
} finally {
|
||||||
|
fIndex.releaseReadLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -18,6 +18,7 @@ import junit.framework.TestSuite;
|
||||||
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorTests;
|
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorTests;
|
||||||
import org.eclipse.cdt.core.internal.errorparsers.tests.ErrorParserTests;
|
import org.eclipse.cdt.core.internal.errorparsers.tests.ErrorParserTests;
|
||||||
import org.eclipse.cdt.core.internal.tests.PositionTrackerTests;
|
import org.eclipse.cdt.core.internal.tests.PositionTrackerTests;
|
||||||
|
import org.eclipse.cdt.core.internal.tests.ResourceLookupTests;
|
||||||
import org.eclipse.cdt.core.internal.tests.StringBuilderTest;
|
import org.eclipse.cdt.core.internal.tests.StringBuilderTest;
|
||||||
import org.eclipse.cdt.core.language.AllLanguageTests;
|
import org.eclipse.cdt.core.language.AllLanguageTests;
|
||||||
import org.eclipse.cdt.core.model.tests.AllCoreTests;
|
import org.eclipse.cdt.core.model.tests.AllCoreTests;
|
||||||
|
@ -61,6 +62,7 @@ public class AutomatedIntegrationSuite extends TestSuite {
|
||||||
suite.addTest(ElementDeltaTests.suite());
|
suite.addTest(ElementDeltaTests.suite());
|
||||||
suite.addTest(WorkingCopyTests.suite());
|
suite.addTest(WorkingCopyTests.suite());
|
||||||
suite.addTest(PositionTrackerTests.suite());
|
suite.addTest(PositionTrackerTests.suite());
|
||||||
|
suite.addTest(ResourceLookupTests.suite());
|
||||||
suite.addTest(StringBuilderTest.suite());
|
suite.addTest(StringBuilderTest.suite());
|
||||||
suite.addTest(AllLanguageTests.suite());
|
suite.addTest(AllLanguageTests.suite());
|
||||||
suite.addTest(RewriteTests.suite());
|
suite.addTest(RewriteTests.suite());
|
||||||
|
|
|
@ -71,6 +71,7 @@ Export-Package: org.eclipse.cdt.core,
|
||||||
org.eclipse.cdt.internal.core.pdom.dom.cpp;x-internal:=true,
|
org.eclipse.cdt.internal.core.pdom.dom.cpp;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.core.pdom.export;x-internal:=true,
|
org.eclipse.cdt.internal.core.pdom.export;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.core.pdom.indexer;x-friends:="org.eclipse.cdt.ui",
|
org.eclipse.cdt.internal.core.pdom.indexer;x-friends:="org.eclipse.cdt.ui",
|
||||||
|
org.eclipse.cdt.internal.core.resources;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.core.util;x-internal:=true,
|
org.eclipse.cdt.internal.core.util;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.errorparsers;x-internal:=true,
|
org.eclipse.cdt.internal.errorparsers;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.formatter;x-internal:=true,
|
org.eclipse.cdt.internal.formatter;x-internal:=true,
|
||||||
|
|
|
@ -70,6 +70,7 @@ import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory;
|
||||||
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
||||||
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
|
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
|
||||||
import org.eclipse.cdt.internal.core.parser.ParserLogService;
|
import org.eclipse.cdt.internal.core.parser.ParserLogService;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerIncludeResolutionHeuristics;
|
||||||
import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter;
|
import org.eclipse.cdt.internal.core.pdom.indexer.ProjectIndexerInputAdapter;
|
||||||
import org.eclipse.cdt.internal.core.util.ICanceler;
|
import org.eclipse.cdt.internal.core.util.ICanceler;
|
||||||
import org.eclipse.cdt.internal.core.util.MementoTokenizer;
|
import org.eclipse.cdt.internal.core.util.MementoTokenizer;
|
||||||
|
@ -835,15 +836,20 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private ICodeReaderFactory getCodeReaderFactory(int style, IIndex index, int linkageID) {
|
private ICodeReaderFactory getCodeReaderFactory(int style, IIndex index, int linkageID) {
|
||||||
|
final ICProject cprj= getCProject();
|
||||||
|
final ProjectIndexerInputAdapter pathResolver = new ProjectIndexerInputAdapter(cprj);
|
||||||
|
final ProjectIndexerIncludeResolutionHeuristics heuristics = new ProjectIndexerIncludeResolutionHeuristics(cprj.getProject(), pathResolver);
|
||||||
ICodeReaderFactory codeReaderFactory;
|
ICodeReaderFactory codeReaderFactory;
|
||||||
if ((style & AST_SKIP_NONINDEXED_HEADERS) != 0) {
|
if ((style & AST_SKIP_NONINDEXED_HEADERS) != 0) {
|
||||||
codeReaderFactory= NullCodeReaderFactory.getInstance();
|
codeReaderFactory= NullCodeReaderFactory.getInstance();
|
||||||
} else {
|
} else {
|
||||||
codeReaderFactory= SavedCodeReaderFactory.getInstance();
|
codeReaderFactory= SavedCodeReaderFactory.createInstance(heuristics);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) {
|
if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) {
|
||||||
IndexBasedCodeReaderFactory ibcf= new IndexBasedCodeReaderFactory(index, new ProjectIndexerInputAdapter(getCProject()), linkageID, codeReaderFactory);
|
IndexBasedCodeReaderFactory ibcf= new IndexBasedCodeReaderFactory(index,
|
||||||
|
heuristics,
|
||||||
|
pathResolver, linkageID, codeReaderFactory);
|
||||||
if ((style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
|
if ((style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
|
||||||
ibcf.setSupportFillGapFromContextToHeader(true);
|
ibcf.setSupportFillGapFromContextToHeader(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* IBM - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast;
|
package org.eclipse.cdt.core.dom.ast;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface represent a preprocessor #include statement.
|
* This interface represent a preprocessor #include statement.
|
||||||
*
|
*
|
||||||
* @author jcamelon
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
public interface IASTPreprocessorIncludeStatement extends
|
public interface IASTPreprocessorIncludeStatement extends
|
||||||
IASTPreprocessorStatement {
|
IASTPreprocessorStatement {
|
||||||
|
@ -57,4 +57,10 @@ public interface IASTPreprocessorIncludeStatement extends
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public boolean isResolved();
|
public boolean isResolved();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the inclusion was resolved using a heuristics.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public boolean isResolvedByHeuristics();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
|
* Copyright (c) 2006, 2008 Wind River Systems, Inc. and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -9,23 +9,14 @@
|
||||||
* Markus Schorn - initial API and implementation
|
* Markus Schorn - initial API and implementation
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.core.index;
|
package org.eclipse.cdt.core.index;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for an include directive stored in the index.
|
* Interface for an include directive stored in the index.
|
||||||
* <p>
|
|
||||||
* This interface is not intended to be implemented by clients.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* <strong>EXPERIMENTAL</strong>. This class or interface has been added as
|
|
||||||
* part of a work in progress. There is no guarantee that this API will work or
|
|
||||||
* that it will remain the same. Please do not use this API without consulting
|
|
||||||
* with the CDT team.
|
|
||||||
* </p>
|
|
||||||
*
|
*
|
||||||
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public interface IIndexInclude {
|
public interface IIndexInclude {
|
||||||
|
@ -106,4 +97,11 @@ public interface IIndexInclude {
|
||||||
* @throws CoreException
|
* @throws CoreException
|
||||||
*/
|
*/
|
||||||
boolean isResolved() throws CoreException;
|
boolean isResolved() throws CoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests whether this include has been resolved using a heuristics rather than relying on
|
||||||
|
* the include search path.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
boolean isResolvedByHeuristics() throws CoreException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ import org.eclipse.cdt.core.index.IIndexMacro;
|
||||||
import org.eclipse.cdt.core.parser.CodeReader;
|
import org.eclipse.cdt.core.parser.CodeReader;
|
||||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.AbstractCodeReaderFactory;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.IIndexBasedCodeReaderFactory;
|
import org.eclipse.cdt.internal.core.parser.scanner.IIndexBasedCodeReaderFactory;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent;
|
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind;
|
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind;
|
||||||
|
@ -46,7 +48,7 @@ import org.eclipse.core.runtime.CoreException;
|
||||||
* Code reader factory, that fakes code readers for header files already stored in the
|
* Code reader factory, that fakes code readers for header files already stored in the
|
||||||
* index.
|
* index.
|
||||||
*/
|
*/
|
||||||
public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory {
|
public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory implements IIndexBasedCodeReaderFactory {
|
||||||
private static final class NeedToParseException extends Exception {}
|
private static final class NeedToParseException extends Exception {}
|
||||||
private static final String GAP = "__gap__"; //$NON-NLS-1$
|
private static final String GAP = "__gap__"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
@ -59,13 +61,15 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
|
||||||
private final AbstractIndexerTask fRelatedIndexerTask;
|
private final AbstractIndexerTask fRelatedIndexerTask;
|
||||||
private boolean fSupportFillGapFromContextToHeader= false;
|
private boolean fSupportFillGapFromContextToHeader= false;
|
||||||
|
|
||||||
public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage,
|
public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics,
|
||||||
ICodeReaderFactory fallbackFactory) {
|
ASTFilePathResolver pathResolver, int linkage, ICodeReaderFactory fallbackFactory) {
|
||||||
this(index, pathResolver, linkage, fallbackFactory, null);
|
this(index, heuristics, pathResolver, linkage, fallbackFactory, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage,
|
public IndexBasedCodeReaderFactory(IIndex index, IIncludeFileResolutionHeuristics heuristics,
|
||||||
|
ASTFilePathResolver pathResolver, int linkage,
|
||||||
ICodeReaderFactory fallbackFactory, AbstractIndexerTask relatedIndexerTask) {
|
ICodeReaderFactory fallbackFactory, AbstractIndexerTask relatedIndexerTask) {
|
||||||
|
super(heuristics);
|
||||||
fIndex= index;
|
fIndex= index;
|
||||||
fFallBackFactory= fallbackFactory;
|
fFallBackFactory= fallbackFactory;
|
||||||
fPathResolver= pathResolver;
|
fPathResolver= pathResolver;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2007 QNX Software Systems and others.
|
* Copyright (c) 2006, 2008 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.indexer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A task for index updates.
|
* A task for index updates.
|
||||||
|
@ -38,4 +39,9 @@ public class StandaloneFastIndexerTask extends StandaloneIndexerTask {
|
||||||
protected ICodeReaderFactory createReaderFactory() {
|
protected ICodeReaderFactory createReaderFactory() {
|
||||||
return new StandaloneIndexerFallbackReaderFactory();
|
return new StandaloneIndexerFallbackReaderFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IIncludeFileResolutionHeuristics createIncludeHeuristics() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2007 QNX Software Systems and others.
|
* Copyright (c) 2006, 2008 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.indexer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A task for index updates.
|
* A task for index updates.
|
||||||
|
@ -39,4 +40,9 @@ public class StandaloneFullIndexerTask extends StandaloneIndexerTask {
|
||||||
protected ICodeReaderFactory createReaderFactory() {
|
protected ICodeReaderFactory createReaderFactory() {
|
||||||
return ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory();
|
return ((StandaloneFullIndexer)fIndexer).getCodeReaderFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IIncludeFileResolutionHeuristics createIncludeHeuristics() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,16 +212,18 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
||||||
private final boolean fIsActive;
|
private final boolean fIsActive;
|
||||||
private final boolean fIsResolved;
|
private final boolean fIsResolved;
|
||||||
private final boolean fIsSystemInclude;
|
private final boolean fIsSystemInclude;
|
||||||
|
private final boolean fFoundByHeuristics;
|
||||||
|
|
||||||
public ASTInclusionStatement(IASTTranslationUnit parent,
|
public ASTInclusionStatement(IASTTranslationUnit parent,
|
||||||
int startNumber, int nameStartNumber, int nameEndNumber, int endNumber,
|
int startNumber, int nameStartNumber, int nameEndNumber, int endNumber,
|
||||||
char[] headerName, String filePath, boolean userInclude, boolean active) {
|
char[] headerName, String filePath, boolean userInclude, boolean active, boolean heuristic) {
|
||||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||||
fName= new ASTPreprocessorName(this, IASTPreprocessorIncludeStatement.INCLUDE_NAME, nameStartNumber, nameEndNumber, headerName, null);
|
fName= new ASTPreprocessorName(this, IASTPreprocessorIncludeStatement.INCLUDE_NAME, nameStartNumber, nameEndNumber, headerName, null);
|
||||||
fPath= filePath == null ? "" : filePath; //$NON-NLS-1$
|
fPath= filePath == null ? "" : filePath; //$NON-NLS-1$
|
||||||
fIsActive= active;
|
fIsActive= active;
|
||||||
fIsResolved= filePath != null;
|
fIsResolved= filePath != null;
|
||||||
fIsSystemInclude= !userInclude;
|
fIsSystemInclude= !userInclude;
|
||||||
|
fFoundByHeuristics= heuristic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTName getName() {
|
public IASTName getName() {
|
||||||
|
@ -249,6 +251,10 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
|
||||||
super.findNode(nodeSpec);
|
super.findNode(nodeSpec);
|
||||||
nodeSpec.visit(fName);
|
nodeSpec.visit(fName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isResolvedByHeuristics() {
|
||||||
|
return fFoundByHeuristics;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {
|
class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
import org.eclipse.cdt.core.parser.util.CharArrayMap;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
|
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind;
|
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
@ -87,21 +88,29 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
private static final DynamicMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
|
private static final DynamicMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
|
||||||
|
|
||||||
private interface IIncludeFileTester<T> {
|
private interface IIncludeFileTester<T> {
|
||||||
T checkFile(String path, String fileName);
|
T checkFile(String path, String fileName, boolean isHeuristicMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() {
|
final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() {
|
||||||
public IncludeFileContent checkFile(String path, String fileName) {
|
public IncludeFileContent checkFile(String path, String fileName, boolean isHeuristicMatch) {
|
||||||
String finalPath = ScannerUtility.createReconciledPath(path, fileName);
|
final String finalPath = ScannerUtility.createReconciledPath(path, fileName);
|
||||||
return fCodeReaderFactory.getContentForInclusion(finalPath);
|
final IncludeFileContent fc= fCodeReaderFactory.getContentForInclusion(finalPath);
|
||||||
|
if (fc != null) {
|
||||||
|
fc.setFoundByHeuristics(isHeuristicMatch);
|
||||||
|
}
|
||||||
|
return fc;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final private IIncludeFileTester<String> createPathTester= new IIncludeFileTester<String>() {
|
private static class IncludeResolution {String fLocation; boolean fHeuristic;}
|
||||||
public String checkFile(String path, String fileName) {
|
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
||||||
|
public IncludeResolution checkFile(String path, String fileName, boolean isHeuristicMatch) {
|
||||||
String finalPath= ScannerUtility.createReconciledPath(path, fileName);
|
String finalPath= ScannerUtility.createReconciledPath(path, fileName);
|
||||||
if (fCodeReaderFactory.getInclusionExists(finalPath)) {
|
if (fCodeReaderFactory.getInclusionExists(finalPath)) {
|
||||||
return finalPath;
|
IncludeResolution res= new IncludeResolution();
|
||||||
|
res.fHeuristic= isHeuristicMatch;
|
||||||
|
res.fLocation= finalPath;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +118,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
final private IParserLogService fLog;
|
final private IParserLogService fLog;
|
||||||
final private IIndexBasedCodeReaderFactory fCodeReaderFactory;
|
final private IIndexBasedCodeReaderFactory fCodeReaderFactory;
|
||||||
|
|
||||||
|
private IIncludeFileResolutionHeuristics fIncludeFileResolutionHeuristics;
|
||||||
private final ExpressionEvaluator fExpressionEvaluator;
|
private final ExpressionEvaluator fExpressionEvaluator;
|
||||||
private final MacroDefinitionParser fMacroDefinitionParser;
|
private final MacroDefinitionParser fMacroDefinitionParser;
|
||||||
private final MacroExpander fMacroExpander;
|
private final MacroExpander fMacroExpander;
|
||||||
|
@ -142,7 +153,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
private Token fPrefetchedTokens;
|
private Token fPrefetchedTokens;
|
||||||
private Token fLastToken;
|
private Token fLastToken;
|
||||||
|
|
||||||
|
|
||||||
public CPreprocessor(CodeReader reader, IScannerInfo info, ParserLanguage language, IParserLogService log,
|
public CPreprocessor(CodeReader reader, IScannerInfo info, ParserLanguage language, IParserLogService log,
|
||||||
IScannerExtensionConfiguration configuration, ICodeReaderFactory readerFactory) {
|
IScannerExtensionConfiguration configuration, ICodeReaderFactory readerFactory) {
|
||||||
fLog = log;
|
fLog = log;
|
||||||
|
@ -162,6 +172,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fMacroDefinitionParser= new MacroDefinitionParser();
|
fMacroDefinitionParser= new MacroDefinitionParser();
|
||||||
fMacroExpander= new MacroExpander(this, fMacroDictionary, fLocationMap, fLexOptions);
|
fMacroExpander= new MacroExpander(this, fMacroDictionary, fLocationMap, fLexOptions);
|
||||||
fCodeReaderFactory= wrapReaderFactory(readerFactory);
|
fCodeReaderFactory= wrapReaderFactory(readerFactory);
|
||||||
|
if (readerFactory instanceof IAdaptable) {
|
||||||
|
fIncludeFileResolutionHeuristics= (IIncludeFileResolutionHeuristics) ((IAdaptable) readerFactory).getAdapter(IIncludeFileResolutionHeuristics.class);
|
||||||
|
}
|
||||||
|
|
||||||
setupMacroDictionary(configuration, info, language);
|
setupMacroDictionary(configuration, info, language);
|
||||||
|
|
||||||
|
@ -746,43 +759,50 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IncludeFileContent findInclusion(final String filename, final boolean quoteInclude,
|
|
||||||
final boolean includeNext, final File currentDir) {
|
|
||||||
return findInclusion(filename, quoteInclude, includeNext, currentDir, createCodeReaderTester);
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> T findInclusion(final String filename, final boolean quoteInclude,
|
private <T> T findInclusion(final String filename, final boolean quoteInclude,
|
||||||
final boolean includeNext, final File currentDirectory, final IIncludeFileTester<T> tester) {
|
final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) {
|
||||||
T reader = null;
|
T reader = null;
|
||||||
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
||||||
if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$
|
if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$
|
||||||
return tester.checkFile( EMPTY_STRING, filename );
|
return tester.checkFile(EMPTY_STRING, filename, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentDirectory != null && quoteInclude && !includeNext) {
|
if (currentFile != null && quoteInclude && !includeNext) {
|
||||||
// Check to see if we find a match in the current directory
|
// Check to see if we find a match in the current directory
|
||||||
String absolutePath = currentDirectory.getAbsolutePath();
|
final File currentDir= new File(currentFile).getParentFile();
|
||||||
reader = tester.checkFile(absolutePath, filename);
|
if (currentDir != null) {
|
||||||
if (reader != null) {
|
String absolutePath = currentDir.getAbsolutePath();
|
||||||
return reader;
|
reader = tester.checkFile(absolutePath, filename, false);
|
||||||
}
|
if (reader != null) {
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're not include_next, then we are looking for the first occurrence of
|
// if we're not include_next, then we are looking for the first occurrence of
|
||||||
// the file, otherwise, we ignore all the paths before the current directory
|
// the file, otherwise, we ignore all the paths before the current directory
|
||||||
final String[] isp= quoteInclude ? fQuoteIncludePaths : fIncludePaths;
|
final String[] isp= quoteInclude ? fQuoteIncludePaths : fIncludePaths;
|
||||||
if (isp != null ) {
|
if (isp != null) {
|
||||||
int i=0;
|
int i=0;
|
||||||
if (includeNext && currentDirectory != null) {
|
if (includeNext && currentFile != null) {
|
||||||
i= findIncludePos(isp, currentDirectory) + 1;
|
final File currentDir= new File(currentFile).getParentFile();
|
||||||
|
if (currentDir != null) {
|
||||||
|
i= findIncludePos(isp, currentDir) + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (; i < isp.length; ++i) {
|
for (; i < isp.length; ++i) {
|
||||||
reader= tester.checkFile(isp[i], filename);
|
reader= tester.checkFile(isp[i], filename, false);
|
||||||
if (reader != null) {
|
if (reader != null) {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fIncludeFileResolutionHeuristics != null) {
|
||||||
|
String location= fIncludeFileResolutionHeuristics.findInclusion(filename, currentFile);
|
||||||
|
if (location != null) {
|
||||||
|
return tester.checkFile(null, location, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1027,20 +1047,21 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
String path= null;
|
String path= null;
|
||||||
boolean reported= false;
|
boolean reported= false;
|
||||||
|
boolean isHeuristic= false;
|
||||||
|
|
||||||
if (!active) {
|
if (!active) {
|
||||||
// test if the include is inactive just because it was included before (bug 167100)
|
// test if the include is inactive just because it was included before (bug 167100)
|
||||||
final File currentDir= userInclude || include_next ? new File(String.valueOf(getCurrentFilename())).getParentFile() : null;
|
final IncludeResolution resolved= findInclusion(new String(headerName), userInclude, include_next, getCurrentFilename(), createPathTester);
|
||||||
final String resolved= findInclusion(new String(headerName), userInclude, include_next, currentDir, createPathTester);
|
if (resolved != null && fCodeReaderFactory.hasFileBeenIncludedInCurrentTranslationUnit(resolved.fLocation)) {
|
||||||
if (resolved != null && fCodeReaderFactory.hasFileBeenIncludedInCurrentTranslationUnit(resolved)) {
|
path= resolved.fLocation;
|
||||||
path= resolved;
|
isHeuristic= resolved.fHeuristic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final File currentDir= userInclude || include_next ? new File(String.valueOf(getCurrentFilename())).getParentFile() : null;
|
final IncludeFileContent fi= findInclusion(new String(headerName), userInclude, include_next, getCurrentFilename(), createCodeReaderTester);
|
||||||
final IncludeFileContent fi= findInclusion(new String(headerName), userInclude, include_next, currentDir);
|
|
||||||
if (fi != null) {
|
if (fi != null) {
|
||||||
path= fi.getFileLocation();
|
path= fi.getFileLocation();
|
||||||
|
isHeuristic= fi.isFoundByHeuristics();
|
||||||
switch(fi.getKind()) {
|
switch(fi.getKind()) {
|
||||||
case FOUND_IN_INDEX:
|
case FOUND_IN_INDEX:
|
||||||
processInclusionFromIndex(poundOffset, path, fi);
|
processInclusionFromIndex(poundOffset, path, fi);
|
||||||
|
@ -1050,7 +1071,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
if (reader != null && !isCircularInclusion(path)) {
|
if (reader != null && !isCircularInclusion(path)) {
|
||||||
reported= true;
|
reported= true;
|
||||||
fAllIncludedFiles.add(path);
|
fAllIncludedFiles.add(path);
|
||||||
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, reader.buffer, path, headerName, userInclude);
|
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, reader.buffer, path, headerName, userInclude, isHeuristic);
|
||||||
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer, fLexOptions, this, this));
|
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer, fLexOptions, this, this));
|
||||||
fCurrentContext= fctx;
|
fCurrentContext= fctx;
|
||||||
}
|
}
|
||||||
|
@ -1074,7 +1095,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!reported) {
|
if (!reported) {
|
||||||
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, headerName, path, userInclude, active);
|
fLocationMap.encounterPoundInclude(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, headerName, path, userInclude, active, isHeuristic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class IncludeFileContent {
|
||||||
private final List<IIndexMacro> fMacroDefinitions;
|
private final List<IIndexMacro> fMacroDefinitions;
|
||||||
private final List<ICPPUsingDirective> fUsingDirectives;
|
private final List<ICPPUsingDirective> fUsingDirectives;
|
||||||
private final String fFileLocation;
|
private final String fFileLocation;
|
||||||
|
private boolean fHeuristic;
|
||||||
private List<IIndexFile> fFiles;
|
private List<IIndexFile> fFiles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,4 +145,15 @@ public class IncludeFileContent {
|
||||||
public List<IIndexFile> getFilesIncluded() {
|
public List<IIndexFile> getFilesIncluded() {
|
||||||
return fFiles;
|
return fFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this inclusion was found by a heuristics.
|
||||||
|
*/
|
||||||
|
public boolean isFoundByHeuristics() {
|
||||||
|
return fHeuristic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoundByHeuristics(boolean val) {
|
||||||
|
fHeuristic= val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,14 +116,14 @@ public class LocationMap implements ILocationResolver {
|
||||||
* @param userInclude <code>true</code> when specified with double-quotes.
|
* @param userInclude <code>true</code> when specified with double-quotes.
|
||||||
*/
|
*/
|
||||||
public ILocationCtx pushInclusion(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
public ILocationCtx pushInclusion(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||||
char[] buffer, String filename, char[] name, boolean userInclude) {
|
char[] buffer, String filename, char[] name, boolean userInclude, boolean heuristic) {
|
||||||
assert fCurrentContext instanceof LocationCtxContainer;
|
assert fCurrentContext instanceof LocationCtxContainer;
|
||||||
int startNumber= getSequenceNumberForOffset(startOffset);
|
int startNumber= getSequenceNumberForOffset(startOffset);
|
||||||
int nameNumber= getSequenceNumberForOffset(nameOffset);
|
int nameNumber= getSequenceNumberForOffset(nameOffset);
|
||||||
int nameEndNumber= getSequenceNumberForOffset(nameEndOffset);
|
int nameEndNumber= getSequenceNumberForOffset(nameEndOffset);
|
||||||
int endNumber= getSequenceNumberForOffset(endOffset);
|
int endNumber= getSequenceNumberForOffset(endOffset);
|
||||||
final ASTInclusionStatement inclusionStatement=
|
final ASTInclusionStatement inclusionStatement=
|
||||||
new ASTInclusionStatement(fTranslationUnit, startNumber, nameNumber, nameEndNumber, endNumber, name, filename, userInclude, true);
|
new ASTInclusionStatement(fTranslationUnit, startNumber, nameNumber, nameEndNumber, endNumber, name, filename, userInclude, true, heuristic);
|
||||||
fDirectives.add(inclusionStatement);
|
fDirectives.add(inclusionStatement);
|
||||||
fCurrentContext= new LocationCtxFile((LocationCtxContainer) fCurrentContext, filename, buffer, startOffset, endOffset, endNumber, inclusionStatement);
|
fCurrentContext= new LocationCtxFile((LocationCtxContainer) fCurrentContext, filename, buffer, startOffset, endOffset, endNumber, inclusionStatement);
|
||||||
fLastChildInsertionOffset= 0;
|
fLastChildInsertionOffset= 0;
|
||||||
|
@ -218,12 +218,12 @@ public class LocationMap implements ILocationResolver {
|
||||||
* @param active <code>true</code> when include appears in active code.
|
* @param active <code>true</code> when include appears in active code.
|
||||||
*/
|
*/
|
||||||
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
public void encounterPoundInclude(int startOffset, int nameOffset, int nameEndOffset, int endOffset,
|
||||||
char[] name, String filename, boolean userInclude, boolean active) {
|
char[] name, String filename, boolean userInclude, boolean active, boolean heuristic) {
|
||||||
startOffset= getSequenceNumberForOffset(startOffset);
|
startOffset= getSequenceNumberForOffset(startOffset);
|
||||||
nameOffset= getSequenceNumberForOffset(nameOffset);
|
nameOffset= getSequenceNumberForOffset(nameOffset);
|
||||||
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
nameEndOffset= getSequenceNumberForOffset(nameEndOffset);
|
||||||
endOffset= getSequenceNumberForOffset(endOffset);
|
endOffset= getSequenceNumberForOffset(endOffset);
|
||||||
fDirectives.add(new ASTInclusionStatement(fTranslationUnit, startOffset, nameOffset, nameEndOffset, endOffset, name, filename, userInclude, active));
|
fDirectives.add(new ASTInclusionStatement(fTranslationUnit, startOffset, nameOffset, nameEndOffset, endOffset, name, filename, userInclude, active, heuristic));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encounteredComment(int offset, int endOffset, boolean isBlockComment) {
|
public void encounteredComment(int offset, int endOffset, boolean isBlockComment) {
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.eclipse.cdt.core.parser.IParserLogService;
|
||||||
import org.eclipse.cdt.core.parser.IScannerInfo;
|
import org.eclipse.cdt.core.parser.IScannerInfo;
|
||||||
import org.eclipse.cdt.core.parser.ParserUtil;
|
import org.eclipse.cdt.core.parser.ParserUtil;
|
||||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
|
||||||
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
import org.eclipse.cdt.internal.core.index.IWritableIndex;
|
||||||
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
|
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
|
||||||
|
@ -134,6 +135,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IWritableIndex createIndex();
|
protected abstract IWritableIndex createIndex();
|
||||||
|
protected abstract IIncludeFileResolutionHeuristics createIncludeHeuristics();
|
||||||
protected abstract ICodeReaderFactory createReaderFactory();
|
protected abstract ICodeReaderFactory createReaderFactory();
|
||||||
protected abstract AbstractLanguage[] getLanguages(String fileName);
|
protected abstract AbstractLanguage[] getLanguages(String fileName);
|
||||||
|
|
||||||
|
@ -178,7 +180,7 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
|
||||||
IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException {
|
IScannerInfo scanInfo, int options, IProgressMonitor pm) throws CoreException {
|
||||||
if (fCodeReaderFactory == null) {
|
if (fCodeReaderFactory == null) {
|
||||||
if (fIsFastIndexer) {
|
if (fIsFastIndexer) {
|
||||||
fCodeReaderFactory= new IndexBasedCodeReaderFactory(fIndex, fResolver, language.getLinkageID(), createReaderFactory(), this);
|
fCodeReaderFactory= new IndexBasedCodeReaderFactory(fIndex, createIncludeHeuristics(), fResolver, language.getLinkageID(), createReaderFactory(), this);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fCodeReaderFactory= createReaderFactory();
|
fCodeReaderFactory= createReaderFactory();
|
||||||
|
|
|
@ -89,6 +89,10 @@ abstract public class PDOMWriter {
|
||||||
fResolver= resolver;
|
fResolver= resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected IndexerInputAdapter getInputAdapter() {
|
||||||
|
return fResolver;
|
||||||
|
}
|
||||||
|
|
||||||
public void setShowActivity(boolean val) {
|
public void setShowActivity(boolean val) {
|
||||||
fShowActivity= val;
|
fShowActivity= val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ public class PDOMInclude implements IIndexFragmentInclude {
|
||||||
private static final int FLAG_SYSTEM_INCLUDE = 1;
|
private static final int FLAG_SYSTEM_INCLUDE = 1;
|
||||||
private static final int FLAG_INACTIVE_INCLUDE = 2;
|
private static final int FLAG_INACTIVE_INCLUDE = 2;
|
||||||
private static final int FLAG_UNRESOLVED_INCLUDE = 4;
|
private static final int FLAG_UNRESOLVED_INCLUDE = 4;
|
||||||
|
private static final int FLAG_RESOLVED_BY_HEURISTICS= 8;
|
||||||
|
|
||||||
private final PDOM pdom;
|
private final PDOM pdom;
|
||||||
private final int record;
|
private final int record;
|
||||||
|
@ -81,6 +82,8 @@ public class PDOMInclude implements IIndexFragmentInclude {
|
||||||
}
|
}
|
||||||
if (unresolved) {
|
if (unresolved) {
|
||||||
flags |= FLAG_UNRESOLVED_INCLUDE;
|
flags |= FLAG_UNRESOLVED_INCLUDE;
|
||||||
|
} else if (include.isResolvedByHeuristics()) {
|
||||||
|
flags |= FLAG_RESOLVED_BY_HEURISTICS;
|
||||||
}
|
}
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
@ -225,6 +228,10 @@ public class PDOMInclude implements IIndexFragmentInclude {
|
||||||
return (getFlag() & FLAG_UNRESOLVED_INCLUDE) == 0;
|
return (getFlag() & FLAG_UNRESOLVED_INCLUDE) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isResolvedByHeuristics() throws CoreException {
|
||||||
|
return (getFlag() & FLAG_RESOLVED_BY_HEURISTICS) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
public int getNameOffset() throws CoreException {
|
public int getNameOffset() throws CoreException {
|
||||||
return pdom.getDB().getInt(record + NODE_OFFSET_OFFSET);
|
return pdom.getDB().getInt(record + NODE_OFFSET_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ public abstract class AbstractPDOMIndexer implements IPDOMIndexer {
|
||||||
|
|
||||||
public AbstractPDOMIndexer() {
|
public AbstractPDOMIndexer() {
|
||||||
fProperties.put(IndexerPreferences.KEY_INDEX_ALL_FILES, String.valueOf(false));
|
fProperties.put(IndexerPreferences.KEY_INDEX_ALL_FILES, String.valueOf(false));
|
||||||
|
fProperties.put(IndexerPreferences.KEY_INCLUDE_HEURISTICS, String.valueOf(true));
|
||||||
fProperties.put(IndexerPreferences.KEY_FILES_TO_PARSE_UP_FRONT, ""); //$NON-NLS-1$
|
fProperties.put(IndexerPreferences.KEY_FILES_TO_PARSE_UP_FRONT, ""); //$NON-NLS-1$
|
||||||
fProperties.put(IndexerPreferences.KEY_SKIP_ALL_REFERENCES, String.valueOf(false));
|
fProperties.put(IndexerPreferences.KEY_SKIP_ALL_REFERENCES, String.valueOf(false));
|
||||||
fProperties.put(IndexerPreferences.KEY_SKIP_TYPE_REFERENCES, String.valueOf(false));
|
fProperties.put(IndexerPreferences.KEY_SKIP_TYPE_REFERENCES, String.valueOf(false));
|
||||||
|
|
|
@ -45,6 +45,7 @@ public class IndexerPreferences {
|
||||||
|
|
||||||
public static final String KEY_INDEXER_ID= "indexerId"; //$NON-NLS-1$
|
public static final String KEY_INDEXER_ID= "indexerId"; //$NON-NLS-1$
|
||||||
public static final String KEY_INDEX_ALL_FILES= "indexAllFiles"; //$NON-NLS-1$
|
public static final String KEY_INDEX_ALL_FILES= "indexAllFiles"; //$NON-NLS-1$
|
||||||
|
public static final String KEY_INCLUDE_HEURISTICS= "useHeuristicIncludeResolution"; //$NON-NLS-1$
|
||||||
public static final String KEY_FILES_TO_PARSE_UP_FRONT= "filesToParseUpFront"; //$NON-NLS-1$
|
public static final String KEY_FILES_TO_PARSE_UP_FRONT= "filesToParseUpFront"; //$NON-NLS-1$
|
||||||
public static final String KEY_SKIP_ALL_REFERENCES= "skipReferences"; //$NON-NLS-1$
|
public static final String KEY_SKIP_ALL_REFERENCES= "skipReferences"; //$NON-NLS-1$
|
||||||
public static final String KEY_SKIP_TYPE_REFERENCES= "skipTypeReferences"; //$NON-NLS-1$
|
public static final String KEY_SKIP_TYPE_REFERENCES= "skipTypeReferences"; //$NON-NLS-1$
|
||||||
|
@ -156,7 +157,7 @@ public class IndexerPreferences {
|
||||||
Preferences[] prefs= getPreferences(project, scope);
|
Preferences[] prefs= getPreferences(project, scope);
|
||||||
Properties props= new Properties();
|
Properties props= new Properties();
|
||||||
for (int i=prefs.length-1; i>=0; i--) {
|
for (int i=prefs.length-1; i>=0; i--) {
|
||||||
addProperties(prefs[i], props);
|
readProperties(prefs[i], props);
|
||||||
}
|
}
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
@ -164,7 +165,7 @@ public class IndexerPreferences {
|
||||||
public static Properties getDefaultIndexerProperties() {
|
public static Properties getDefaultIndexerProperties() {
|
||||||
Preferences prefs= getDefaultPreferences();
|
Preferences prefs= getDefaultPreferences();
|
||||||
Properties props= new Properties();
|
Properties props= new Properties();
|
||||||
addProperties(prefs, props);
|
readProperties(prefs, props);
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +281,7 @@ public class IndexerPreferences {
|
||||||
return new LocalProjectScope(project).getNode(QUALIFIER).node(INDEXER_NODE);
|
return new LocalProjectScope(project).getNode(QUALIFIER).node(INDEXER_NODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addProperties(Preferences preferences, Properties props) {
|
private static void readProperties(Preferences preferences, Properties props) {
|
||||||
try {
|
try {
|
||||||
String[] keys = preferences.keys();
|
String[] keys = preferences.keys();
|
||||||
for (int i=0; i < keys.length; i++) {
|
for (int i=0; i < keys.length; i++) {
|
||||||
|
@ -298,6 +299,7 @@ public class IndexerPreferences {
|
||||||
Preferences prefs= defaultPreferences.node(INDEXER_NODE);
|
Preferences prefs= defaultPreferences.node(INDEXER_NODE);
|
||||||
prefs.put(KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER);
|
prefs.put(KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER);
|
||||||
prefs.putBoolean(KEY_INDEX_ALL_FILES, false);
|
prefs.putBoolean(KEY_INDEX_ALL_FILES, false);
|
||||||
|
prefs.putBoolean(KEY_INCLUDE_HEURISTICS, true);
|
||||||
prefs.putBoolean(KEY_SKIP_ALL_REFERENCES, false);
|
prefs.putBoolean(KEY_SKIP_ALL_REFERENCES, false);
|
||||||
prefs.putBoolean(KEY_SKIP_TYPE_REFERENCES, false);
|
prefs.putBoolean(KEY_SKIP_TYPE_REFERENCES, false);
|
||||||
prefs.putBoolean(KEY_SKIP_MACRO_REFERENCES, false);
|
prefs.putBoolean(KEY_SKIP_MACRO_REFERENCES, false);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2007 QNX Software Systems and others.
|
* Copyright (c) 2006, 2008 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.pdom.indexer;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the abstract indexer to return tasks suitable for fast indexing.
|
* Configures the abstract indexer to return tasks suitable for fast indexing.
|
||||||
|
@ -28,4 +29,9 @@ class PDOMFastIndexerTask extends PDOMIndexerTask {
|
||||||
protected ICodeReaderFactory createReaderFactory() {
|
protected ICodeReaderFactory createReaderFactory() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IIncludeFileResolutionHeuristics createIncludeHeuristics() {
|
||||||
|
return new ProjectIndexerIncludeResolutionHeuristics(getCProject().getProject(), getInputAdapter());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2006, 2007 QNX Software Systems and others.
|
* Copyright (c) 2006, 2008 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.pdom.indexer;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +29,11 @@ class PDOMFullIndexerTask extends PDOMIndexerTask {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ICodeReaderFactory createReaderFactory() {
|
protected ICodeReaderFactory createReaderFactory() {
|
||||||
return SavedCodeReaderFactory.getInstance();
|
return SavedCodeReaderFactory.createInstance(createIncludeHeuristics());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected IIncludeFileResolutionHeuristics createIncludeHeuristics() {
|
||||||
|
return new ProjectIndexerIncludeResolutionHeuristics(getCProject().getProject(), getInputAdapter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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 java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.IIncludeFileResolutionHeuristics;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.ASTFilePathResolver;
|
||||||
|
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Heuristics for picking up includes from the project
|
||||||
|
*/
|
||||||
|
public class ProjectIndexerIncludeResolutionHeuristics implements IIncludeFileResolutionHeuristics {
|
||||||
|
private static final String TRUE = "true"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
private static final boolean IGNORE_CASE = new File("a").equals(new File("A"));
|
||||||
|
|
||||||
|
private IProject fProject;
|
||||||
|
private IProject[] fProjects;
|
||||||
|
private final ASTFilePathResolver fResolver;
|
||||||
|
|
||||||
|
public ProjectIndexerIncludeResolutionHeuristics(IProject project, ASTFilePathResolver resolver) {
|
||||||
|
fProject= project;
|
||||||
|
fResolver= resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String findInclusion(String include, String currentFile) {
|
||||||
|
final IIndexFileLocation ifl= fResolver.resolveASTPath(currentFile);
|
||||||
|
if (ifl == null || ifl.getFullPath() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fProject == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
|
||||||
|
if (fProjects == null) {
|
||||||
|
if (fProject.isOpen()) {
|
||||||
|
String val= IndexerPreferences.get(fProject, IndexerPreferences.KEY_INCLUDE_HEURISTICS, TRUE);
|
||||||
|
if (TRUE.equals(val)) {
|
||||||
|
fProjects= getOpenReferencedProjects(fProject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fProjects == null) {
|
||||||
|
fProject= null;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IFile[] files= ResourceLookup.findFilesByName(new Path(include), fProjects, IGNORE_CASE);
|
||||||
|
if (files.length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return selectBest(files, ifl.getFullPath().toCharArray()).getLocation().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IResource selectBest(IFile[] files, char[] currentFullPath) {
|
||||||
|
IFile best= files[0];
|
||||||
|
int bestScore= computeScore(best.getFullPath().toString().toCharArray(), currentFullPath);
|
||||||
|
|
||||||
|
for (int i = 1; i < files.length; i++) {
|
||||||
|
IFile file= files[i];
|
||||||
|
int score= computeScore(file.getFullPath().toString().toCharArray(), currentFullPath);
|
||||||
|
if (score > bestScore) {
|
||||||
|
bestScore= score;
|
||||||
|
best= file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int computeScore(char[] path1, char[] path2) {
|
||||||
|
final int limit= Math.min(path1.length, path2.length);
|
||||||
|
int match=0;
|
||||||
|
for (int i = 0; i < limit; i++) {
|
||||||
|
if (path1[i] != path2[i])
|
||||||
|
break;
|
||||||
|
if (path1[i] == '/')
|
||||||
|
match= i;
|
||||||
|
}
|
||||||
|
// prefer shortest path with longest matches with
|
||||||
|
return (match << 16) - path1.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IProject[] getOpenReferencedProjects(IProject prj) {
|
||||||
|
Set<IProject> result= new HashSet<IProject>();
|
||||||
|
|
||||||
|
if (prj.isOpen()) {
|
||||||
|
result.add(prj);
|
||||||
|
|
||||||
|
List<IProject> projectsToSearch= new ArrayList<IProject>();
|
||||||
|
projectsToSearch.add(prj);
|
||||||
|
for (int i=0; i<projectsToSearch.size(); i++) {
|
||||||
|
IProject project= projectsToSearch.get(i);
|
||||||
|
IProject[] nextLevel;
|
||||||
|
try {
|
||||||
|
nextLevel= project.getReferencedProjects();
|
||||||
|
for (IProject prjNextLevel : nextLevel) {
|
||||||
|
if (prjNextLevel.isOpen() && result.add(prjNextLevel)) {
|
||||||
|
projectsToSearch.add(prjNextLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toArray(new IProject[result.size()]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,6 +55,7 @@ import org.eclipse.cdt.internal.core.model.IBufferFactory;
|
||||||
import org.eclipse.cdt.internal.core.model.Util;
|
import org.eclipse.cdt.internal.core.model.Util;
|
||||||
import org.eclipse.cdt.internal.core.model.WorkingCopy;
|
import org.eclipse.cdt.internal.core.model.WorkingCopy;
|
||||||
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
|
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
|
||||||
|
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
||||||
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
|
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IProjectDescription;
|
import org.eclipse.core.resources.IProjectDescription;
|
||||||
|
@ -322,6 +323,7 @@ public class CCorePlugin extends Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
fNewCProjectDescriptionManager.shutdown();
|
fNewCProjectDescriptionManager.shutdown();
|
||||||
|
ResourceLookup.shutdown();
|
||||||
|
|
||||||
savePluginPreferences();
|
savePluginPreferences();
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -340,6 +342,7 @@ public class CCorePlugin extends Plugin {
|
||||||
cdtLog = new CDTLogWriter(CCorePlugin.getDefault().getStateLocation().append(".log").toFile()); //$NON-NLS-1$
|
cdtLog = new CDTLogWriter(CCorePlugin.getDefault().getStateLocation().append(".log").toFile()); //$NON-NLS-1$
|
||||||
configurePluginDebugOptions();
|
configurePluginDebugOptions();
|
||||||
PositionTrackerManager.getInstance().install();
|
PositionTrackerManager.getInstance().install();
|
||||||
|
ResourceLookup.startup();
|
||||||
|
|
||||||
// new project model needs to register the resource listener first.
|
// new project model needs to register the resource listener first.
|
||||||
fNewCProjectDescriptionManager= CProjectDescriptionManager.getInstance();
|
fNewCProjectDescriptionManager= CProjectDescriptionManager.getInstance();
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* IBM - Initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom;
|
package org.eclipse.cdt.core.dom;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
||||||
|
@ -105,9 +105,9 @@ public class CDOM implements IASTServiceProvider {
|
||||||
case PARSE_SAVED_RESOURCES:
|
case PARSE_SAVED_RESOURCES:
|
||||||
return SavedCodeReaderFactory.getInstance();
|
return SavedCodeReaderFactory.getInstance();
|
||||||
case PARSE_WORKING_COPY_WITH_SAVED_INCLUSIONS:
|
case PARSE_WORKING_COPY_WITH_SAVED_INCLUSIONS:
|
||||||
return new PartialWorkingCopyCodeReaderFactory( provider );
|
return new PartialWorkingCopyCodeReaderFactory(provider, null);
|
||||||
case PARSE_WORKING_COPY_WHENEVER_POSSIBLE:
|
case PARSE_WORKING_COPY_WHENEVER_POSSIBLE:
|
||||||
return new WorkingCopyCodeReaderFactory( provider );
|
return new WorkingCopyCodeReaderFactory( provider, null );
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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.dom;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
||||||
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base implementation for all code reader factories.
|
||||||
|
*/
|
||||||
|
public abstract class AbstractCodeReaderFactory implements ICodeReaderFactory, IAdaptable {
|
||||||
|
|
||||||
|
private final IIncludeFileResolutionHeuristics fHeuristics;
|
||||||
|
|
||||||
|
public AbstractCodeReaderFactory(IIncludeFileResolutionHeuristics heuristics) {
|
||||||
|
fHeuristics= heuristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public Object getAdapter(Class adapter) {
|
||||||
|
if (adapter.isAssignableFrom(IIncludeFileResolutionHeuristics.class)) {
|
||||||
|
return fHeuristics;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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.dom;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract base class for heuristic include file resolution.
|
||||||
|
*/
|
||||||
|
public interface IIncludeFileResolutionHeuristics {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to find a file for the given include without using an include search path.
|
||||||
|
* @param include the include as provided in the directive
|
||||||
|
* @param currentFile the file the inclusion belongs to.
|
||||||
|
* @return a location for the inclusion or null.
|
||||||
|
*/
|
||||||
|
String findInclusion(String include, String currentFile);
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class NullCodeReaderFactory implements ICodeReaderFactory {
|
public class NullCodeReaderFactory extends AbstractCodeReaderFactory {
|
||||||
|
|
||||||
private static final char[] EMPTY_CHARS = new char[0];
|
private static final char[] EMPTY_CHARS = new char[0];
|
||||||
private static final ICodeReaderFactory INSTANCE= new NullCodeReaderFactory();
|
private static final ICodeReaderFactory INSTANCE= new NullCodeReaderFactory();
|
||||||
|
@ -29,7 +29,7 @@ public class NullCodeReaderFactory implements ICodeReaderFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private NullCodeReaderFactory() {
|
private NullCodeReaderFactory() {
|
||||||
// singleton
|
super(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -14,7 +14,6 @@ import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.CDOM;
|
import org.eclipse.cdt.core.dom.CDOM;
|
||||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
import org.eclipse.cdt.core.model.IWorkingCopyProvider;
|
import org.eclipse.cdt.core.model.IWorkingCopyProvider;
|
||||||
|
@ -26,8 +25,7 @@ import org.eclipse.cdt.internal.core.parser.EmptyIterator;
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
*/
|
*/
|
||||||
public class PartialWorkingCopyCodeReaderFactory
|
public class PartialWorkingCopyCodeReaderFactory extends AbstractCodeReaderFactory {
|
||||||
implements ICodeReaderFactory {
|
|
||||||
|
|
||||||
private final IWorkingCopyProvider provider;
|
private final IWorkingCopyProvider provider;
|
||||||
private ICodeReaderCache cache = null;
|
private ICodeReaderCache cache = null;
|
||||||
|
@ -35,7 +33,8 @@ public class PartialWorkingCopyCodeReaderFactory
|
||||||
/**
|
/**
|
||||||
* @param provider
|
* @param provider
|
||||||
*/
|
*/
|
||||||
public PartialWorkingCopyCodeReaderFactory(IWorkingCopyProvider provider) {
|
public PartialWorkingCopyCodeReaderFactory(IWorkingCopyProvider provider, IIncludeFileResolutionHeuristics heuristics) {
|
||||||
|
super(heuristics);
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
cache = SavedCodeReaderFactory.getInstance().getCodeReaderCache();
|
cache = SavedCodeReaderFactory.getInstance().getCodeReaderCache();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.dom;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.CDOM;
|
import org.eclipse.cdt.core.dom.CDOM;
|
||||||
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
|
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.parser.CodeReader;
|
import org.eclipse.cdt.core.parser.CodeReader;
|
||||||
import org.eclipse.cdt.core.parser.CodeReaderCache;
|
import org.eclipse.cdt.core.parser.CodeReaderCache;
|
||||||
|
@ -22,43 +21,49 @@ import org.eclipse.core.runtime.Preferences;
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
*/
|
*/
|
||||||
public class SavedCodeReaderFactory implements ICodeReaderFactory {
|
public class SavedCodeReaderFactory extends AbstractCodeReaderFactory {
|
||||||
|
|
||||||
private ICodeReaderCache cache = null;
|
private static ICodeReaderCache cache;
|
||||||
|
private static SavedCodeReaderFactory instance = new SavedCodeReaderFactory(null);
|
||||||
|
|
||||||
public static SavedCodeReaderFactory getInstance()
|
public static SavedCodeReaderFactory getInstance() {
|
||||||
{
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SavedCodeReaderFactory instance = new SavedCodeReaderFactory();
|
public static SavedCodeReaderFactory createInstance(IIncludeFileResolutionHeuristics heuristics) {
|
||||||
|
return new SavedCodeReaderFactory(heuristics);
|
||||||
|
}
|
||||||
|
|
||||||
private SavedCodeReaderFactory()
|
|
||||||
{
|
private SavedCodeReaderFactory(IIncludeFileResolutionHeuristics heuristics) {
|
||||||
int size= CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB;
|
super(heuristics);
|
||||||
final CCorePlugin corePlugin = CCorePlugin.getDefault();
|
|
||||||
if (corePlugin != null) {
|
if (cache == null) {
|
||||||
Preferences pluginPreferences = corePlugin.getPluginPreferences();
|
int size= CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB;
|
||||||
if (pluginPreferences != null) {
|
final CCorePlugin corePlugin = CCorePlugin.getDefault();
|
||||||
size = pluginPreferences.getInt(CodeReaderCache.CODE_READER_BUFFER);
|
if (corePlugin != null) {
|
||||||
if (size == 0) {
|
Preferences pluginPreferences = corePlugin.getPluginPreferences();
|
||||||
String [] properties = pluginPreferences.propertyNames();
|
if (pluginPreferences != null) {
|
||||||
boolean found = false;
|
size = pluginPreferences.getInt(CodeReaderCache.CODE_READER_BUFFER);
|
||||||
for (int j = 0; j < properties.length; ++j) {
|
if (size == 0) {
|
||||||
if (properties[j].equals( CodeReaderCache.CODE_READER_BUFFER)) {
|
String [] properties = pluginPreferences.propertyNames();
|
||||||
found = true;
|
boolean found = false;
|
||||||
break;
|
for (int j = 0; j < properties.length; ++j) {
|
||||||
|
if (properties[j].equals( CodeReaderCache.CODE_READER_BUFFER)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!found) {
|
||||||
if (!found) {
|
size= CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB;
|
||||||
|
}
|
||||||
|
} else if (size < 0) {
|
||||||
size= CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB;
|
size= CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB;
|
||||||
}
|
}
|
||||||
} else if (size < 0) {
|
|
||||||
size= CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cache= new CodeReaderCache(size);
|
||||||
}
|
}
|
||||||
cache = new CodeReaderCache(size);
|
|
||||||
}
|
}
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.eclipse.cdt.core.dom.ICodeReaderFactory#getUniqueIdentifier()
|
* @see org.eclipse.cdt.core.dom.ICodeReaderFactory#getUniqueIdentifier()
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* IBM - Initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom;
|
package org.eclipse.cdt.internal.core.dom;
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ public class WorkingCopyCodeReaderFactory extends PartialWorkingCopyCodeReaderFa
|
||||||
/**
|
/**
|
||||||
* @param provider
|
* @param provider
|
||||||
*/
|
*/
|
||||||
public WorkingCopyCodeReaderFactory(IWorkingCopyProvider provider) {
|
public WorkingCopyCodeReaderFactory(IWorkingCopyProvider provider, IIncludeFileResolutionHeuristics heuristics) {
|
||||||
super(provider);
|
super(provider, heuristics);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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.resources;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows for looking up resources by location or name.
|
||||||
|
*/
|
||||||
|
public class ResourceLookup {
|
||||||
|
private static ResourceLookupImpl sInstance= new ResourceLookupImpl();
|
||||||
|
|
||||||
|
public static void startup() {
|
||||||
|
sInstance.startup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void shutdown() {
|
||||||
|
sInstance.shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IFile[] findFilesForLocation(URI location, IProject[] projects) {
|
||||||
|
return sInstance.findFilesForLocation(location, projects);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for files with the given location suffix.
|
||||||
|
* @param locationSuffix the suffix to match, always used as relative path.
|
||||||
|
* @param projects the projects to search
|
||||||
|
* @param ignoreCase whether or not to ignore case when comparing the suffix.
|
||||||
|
*/
|
||||||
|
public static IFile[] findFilesByName(IPath locationSuffix, IProject[] projects, boolean ignoreCase) {
|
||||||
|
return sInstance.findFilesByName(locationSuffix, projects, ignoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For testing, only.
|
||||||
|
*/
|
||||||
|
public static void dump() {
|
||||||
|
sInstance.dump();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* For testing, only.
|
||||||
|
*/
|
||||||
|
public static void unrefNodeMap() {
|
||||||
|
sInstance.unrefNodeMap();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* For testing, only.
|
||||||
|
*/
|
||||||
|
public static void simulateNodeMapCollection() {
|
||||||
|
sInstance.simulateNodeMapCollection();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,809 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2008 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.resources;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.ref.SoftReference;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.CProjectNature;
|
||||||
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||||
|
import org.eclipse.core.resources.IResourceChangeListener;
|
||||||
|
import org.eclipse.core.resources.IResourceDelta;
|
||||||
|
import org.eclipse.core.resources.IResourceDeltaVisitor;
|
||||||
|
import org.eclipse.core.resources.IResourceProxy;
|
||||||
|
import org.eclipse.core.resources.IResourceProxyVisitor;
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||||
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.content.IContentType;
|
||||||
|
import org.eclipse.core.runtime.content.IContentTypeManager;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows for looking up resources by location or name. When using this class 100 bytes per resource
|
||||||
|
* are needed. Therefore the support is limited to header-files int non-cdt projects and all files
|
||||||
|
* except non-cdt-files in CDT projects.
|
||||||
|
*
|
||||||
|
* The information for a project is initialized when first requested and then it is kept up to date
|
||||||
|
* using a resource change listener. No memory is used, as long as the class is not used.
|
||||||
|
* When information is not used for more than 10 minutes, the data-structures will be held via a weak
|
||||||
|
* reference, only and are subject to garbage collection.
|
||||||
|
*
|
||||||
|
* The node map stores a map from hash-code of file-names to nodes.
|
||||||
|
* A node contains the name of a file plus a link to the parent resource. From that we can compute
|
||||||
|
* the resource path and obtain further information via the resource.
|
||||||
|
*/
|
||||||
|
class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisitor, IResourceProxyVisitor {
|
||||||
|
private static final int UNREF_DELAY = 10 * 60000; // 10 min
|
||||||
|
|
||||||
|
private static final boolean VISIT_CHILDREN = true;
|
||||||
|
private static final boolean SKIP_CHILDREN = false;
|
||||||
|
private static final IFile[] NO_FILES = new IFile[0];
|
||||||
|
private static final int TRIGGER_RECALC=
|
||||||
|
IResourceDelta.TYPE | IResourceDelta.REPLACED |
|
||||||
|
IResourceDelta.LOCAL_CHANGED | IResourceDelta.OPEN;
|
||||||
|
|
||||||
|
private static class Extensions {
|
||||||
|
private final boolean fInvert;
|
||||||
|
private final Set<String> fExtensions;
|
||||||
|
Extensions(Set<String> extensions, boolean invert) {
|
||||||
|
fInvert= invert;
|
||||||
|
fExtensions= extensions;
|
||||||
|
}
|
||||||
|
boolean isRelevant(String filename) {
|
||||||
|
// accept all files without extension
|
||||||
|
final int idx= filename.lastIndexOf('.');
|
||||||
|
if (idx < 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return fExtensions.contains(filename.substring(idx+1)) != fInvert;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Node {
|
||||||
|
final Node fParent;
|
||||||
|
final char[] fResourceName;
|
||||||
|
final boolean fIsFolder;
|
||||||
|
|
||||||
|
boolean fDeleted;
|
||||||
|
boolean fHasChildren;
|
||||||
|
private int fCanonicHash;
|
||||||
|
|
||||||
|
Node(Node parent, char[] name, boolean isFolder) {
|
||||||
|
fParent= parent;
|
||||||
|
fResourceName= name;
|
||||||
|
fIsFolder= isFolder;
|
||||||
|
if (parent != null)
|
||||||
|
parent.fHasChildren= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Object fLock= new Object();
|
||||||
|
private final Job fUnrefJob;
|
||||||
|
private SoftReference<Map<Integer, Object>> fNodeMapRef;
|
||||||
|
private Map<Integer, Object> fNodeMap;
|
||||||
|
private final Map<String, Extensions> fFileExtensions;
|
||||||
|
private Extensions fCDTProjectExtensions;
|
||||||
|
private Extensions fDefaultExtensions;
|
||||||
|
private Extensions fCurrentExtensions;
|
||||||
|
private Node fRootNode;
|
||||||
|
private boolean fNeedCleanup;
|
||||||
|
private Node fLastFolderNode;
|
||||||
|
|
||||||
|
public ResourceLookupImpl() {
|
||||||
|
fRootNode= new Node(null, CharArrayUtils.EMPTY, true) {};
|
||||||
|
fFileExtensions= new HashMap<String, Extensions>();
|
||||||
|
fUnrefJob= new Job("Timer") { //$NON-NLS-1$
|
||||||
|
@Override
|
||||||
|
protected IStatus run(IProgressMonitor monitor) {
|
||||||
|
unrefNodeMap();
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fUnrefJob.setSystem(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startup() {
|
||||||
|
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||||
|
workspace.addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() {
|
||||||
|
ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
|
||||||
|
synchronized (fLock) {
|
||||||
|
fNodeMap= null;
|
||||||
|
fNodeMapRef= null;
|
||||||
|
fFileExtensions.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle resource change notifications.
|
||||||
|
*/
|
||||||
|
public void resourceChanged(IResourceChangeEvent event) {
|
||||||
|
IResourceDelta delta= event.getDelta();
|
||||||
|
synchronized (fLock) {
|
||||||
|
if (fNodeMapRef == null)
|
||||||
|
return;
|
||||||
|
boolean unsetMap= false;
|
||||||
|
if (fNodeMap == null) {
|
||||||
|
fNodeMap= fNodeMapRef.get();
|
||||||
|
if (fNodeMap == null)
|
||||||
|
return;
|
||||||
|
unsetMap= true;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
delta.accept(this);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
} finally {
|
||||||
|
if (fNeedCleanup)
|
||||||
|
cleanup();
|
||||||
|
fCurrentExtensions= null;
|
||||||
|
fNeedCleanup= false;
|
||||||
|
if (unsetMap)
|
||||||
|
fNodeMap= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles resource change notifications by visiting the delta.
|
||||||
|
*/
|
||||||
|
public boolean visit(IResourceDelta delta) throws CoreException {
|
||||||
|
assert Thread.holdsLock(fLock);
|
||||||
|
|
||||||
|
final IResource res= delta.getResource();
|
||||||
|
if (res instanceof IWorkspaceRoot)
|
||||||
|
return VISIT_CHILDREN;
|
||||||
|
|
||||||
|
if (res instanceof IProject) {
|
||||||
|
// project not yet handled
|
||||||
|
final String name = res.getName();
|
||||||
|
final Extensions exts= fFileExtensions.get(name);
|
||||||
|
if (exts == null)
|
||||||
|
return SKIP_CHILDREN;
|
||||||
|
|
||||||
|
switch (delta.getKind()) {
|
||||||
|
case IResourceDelta.ADDED: // new projects should not yet be part of the tree
|
||||||
|
case IResourceDelta.REMOVED:
|
||||||
|
fFileExtensions.remove(name);
|
||||||
|
remove(res);
|
||||||
|
return SKIP_CHILDREN;
|
||||||
|
|
||||||
|
case IResourceDelta.CHANGED:
|
||||||
|
if ((delta.getFlags() & (TRIGGER_RECALC | IResourceDelta.DESCRIPTION)) != 0) {
|
||||||
|
fFileExtensions.remove(name);
|
||||||
|
remove(res);
|
||||||
|
return SKIP_CHILDREN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fCurrentExtensions= exts;
|
||||||
|
return VISIT_CHILDREN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file or folder
|
||||||
|
switch (delta.getKind()) {
|
||||||
|
case IResourceDelta.ADDED:
|
||||||
|
add(res);
|
||||||
|
return SKIP_CHILDREN;
|
||||||
|
|
||||||
|
case IResourceDelta.CHANGED:
|
||||||
|
if ((delta.getFlags() & TRIGGER_RECALC) != 0) {
|
||||||
|
remove(res);
|
||||||
|
add(res);
|
||||||
|
return SKIP_CHILDREN;
|
||||||
|
}
|
||||||
|
return VISIT_CHILDREN;
|
||||||
|
|
||||||
|
case IResourceDelta.REMOVED:
|
||||||
|
|
||||||
|
remove(res);
|
||||||
|
return SKIP_CHILDREN;
|
||||||
|
}
|
||||||
|
return VISIT_CHILDREN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a resource to the tree.
|
||||||
|
*/
|
||||||
|
private void add(IResource res) {
|
||||||
|
assert Thread.holdsLock(fLock);
|
||||||
|
|
||||||
|
if (res instanceof IFile) {
|
||||||
|
if (fCurrentExtensions.isRelevant(res.getName())) {
|
||||||
|
createFileNode(res.getFullPath());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
res.accept(this, 0);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a resource tree by using a resource proxy visitor.
|
||||||
|
*/
|
||||||
|
public boolean visit(IResourceProxy proxy) throws CoreException {
|
||||||
|
if (proxy.getType() == IResource.FILE) {
|
||||||
|
if (fCurrentExtensions.isRelevant(proxy.getName())) {
|
||||||
|
createFileNode(proxy.requestFullPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void unrefNodeMap() {
|
||||||
|
synchronized (fLock) {
|
||||||
|
fNodeMap= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void simulateNodeMapCollection() {
|
||||||
|
synchronized (fLock) {
|
||||||
|
fNodeMap= null;
|
||||||
|
fNodeMapRef= new SoftReference<Map<Integer, Object>>(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes nodes for the given projects. Also creates the node map if it was collected.
|
||||||
|
*/
|
||||||
|
private void initializeProjects(IProject[] projects) {
|
||||||
|
assert Thread.holdsLock(fLock);
|
||||||
|
|
||||||
|
if (fNodeMap == null) {
|
||||||
|
if (fNodeMapRef != null) {
|
||||||
|
fNodeMap= fNodeMapRef.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fNodeMap == null) {
|
||||||
|
fFileExtensions.clear();
|
||||||
|
fNodeMap= new HashMap<Integer, Object>();
|
||||||
|
fNodeMapRef= new SoftReference<Map<Integer, Object>>(fNodeMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fUnrefJob.cancel();
|
||||||
|
fUnrefJob.schedule(UNREF_DELAY);
|
||||||
|
|
||||||
|
for (IProject project : projects) {
|
||||||
|
if (project.isOpen() && !fFileExtensions.containsKey(project.getName())) {
|
||||||
|
Extensions ext= fDefaultExtensions;
|
||||||
|
try {
|
||||||
|
if (project.hasNature(CProjectNature.C_NATURE_ID)) {
|
||||||
|
ext= fCDTProjectExtensions;
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
// treat as non-cdt project
|
||||||
|
}
|
||||||
|
fCurrentExtensions= ext;
|
||||||
|
add(project);
|
||||||
|
fFileExtensions.put(project.getName(), ext);
|
||||||
|
fCurrentExtensions= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes file-extensions and node map
|
||||||
|
*/
|
||||||
|
private void initFileExtensions() {
|
||||||
|
if (fDefaultExtensions == null) {
|
||||||
|
HashSet<String> select= new HashSet<String>();
|
||||||
|
String[] registeredContentTypes= CoreModel.getRegistedContentTypeIds();
|
||||||
|
select.addAll(Arrays.asList(registeredContentTypes));
|
||||||
|
|
||||||
|
final IContentTypeManager ctm= Platform.getContentTypeManager();
|
||||||
|
final IContentType[] ctts= ctm.getAllContentTypes();
|
||||||
|
Set<String> result= new HashSet<String>();
|
||||||
|
outer: for (IContentType ctt : ctts) {
|
||||||
|
IContentType basedOn= ctt;
|
||||||
|
while (basedOn != null) {
|
||||||
|
if (select.contains(basedOn.getId()))
|
||||||
|
continue outer;
|
||||||
|
basedOn= basedOn.getBaseType();
|
||||||
|
}
|
||||||
|
// this is a non-cdt content type
|
||||||
|
String[] fspecs= ctt.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
|
||||||
|
result.addAll(Arrays.asList(fspecs));
|
||||||
|
}
|
||||||
|
fCDTProjectExtensions= new Extensions(result, true);
|
||||||
|
|
||||||
|
result= new HashSet<String>();
|
||||||
|
select.clear();
|
||||||
|
select.add(CCorePlugin.CONTENT_TYPE_CHEADER);
|
||||||
|
select.add(CCorePlugin.CONTENT_TYPE_CXXHEADER);
|
||||||
|
for (IContentType ctt : ctts) {
|
||||||
|
IContentType basedOn= ctt;
|
||||||
|
boolean selectme= false;
|
||||||
|
while (basedOn != null) {
|
||||||
|
if (select.contains(basedOn.getId())) {
|
||||||
|
selectme= true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
basedOn= basedOn.getBaseType();
|
||||||
|
}
|
||||||
|
if (selectme) {
|
||||||
|
// this is content type for a header file
|
||||||
|
String[] fspecs= ctt.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
|
||||||
|
result.addAll(Arrays.asList(fspecs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fDefaultExtensions= new Extensions(result, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a node for the given path.
|
||||||
|
*/
|
||||||
|
private void createFileNode(IPath fullPath) {
|
||||||
|
final String[] segments= fullPath.segments();
|
||||||
|
createNode(toCharArrayArray(segments), segments.length, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private char[][] toCharArrayArray(String[] segments) {
|
||||||
|
final int len= segments.length;
|
||||||
|
char[][] chsegs= new char[len][];
|
||||||
|
for (int i = 0; i < segments.length; i++) {
|
||||||
|
chsegs[i]= segments[i].toCharArray();
|
||||||
|
}
|
||||||
|
return chsegs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a node for the given path.
|
||||||
|
*/
|
||||||
|
private Node createNode(char[][] segments, int segmentCount, boolean folder) {
|
||||||
|
assert Thread.holdsLock(fLock);
|
||||||
|
|
||||||
|
if (segmentCount == 0)
|
||||||
|
return fRootNode;
|
||||||
|
|
||||||
|
if (folder && fLastFolderNode != null) {
|
||||||
|
if (isNodeForSegments(fLastFolderNode, segments, segmentCount))
|
||||||
|
return fLastFolderNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
final char[] name= segments[segmentCount-1];
|
||||||
|
final int hash= hashCode(name);
|
||||||
|
|
||||||
|
// search for existing node
|
||||||
|
Object obj= fNodeMap.get(hash);
|
||||||
|
|
||||||
|
Node[] nodes= null;
|
||||||
|
int len= 0;
|
||||||
|
if (obj != null) {
|
||||||
|
if (obj instanceof Node) {
|
||||||
|
Node node= (Node) obj;
|
||||||
|
if (isNodeForSegments(node, segments, segmentCount)) {
|
||||||
|
if (folder)
|
||||||
|
fLastFolderNode= node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
nodes= new Node[]{node, null};
|
||||||
|
fNodeMap.put(hash, nodes);
|
||||||
|
len= 1;
|
||||||
|
} else {
|
||||||
|
nodes= (Node[]) obj;
|
||||||
|
for (len=0; len < nodes.length; len++) {
|
||||||
|
Node node = nodes[len];
|
||||||
|
if (node == null)
|
||||||
|
break;
|
||||||
|
if (isNodeForSegments(node, segments, segmentCount)) {
|
||||||
|
if (folder)
|
||||||
|
fLastFolderNode= node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Node parent= createNode(segments, segmentCount-1, true);
|
||||||
|
Node node= new Node(parent, name, folder);
|
||||||
|
if (nodes == null) {
|
||||||
|
fNodeMap.put(hash, node);
|
||||||
|
} else {
|
||||||
|
if (len == nodes.length) {
|
||||||
|
Node[] newNodes= new Node[len+2];
|
||||||
|
System.arraycopy(nodes, 0, newNodes, 0, len);
|
||||||
|
nodes= newNodes;
|
||||||
|
fNodeMap.put(hash, nodes);
|
||||||
|
}
|
||||||
|
nodes[len]= node;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (folder)
|
||||||
|
fLastFolderNode= node;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given node matches the given segments.
|
||||||
|
*/
|
||||||
|
private boolean isNodeForSegments(Node node, char[][] segments, int segmentLength) {
|
||||||
|
assert Thread.holdsLock(fLock);
|
||||||
|
|
||||||
|
while(segmentLength > 0 && node != null) {
|
||||||
|
if (!CharArrayUtils.equals(segments[--segmentLength], node.fResourceName))
|
||||||
|
return false;
|
||||||
|
node= node.fParent;
|
||||||
|
}
|
||||||
|
return node == fRootNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a resource from the tree
|
||||||
|
*/
|
||||||
|
private void remove(IResource res) {
|
||||||
|
assert Thread.holdsLock(fLock);
|
||||||
|
|
||||||
|
final char[] name= res.getName().toCharArray();
|
||||||
|
final int hash= hashCode(name);
|
||||||
|
|
||||||
|
Object obj= fNodeMap.get(hash);
|
||||||
|
if (obj == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final IPath fullPath= res.getFullPath();
|
||||||
|
final int segmentCount= fullPath.segmentCount();
|
||||||
|
if (segmentCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
final char[][]segments= toCharArrayArray(fullPath.segments());
|
||||||
|
if (obj instanceof Node) {
|
||||||
|
final Node node= (Node) obj;
|
||||||
|
if (!node.fDeleted && isNodeForSegments(node, segments, segmentCount)) {
|
||||||
|
node.fDeleted= true;
|
||||||
|
if (node.fHasChildren)
|
||||||
|
fNeedCleanup= true;
|
||||||
|
fNodeMap.remove(hash);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final Node[] nodes= (Node[]) obj;
|
||||||
|
for (int i= 0; i < nodes.length; i++) {
|
||||||
|
Node node = nodes[i];
|
||||||
|
if (node == null)
|
||||||
|
return;
|
||||||
|
if (!node.fDeleted && isNodeForSegments(node, segments, segmentCount)) {
|
||||||
|
remove(nodes, i);
|
||||||
|
|
||||||
|
if (nodes[0] == null)
|
||||||
|
fNodeMap.remove(hash);
|
||||||
|
|
||||||
|
node.fDeleted= true;
|
||||||
|
if (node.fHasChildren)
|
||||||
|
fNeedCleanup= true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void remove(Node[] nodes, int i) {
|
||||||
|
int idx= lastValid(nodes, i);
|
||||||
|
if (idx > 0) {
|
||||||
|
nodes[i]= nodes[idx];
|
||||||
|
nodes[idx]= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int lastValid(Node[] nodes, int left) {
|
||||||
|
int right= nodes.length-1;
|
||||||
|
while (left < right) {
|
||||||
|
int mid= (left+right+1)/2; // ==> mid > left
|
||||||
|
if (nodes[mid] == null)
|
||||||
|
right= mid-1;
|
||||||
|
else
|
||||||
|
left= mid;
|
||||||
|
}
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanup() {
|
||||||
|
assert Thread.holdsLock(fLock);
|
||||||
|
fLastFolderNode= null;
|
||||||
|
|
||||||
|
for (Iterator<Object> iterator = fNodeMap.values().iterator(); iterator.hasNext();) {
|
||||||
|
Object obj= iterator.next();
|
||||||
|
if (obj instanceof Node) {
|
||||||
|
if (isDeleted((Node) obj)) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Node[] nodes= (Node[]) obj;
|
||||||
|
int j= 0;
|
||||||
|
for (int i = 0; i < nodes.length; i++) {
|
||||||
|
final Node node = nodes[i];
|
||||||
|
if (node == null) {
|
||||||
|
if (j==0) {
|
||||||
|
iterator.remove();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!isDeleted(node)) {
|
||||||
|
if (i != j) {
|
||||||
|
nodes[j]= node;
|
||||||
|
nodes[i]= null;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
} else {
|
||||||
|
nodes[i]= null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDeleted(Node node) {
|
||||||
|
while(node != null) {
|
||||||
|
if (node.fDeleted)
|
||||||
|
return true;
|
||||||
|
node= node.fParent;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes a case insensitive hash-code for file names.
|
||||||
|
*/
|
||||||
|
private int hashCode(char[] name) {
|
||||||
|
int h= 0;
|
||||||
|
final int len = name.length;
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
h = 31*h + Character.toUpperCase(name[i]);
|
||||||
|
}
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for all files with the given location.
|
||||||
|
*/
|
||||||
|
public IFile[] findFilesForLocation(URI location, IProject[] projects) {
|
||||||
|
initFileExtensions();
|
||||||
|
String name= extractName(location);
|
||||||
|
Node[] candidates;
|
||||||
|
synchronized (fLock) {
|
||||||
|
initializeProjects(projects);
|
||||||
|
Object obj= fNodeMap.get(hashCode(name.toCharArray()));
|
||||||
|
if (obj == null) {
|
||||||
|
return NO_FILES;
|
||||||
|
}
|
||||||
|
candidates= convert(obj);
|
||||||
|
}
|
||||||
|
return extractMatchesForLocation(candidates, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node[] convert(Object obj) {
|
||||||
|
if (obj instanceof Node)
|
||||||
|
return new Node[] {(Node) obj};
|
||||||
|
|
||||||
|
final Node[] nodes= (Node[]) obj;
|
||||||
|
final int len= lastValid(nodes, -1)+1;
|
||||||
|
final Node[] result= new Node[len];
|
||||||
|
System.arraycopy(nodes, 0, result, 0, len);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of files for the given name. Search is limited to the supplied projects.
|
||||||
|
*/
|
||||||
|
public IFile[] findFilesByName(IPath relativeLocation, IProject[] projects, boolean ignoreCase) {
|
||||||
|
final int segCount= relativeLocation.segmentCount();
|
||||||
|
if (segCount < 1)
|
||||||
|
return NO_FILES;
|
||||||
|
|
||||||
|
final String name= relativeLocation.lastSegment();
|
||||||
|
Node[] candidates;
|
||||||
|
|
||||||
|
initFileExtensions();
|
||||||
|
synchronized (fLock) {
|
||||||
|
initializeProjects(projects);
|
||||||
|
Object obj= fNodeMap.get(hashCode(name.toCharArray()));
|
||||||
|
if (obj == null) {
|
||||||
|
return NO_FILES;
|
||||||
|
}
|
||||||
|
candidates= convert(obj);
|
||||||
|
}
|
||||||
|
String suffix= relativeLocation.toString();
|
||||||
|
while(suffix.startsWith("../")) { //$NON-NLS-1$
|
||||||
|
suffix= suffix.substring(3);
|
||||||
|
}
|
||||||
|
return extractMatchesForName(candidates, name, suffix, ignoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String extractName(URI location) {
|
||||||
|
String path= location.getPath();
|
||||||
|
int idx= path.lastIndexOf('/');
|
||||||
|
return path.substring(idx+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects the actual matches for the list of candidate nodes.
|
||||||
|
*/
|
||||||
|
private IFile[] extractMatchesForName(Node[] candidates, String name, String suffix, boolean ignoreCase) {
|
||||||
|
final char[] n1= name.toCharArray();
|
||||||
|
final int namelen = n1.length;
|
||||||
|
int resultIdx= 0;
|
||||||
|
|
||||||
|
if (ignoreCase) {
|
||||||
|
for (int j = 0; j < namelen; j++) {
|
||||||
|
n1[j]= Character.toUpperCase(n1[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final int suffixLen= suffix.length();
|
||||||
|
final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
|
||||||
|
IFile[] result= null;
|
||||||
|
outer: for (int i = 0; i < candidates.length; i++) {
|
||||||
|
final Node node = candidates[i];
|
||||||
|
if (!node.fIsFolder) {
|
||||||
|
final char[] n2= node.fResourceName;
|
||||||
|
if (namelen == n2.length) {
|
||||||
|
for (int j = 0; j < n2.length; j++) {
|
||||||
|
final char c= ignoreCase ? Character.toUpperCase(n2[j]) : n2[j];
|
||||||
|
if (c != n1[j])
|
||||||
|
continue outer;
|
||||||
|
}
|
||||||
|
final IFile file= root.getFile(createPath(node));
|
||||||
|
final URI loc= file.getLocationURI();
|
||||||
|
if (loc != null) {
|
||||||
|
String path= loc.getPath();
|
||||||
|
final int len= path.length();
|
||||||
|
if (len >= suffixLen &&
|
||||||
|
suffix.regionMatches(ignoreCase, 0, path, len-suffixLen, suffixLen)) {
|
||||||
|
if (result == null)
|
||||||
|
result= new IFile[candidates.length-i];
|
||||||
|
result[resultIdx++]= root.getFile(createPath(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result==null)
|
||||||
|
return NO_FILES;
|
||||||
|
|
||||||
|
if (resultIdx < result.length) {
|
||||||
|
IFile[] copy= new IFile[resultIdx];
|
||||||
|
System.arraycopy(result, 0, copy, 0, resultIdx);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPath createPath(Node node) {
|
||||||
|
if (node == fRootNode)
|
||||||
|
return Path.ROOT;
|
||||||
|
|
||||||
|
return createPath(node.fParent).append(new String(node.fResourceName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects the actual matches from the list of candidates
|
||||||
|
*/
|
||||||
|
private IFile[] extractMatchesForLocation(Node[] candidates, URI location) {
|
||||||
|
final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
|
||||||
|
final String searchPath= getCanonicalPath(location);
|
||||||
|
IFile[] result= null;
|
||||||
|
int resultIdx= 0;
|
||||||
|
for (int i = 0; i < candidates.length; i++) {
|
||||||
|
final Node node = candidates[i];
|
||||||
|
if (!node.fIsFolder) {
|
||||||
|
final IFile file= root.getFile(createPath(node));
|
||||||
|
final URI loc= file.getLocationURI();
|
||||||
|
if (loc != null) {
|
||||||
|
if (!loc.equals(location)) {
|
||||||
|
if (searchPath == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (node.fCanonicHash != 0 && node.fCanonicHash != searchPath.hashCode())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
final String candPath= getCanonicalPath(loc);
|
||||||
|
if (candPath == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
node.fCanonicHash= candPath.hashCode();
|
||||||
|
if (!candPath.equals(searchPath))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (result == null)
|
||||||
|
result= new IFile[candidates.length-i];
|
||||||
|
result[resultIdx++]= root.getFile(createPath(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result==null)
|
||||||
|
return NO_FILES;
|
||||||
|
|
||||||
|
if (resultIdx < result.length) {
|
||||||
|
IFile[] copy= new IFile[resultIdx];
|
||||||
|
System.arraycopy(result, 0, copy, 0, resultIdx);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCanonicalPath(URI location) {
|
||||||
|
if (!"file".equals(location.getScheme())) //$NON-NLS-1$
|
||||||
|
return null;
|
||||||
|
|
||||||
|
String path= location.getPath();
|
||||||
|
try {
|
||||||
|
path= new File(path).getCanonicalPath();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// use non-canonical version
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
public void dump() {
|
||||||
|
List<String> lines= new ArrayList<String>();
|
||||||
|
synchronized (fLock) {
|
||||||
|
for (Iterator<Object> iterator = fNodeMap.values().iterator(); iterator.hasNext();) {
|
||||||
|
Node[] nodes= convert(iterator.next());
|
||||||
|
for (int i = 0; i < nodes.length; i++) {
|
||||||
|
final Node node = nodes[i];
|
||||||
|
if (node == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lines.add(toString(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(lines);
|
||||||
|
System.out.println("Dumping files:");
|
||||||
|
for (Iterator<String> iterator = lines.iterator(); iterator.hasNext();) {
|
||||||
|
String line = iterator.next();
|
||||||
|
System.out.println(line);
|
||||||
|
}
|
||||||
|
System.out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
|
private String toString(Node node) {
|
||||||
|
if (node == fRootNode)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return toString(node.fParent) + "/" + new String(node.fResourceName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,7 @@ public abstract class AbstractIndexerPage extends AbstractCOptionPage {
|
||||||
protected static final String TRUE = String.valueOf(true);
|
protected static final String TRUE = String.valueOf(true);
|
||||||
|
|
||||||
private Button fAllFiles;
|
private Button fAllFiles;
|
||||||
|
private Button fIncludeHeuristics;
|
||||||
private Text fFilesToParseUpFront;
|
private Text fFilesToParseUpFront;
|
||||||
private Button fSkipReferences;
|
private Button fSkipReferences;
|
||||||
private Button fSkipTypeReferences;
|
private Button fSkipTypeReferences;
|
||||||
|
@ -57,6 +58,7 @@ public abstract class AbstractIndexerPage extends AbstractCOptionPage {
|
||||||
public void createControl(Composite parent) {
|
public void createControl(Composite parent) {
|
||||||
Composite page = ControlFactory.createComposite(parent, 1);
|
Composite page = ControlFactory.createComposite(parent, 1);
|
||||||
fAllFiles= createAllFilesButton(page);
|
fAllFiles= createAllFilesButton(page);
|
||||||
|
fIncludeHeuristics= createIncludeHeuristicsButton(page);
|
||||||
fSkipReferences= createSkipReferencesButton(page);
|
fSkipReferences= createSkipReferencesButton(page);
|
||||||
fSkipTypeReferences= createSkipTypeReferencesButton(page);
|
fSkipTypeReferences= createSkipTypeReferencesButton(page);
|
||||||
fSkipMacroReferences= createSkipMacroReferencesButton(page);
|
fSkipMacroReferences= createSkipMacroReferencesButton(page);
|
||||||
|
@ -81,6 +83,11 @@ public abstract class AbstractIndexerPage extends AbstractCOptionPage {
|
||||||
boolean indexAllFiles= TRUE.equals(properties.get(IndexerPreferences.KEY_INDEX_ALL_FILES));
|
boolean indexAllFiles= TRUE.equals(properties.get(IndexerPreferences.KEY_INDEX_ALL_FILES));
|
||||||
fAllFiles.setSelection(indexAllFiles);
|
fAllFiles.setSelection(indexAllFiles);
|
||||||
}
|
}
|
||||||
|
if (fIncludeHeuristics != null) {
|
||||||
|
Object prop= properties.get(IndexerPreferences.KEY_INCLUDE_HEURISTICS);
|
||||||
|
boolean use= prop == null || TRUE.equals(prop);
|
||||||
|
fIncludeHeuristics.setSelection(use);
|
||||||
|
}
|
||||||
if (fSkipReferences != null) {
|
if (fSkipReferences != null) {
|
||||||
boolean skipReferences= TRUE.equals(properties.get(IndexerPreferences.KEY_SKIP_ALL_REFERENCES));
|
boolean skipReferences= TRUE.equals(properties.get(IndexerPreferences.KEY_SKIP_ALL_REFERENCES));
|
||||||
fSkipReferences.setSelection(skipReferences);
|
fSkipReferences.setSelection(skipReferences);
|
||||||
|
@ -109,6 +116,9 @@ public abstract class AbstractIndexerPage extends AbstractCOptionPage {
|
||||||
if (fAllFiles != null) {
|
if (fAllFiles != null) {
|
||||||
props.put(IndexerPreferences.KEY_INDEX_ALL_FILES, String.valueOf(fAllFiles.getSelection()));
|
props.put(IndexerPreferences.KEY_INDEX_ALL_FILES, String.valueOf(fAllFiles.getSelection()));
|
||||||
}
|
}
|
||||||
|
if (fIncludeHeuristics != null) {
|
||||||
|
props.put(IndexerPreferences.KEY_INCLUDE_HEURISTICS, String.valueOf(fIncludeHeuristics.getSelection()));
|
||||||
|
}
|
||||||
if (fFilesToParseUpFront != null) {
|
if (fFilesToParseUpFront != null) {
|
||||||
props.put(IndexerPreferences.KEY_FILES_TO_PARSE_UP_FRONT, fFilesToParseUpFront.getText());
|
props.put(IndexerPreferences.KEY_FILES_TO_PARSE_UP_FRONT, fFilesToParseUpFront.getText());
|
||||||
}
|
}
|
||||||
|
@ -169,6 +179,10 @@ public abstract class AbstractIndexerPage extends AbstractCOptionPage {
|
||||||
return ControlFactory.createCheckBox(page, INDEX_ALL_FILES);
|
return ControlFactory.createCheckBox(page, INDEX_ALL_FILES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Button createIncludeHeuristicsButton(Composite page) {
|
||||||
|
return ControlFactory.createCheckBox(page, DialogsMessages.AbstractIndexerPage_heuristicIncludes);
|
||||||
|
}
|
||||||
|
|
||||||
private Button createSkipReferencesButton(Composite page) {
|
private Button createSkipReferencesButton(Composite page) {
|
||||||
return ControlFactory.createCheckBox(page, DialogsMessages.AbstractIndexerPage_skipAllReferences);
|
return ControlFactory.createCheckBox(page, DialogsMessages.AbstractIndexerPage_skipAllReferences);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,10 @@ import org.eclipse.osgi.util.NLS;
|
||||||
|
|
||||||
public class DialogsMessages extends NLS {
|
public class DialogsMessages extends NLS {
|
||||||
private static final String BUNDLE_NAME = "org.eclipse.cdt.ui.dialogs.DialogsMessages"; //$NON-NLS-1$
|
private static final String BUNDLE_NAME = "org.eclipse.cdt.ui.dialogs.DialogsMessages"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public static String AbstractIndexerPage_heuristicIncludes;
|
||||||
public static String AbstractIndexerPage_indexAllFiles;
|
public static String AbstractIndexerPage_indexAllFiles;
|
||||||
public static String AbstractIndexerPage_indexUpFront;
|
public static String AbstractIndexerPage_indexUpFront;
|
||||||
public static String AbstractIndexerPage_skipAllReferences;
|
public static String AbstractIndexerPage_skipAllReferences;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
PreferenceScopeBlock_enableProjectSettings=Enable project specific settings
|
PreferenceScopeBlock_enableProjectSettings=Enable project specific settings
|
||||||
PreferenceScopeBlock_storeWithProject=Store settings with project
|
PreferenceScopeBlock_storeWithProject=Store settings with project
|
||||||
PreferenceScopeBlock_preferenceLink=<a>Configure Workspace Settings...</a>
|
PreferenceScopeBlock_preferenceLink=<a>Configure Workspace Settings...</a>
|
||||||
|
AbstractIndexerPage_heuristicIncludes=Allow heuristic resolution of includes
|
||||||
AbstractIndexerPage_indexAllFiles=Index all files (files neither built nor included, also)
|
AbstractIndexerPage_indexAllFiles=Index all files (files neither built nor included, also)
|
||||||
AbstractIndexerPage_skipAllReferences=Skip all references (Call Hierarchy and Search will not work)
|
AbstractIndexerPage_skipAllReferences=Skip all references (Call Hierarchy and Search will not work)
|
||||||
AbstractIndexerPage_skipTypeReferences=Skip type references (Search for type references will not work)
|
AbstractIndexerPage_skipTypeReferences=Skip type references (Search for type references will not work)
|
||||||
|
|
Loading…
Add table
Reference in a new issue