mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Correctly resolving includes like "path/../file.h", bug 246129
This commit is contained in:
parent
0c73673ec2
commit
7b7875106f
14 changed files with 443 additions and 118 deletions
|
@ -66,5 +66,4 @@ public class FileCodeReaderFactory implements ICodeReaderFactory {
|
|||
public ICodeReaderCache getCodeReaderCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
package org.eclipse.cdt.internal.index.tests;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||
import org.eclipse.cdt.core.index.IIndexFile;
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.index.IIndexInclude;
|
||||
import org.eclipse.cdt.core.index.IndexFilter;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.IPathEntry;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||
import org.eclipse.cdt.core.testplugin.TestScannerProvider;
|
||||
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
|
||||
public class Bug246129 extends IndexTestBase {
|
||||
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = suite(Bug246129.class, "_");
|
||||
// suite.addTest(new Bug246129("include ext/../type.h"));
|
||||
return suite;
|
||||
}
|
||||
|
||||
private ICProject fProject;
|
||||
|
||||
private IFile fSource;
|
||||
|
||||
private IFolder fWrapperIncludeFolder;
|
||||
|
||||
private IFolder fIncludeFolder;
|
||||
|
||||
private File fTmpDir;
|
||||
|
||||
private File fExternalWrapperIncludeFolder;
|
||||
|
||||
private File fExternalWrapperHeader;
|
||||
|
||||
private File fExternalIncludeFolder;
|
||||
|
||||
private File fExternalHeader;
|
||||
|
||||
private File fExternalExtFolder;
|
||||
|
||||
IIndex fIndex;
|
||||
|
||||
boolean fFalseFriendsAccepted;
|
||||
|
||||
public Bug246129(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
if (fProject == null) {
|
||||
|
||||
// Populate workspace
|
||||
fProject = createProject(true, "resources/indexTests/bug246129");
|
||||
|
||||
fSource = fProject.getProject().getFile("source.cpp");
|
||||
|
||||
fWrapperIncludeFolder = fProject.getProject().getFolder(
|
||||
"wrapper_include");
|
||||
|
||||
fIncludeFolder = fProject.getProject().getFolder("include");
|
||||
|
||||
// Create header files external to the workspace.
|
||||
fTmpDir = CProjectHelper.freshDir();
|
||||
|
||||
fExternalWrapperIncludeFolder = new File(fTmpDir,
|
||||
"wrapper_include");
|
||||
fExternalWrapperIncludeFolder.mkdir();
|
||||
|
||||
fExternalWrapperHeader = new File(
|
||||
fExternalWrapperIncludeFolder, "external_type.h");
|
||||
fExternalWrapperHeader.createNewFile();
|
||||
FileWriter writer = new FileWriter(fExternalWrapperHeader);
|
||||
writer.write("#ifndef EXTERNAL_WRAPPER_TYPE_H_\n");
|
||||
writer.write("#define EXTERNAL_WRAPPER_TYPE_H_\n");
|
||||
writer.write("#include <ext/../external_type.h>\n");
|
||||
writer.write("class ExternalWrapper {\n");
|
||||
writer.write("};\n");
|
||||
writer.write("#endif\n");
|
||||
writer.close();
|
||||
|
||||
fExternalIncludeFolder = new File(fTmpDir, "include");
|
||||
fExternalIncludeFolder.mkdir();
|
||||
|
||||
fExternalExtFolder = new File(fExternalIncludeFolder, "ext");
|
||||
fExternalExtFolder.mkdir();
|
||||
|
||||
fExternalHeader = new File(fExternalIncludeFolder,
|
||||
"external_type.h");
|
||||
fExternalHeader.createNewFile();
|
||||
writer = new FileWriter(fExternalHeader);
|
||||
writer.write("#ifndef EXTERNAL_TYPE_H_\n");
|
||||
writer.write("#define EXTERNAL_TYPE_H_\n");
|
||||
writer.write("class ExternalType {\n");
|
||||
writer.write("};\n");
|
||||
writer.write("#endif\n");
|
||||
writer.close();
|
||||
|
||||
// The indexer needs non-empty build info in order to index
|
||||
// source files if index-all-files is turned off.
|
||||
IPathEntry[] entries = new IPathEntry[] { CoreModel
|
||||
.newIncludeEntry(fProject.getPath(), null,
|
||||
fWrapperIncludeFolder.getLocation()),
|
||||
CoreModel.newIncludeEntry(fProject.getPath(), null,
|
||||
fIncludeFolder.getLocation()) };
|
||||
|
||||
fProject.setRawPathEntries(entries, NPM);
|
||||
|
||||
// However, the scanner info provider used by the unit tests
|
||||
// needs separate setup, and this one must be complete.
|
||||
TestScannerProvider.sIncludes = new String[] {
|
||||
fWrapperIncludeFolder.getLocation().toOSString(),
|
||||
fIncludeFolder.getLocation().toOSString(),
|
||||
fExternalWrapperIncludeFolder.getAbsolutePath(),
|
||||
fExternalIncludeFolder.getAbsolutePath() };
|
||||
|
||||
IndexerPreferences.set(fProject.getProject(),
|
||||
IndexerPreferences.KEY_INDEX_ALL_FILES, "false");
|
||||
|
||||
File falseFriendDirectory = new File(fWrapperIncludeFolder
|
||||
.getLocation().toOSString()
|
||||
+ "/ext/..");
|
||||
|
||||
fFalseFriendsAccepted = falseFriendDirectory.exists();
|
||||
|
||||
CCorePlugin.getIndexManager().reindex(fProject);
|
||||
assertTrue(CCorePlugin.getIndexManager().joinIndexer(10000, NPM));
|
||||
fIndex = CCorePlugin.getIndexManager().getIndex(fProject);
|
||||
}
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
fExternalWrapperHeader.delete();
|
||||
fExternalWrapperIncludeFolder.delete();
|
||||
|
||||
fExternalHeader.delete();
|
||||
fExternalExtFolder.delete();
|
||||
fExternalIncludeFolder.delete();
|
||||
|
||||
fTmpDir.delete();
|
||||
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private void assertSymbolInIndex(String symbolName) throws Exception {
|
||||
IIndexBinding[] bindings = fIndex.findBindings(
|
||||
symbolName
|
||||
.toCharArray(), false, IndexFilter.ALL, NPM);
|
||||
assertTrue(bindings.length > 0);
|
||||
}
|
||||
|
||||
public void testIndex() throws Exception {
|
||||
|
||||
try {
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
IIndexFile[] indexFiles = fIndex.getAllFiles();
|
||||
|
||||
// Check that all header files have been found, provided the
|
||||
// File implementation does support it.
|
||||
if (fFalseFriendsAccepted) {
|
||||
assertEquals(3, indexFiles.length);
|
||||
} else {
|
||||
assertEquals(5, indexFiles.length);
|
||||
}
|
||||
|
||||
// The wrapper classes are found regardless whether false friends
|
||||
// are
|
||||
// accepted or not.
|
||||
assertSymbolInIndex("Wrapper");
|
||||
assertSymbolInIndex("ExternalWrapper");
|
||||
|
||||
// The Type class is only known on platforms with a File
|
||||
// implementation sorting out the false friends.
|
||||
if (!fFalseFriendsAccepted) {
|
||||
assertSymbolInIndex("Type");
|
||||
assertSymbolInIndex("ExternalType");
|
||||
}
|
||||
|
||||
// Check that all paths are normalized.
|
||||
for (IIndexFile indexFile : indexFiles) {
|
||||
|
||||
IIndexInclude[] includes = indexFile.getIncludes();
|
||||
|
||||
for (IIndexInclude i : includes) {
|
||||
IIndexFileLocation location = i.getIncludesLocation();
|
||||
assertNotNull(location);
|
||||
|
||||
assertFalse(location.getURI().toASCIIString()
|
||||
.contains(".."));
|
||||
|
||||
String fullPath = location.getFullPath();
|
||||
if (fullPath != null) {
|
||||
assertFalse(fullPath.contains(".."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertSymbolInAst(IScope scope, String symbolName)
|
||||
throws Exception {
|
||||
IBinding[] bindings = scope.find(symbolName);
|
||||
assertTrue(bindings.length > 0);
|
||||
}
|
||||
|
||||
public void testAst() throws Exception {
|
||||
ITranslationUnit tu = CoreModel.getDefault().createTranslationUnitFrom(
|
||||
fProject, fSource.getLocation());
|
||||
|
||||
IASTTranslationUnit ast = tu.getAST();
|
||||
|
||||
// The wrapper classes are found regardless whether false friends
|
||||
// are
|
||||
// accepted or not.
|
||||
IScope topLevel = ast.getScope();
|
||||
assertSymbolInAst(topLevel, "Wrapper");
|
||||
assertSymbolInAst(topLevel, "ExternalWrapper");
|
||||
|
||||
// The Type class is only known on platforms with a File
|
||||
// implementation sorting out the false friends.
|
||||
if (!fFalseFriendsAccepted) {
|
||||
assertSymbolInAst(topLevel, "Type");
|
||||
assertSymbolInAst(topLevel, "ExternalType");
|
||||
}
|
||||
|
||||
// Check that all paths are normalized.
|
||||
IASTPreprocessorIncludeStatement[] includes = ast
|
||||
.getIncludeDirectives();
|
||||
for (IASTPreprocessorIncludeStatement i : includes) {
|
||||
String includedPath = i.getPath();
|
||||
|
||||
assertNotNull(includedPath);
|
||||
assertFalse(includedPath.contains(".."));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@
|
|||
* Markus Schorn - initial API and implementation
|
||||
* Andrew Ferguson (Symbian)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.index.tests;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -81,7 +80,9 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
}
|
||||
|
||||
public static TestSuite suite() {
|
||||
return suite(IndexBugsTests.class);
|
||||
final TestSuite ts = suite(IndexBugsTests.class);
|
||||
ts.addTest(Bug246129.suite());
|
||||
return ts;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef DUMMY_H_
|
||||
#define DUMMY_H_
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
#ifndef TYPE_H_
|
||||
#define TYPE_H_
|
||||
class Type {
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,9 @@
|
|||
#include <type.h>
|
||||
#include <external_type.h>
|
||||
void check()
|
||||
{
|
||||
Type t;
|
||||
Wrapper w;
|
||||
ExternalType et;
|
||||
ExternalWrapper ew;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef WRAPPER_TYPE_H_
|
||||
#define WRAPPER_TYPE_H_
|
||||
#include <ext/../type.h>
|
||||
class Wrapper {
|
||||
};
|
||||
#endif
|
|
@ -69,6 +69,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
|||
import org.eclipse.cdt.internal.core.dom.NullCodeReaderFactory;
|
||||
import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory;
|
||||
import org.eclipse.cdt.internal.core.index.IndexBasedCodeReaderFactory;
|
||||
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
|
||||
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;
|
||||
|
@ -930,20 +931,25 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
|||
}
|
||||
|
||||
public CodeReader getCodeReader() {
|
||||
CodeReader reader;
|
||||
IPath location= getLocation();
|
||||
if (isWorkingCopy() || location == null) {
|
||||
if (location == null) {
|
||||
reader= new CodeReader(getContents());
|
||||
}
|
||||
else {
|
||||
reader= new CodeReader(location.toString(), getContents());
|
||||
}
|
||||
if (location == null)
|
||||
return new CodeReader(getContents());
|
||||
if (isWorkingCopy()) {
|
||||
return new CodeReader(location.toOSString(), getContents());
|
||||
}
|
||||
else {
|
||||
reader= ParserUtil.createReader(location.toString(), null);
|
||||
|
||||
IResource res= getResource();
|
||||
try {
|
||||
if (res instanceof IFile)
|
||||
return InternalParserUtil.createWorkspaceFileReader(location.toOSString(), (IFile) res);
|
||||
else
|
||||
return InternalParserUtil.createExternalFileReader(location.toOSString());
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
} catch (IOException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return reader;
|
||||
return null;
|
||||
}
|
||||
|
||||
public IScannerInfo getScannerInfo(boolean force) {
|
||||
|
|
|
@ -10,12 +10,10 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
||||
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
|
||||
|
||||
/**
|
||||
* This is an empty implementation of the ICodeReaderCache interface. It is used to implement a
|
||||
|
@ -32,18 +30,11 @@ public class EmptyCodeReaderCache implements ICodeReaderCache {
|
|||
* Creates a new CodeReader for the given file location.
|
||||
*/
|
||||
public CodeReader get(String location) {
|
||||
CodeReader ret = null;
|
||||
ret = InternalParserUtil.createFileReader(location);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* This provides support for PartialWorkingCopyCodeReaderFactory.
|
||||
* @param finalPath
|
||||
* @param workingCopies
|
||||
*/
|
||||
public CodeReader createReader(String finalPath, Iterator<IWorkingCopy> workingCopies ) {
|
||||
return InternalParserUtil.createFileReader(finalPath);
|
||||
try {
|
||||
return new CodeReader(location);
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.index;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -36,6 +37,7 @@ import org.eclipse.cdt.core.parser.ICodeReaderCache;
|
|||
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.InternalParserUtil;
|
||||
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.InclusionKind;
|
||||
|
@ -162,9 +164,15 @@ public final class IndexBasedCodeReaderFactory extends AbstractCodeReaderFactory
|
|||
CCorePlugin.log(e);
|
||||
}
|
||||
|
||||
CodeReader codeReader= createCodeReaderForInclusion(path);
|
||||
if (codeReader != null) {
|
||||
return new IncludeFileContent(codeReader);
|
||||
try {
|
||||
CodeReader codeReader= InternalParserUtil.createCodeReader(ifl);
|
||||
if (codeReader != null) {
|
||||
return new IncludeFileContent(codeReader);
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
CCorePlugin.log(e);
|
||||
} catch (IOException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -6,32 +6,80 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* John Camelon (IBM Corporation) - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.parser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||
import org.eclipse.cdt.core.parser.CodeReader;
|
||||
import org.eclipse.cdt.core.parser.ParserFactory;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
* Utility for creating code readers
|
||||
*/
|
||||
public class InternalParserUtil extends ParserFactory {
|
||||
|
||||
public static CodeReader createFileReader(String finalPath) {
|
||||
File includeFile = new File(finalPath);
|
||||
/**
|
||||
* Normalizes the path by using the location of the file, if possible.
|
||||
*/
|
||||
public static String normalizePath(String path, IFile file) {
|
||||
IPath loc= file.getLocation();
|
||||
if (loc != null) {
|
||||
path= loc.toOSString();
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a code reader for an external location, normalizing path to
|
||||
* canonical path.
|
||||
*/
|
||||
public static CodeReader createExternalFileReader(String externalLocation) throws IOException {
|
||||
File includeFile = new File(externalLocation);
|
||||
if (includeFile.isFile()) {
|
||||
try {
|
||||
//use the canonical path so that in case of non-case-sensitive OSs
|
||||
//the CodeReader always has the same name as the file on disk with
|
||||
//no differences in case.
|
||||
return new CodeReader(includeFile.getCanonicalPath());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
return new CodeReader(includeFile.getCanonicalPath());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a code reader for an external location, normalizing path to
|
||||
* canonical path.
|
||||
*/
|
||||
public static CodeReader createWorkspaceFileReader(String path, IFile file) throws CoreException, IOException{
|
||||
path = normalizePath(path, file);
|
||||
InputStream in= file.getContents();
|
||||
try {
|
||||
return new CodeReader(path, file.getCharset(), in);
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CodeReader createCodeReader(IIndexFileLocation ifl) throws CoreException, IOException {
|
||||
String fullPath= ifl.getFullPath();
|
||||
if (fullPath != null) {
|
||||
IResource res= ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(fullPath));
|
||||
if (res instanceof IFile)
|
||||
return createWorkspaceFileReader(ifl.getURI().getPath(), (IFile) res);
|
||||
}
|
||||
return createExternalFileReader(ifl.getURI().getPath());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,19 @@ public class ScannerUtility {
|
|||
* - replace multiple separators by single one
|
||||
* - skip "/./"
|
||||
* - skip quotes
|
||||
* - process "/../" (skip previous directory level)
|
||||
*
|
||||
* Note: "/../" is left untouched on purpose in order to work properly under
|
||||
* circumstances such as this:
|
||||
*
|
||||
* header file at include_1/vector:
|
||||
* // Is supposed to find the STL vector header:
|
||||
* #include <ext/../vector>
|
||||
*
|
||||
* GCC include tree
|
||||
* include_gcc/ext/...
|
||||
* /vector
|
||||
*
|
||||
* (ls include_1/ext/../vector does not work either).
|
||||
*
|
||||
* @param originalPath - path to process
|
||||
* @return - reconciled path
|
||||
|
@ -87,29 +99,12 @@ public class ScannerUtility {
|
|||
aus[j++] = DOT;
|
||||
aus[j++] = c;
|
||||
}
|
||||
// we found "/.." sequence. Look ahead.
|
||||
// Processed as usual
|
||||
else {
|
||||
// we found "/../" (or "/.." is at the end of string)
|
||||
// we should delete previous segment of output path
|
||||
if (i == len1 || ein[i+2] == SLASH || ein[i+2] == BSLASH) {
|
||||
i+=2;
|
||||
noSepBefore = false;
|
||||
if (j > 1) { // there is at least 1 segment before
|
||||
int k = j - 2;
|
||||
while ( k >= 0 ) {
|
||||
if (aus[k] == File.separatorChar) break;
|
||||
k--;
|
||||
}
|
||||
j = k + 1; // set index to previous segment or to 0
|
||||
}
|
||||
}
|
||||
// Case "/..blabla" processed as usual
|
||||
else {
|
||||
i++;
|
||||
noSepBefore = true;
|
||||
aus[j++] = DOT;
|
||||
aus[j++] = DOT;
|
||||
}
|
||||
i++;
|
||||
noSepBefore = true;
|
||||
aus[j++] = DOT;
|
||||
aus[j++] = DOT;
|
||||
}
|
||||
} else
|
||||
{} // do nothing when "." is last symbol
|
||||
|
|
|
@ -13,11 +13,10 @@
|
|||
package org.eclipse.cdt.core.parser;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.internal.core.parser.InternalParserUtil;
|
||||
import org.eclipse.cdt.internal.core.util.ILRUCacheable;
|
||||
import org.eclipse.cdt.internal.core.util.OverflowingLRUCache;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
|
@ -27,6 +26,7 @@ import org.eclipse.core.resources.IResourceChangeListener;
|
|||
import org.eclipse.core.resources.IResourceDelta;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
@ -140,25 +140,44 @@ public class CodeReaderCache implements ICodeReaderCache {
|
|||
* @param key the path of the CodeReader to retrieve
|
||||
*/
|
||||
public synchronized CodeReader get(String key) {
|
||||
CodeReader ret = null;
|
||||
CodeReader result = null;
|
||||
if (cache.getSpaceLimit() > 0)
|
||||
ret = cache.get(key);
|
||||
result= cache.get(key);
|
||||
|
||||
// not in the cache
|
||||
if (ret == null) {
|
||||
// for efficiency: check File.exists before ParserUtil#createReader()
|
||||
// bug 100947 fix: don't want to attempt to create a code reader if there is no file for the key
|
||||
if (!(new File(key).exists()))
|
||||
return null;
|
||||
if (result != null)
|
||||
return result;
|
||||
|
||||
final List<IWorkingCopy> emptyList= Collections.emptyList();
|
||||
ret = ParserUtil.createReader(key, emptyList.iterator());
|
||||
// for efficiency: check File.exists before ParserUtil#createReader()
|
||||
// bug 100947 fix: don't want to attempt to create a code reader if there is no file for the key
|
||||
final File jfile = new File(key);
|
||||
if (!(jfile.exists()))
|
||||
return null;
|
||||
|
||||
try {
|
||||
IResource file = ParserUtil.getResourceForFilename(key);
|
||||
if (file instanceof IFile) {
|
||||
key= InternalParserUtil.normalizePath(key, (IFile) file);
|
||||
result= cache.get(key);
|
||||
if (result != null)
|
||||
return result;
|
||||
|
||||
result= InternalParserUtil.createWorkspaceFileReader(key, (IFile) file);
|
||||
}
|
||||
key= jfile.getCanonicalPath();
|
||||
result= cache.get(key);
|
||||
if (result != null)
|
||||
return result;
|
||||
|
||||
result= InternalParserUtil.createExternalFileReader(key);
|
||||
if (cache.getSpaceLimit() > 0)
|
||||
put(ret);
|
||||
}
|
||||
put(result);
|
||||
|
||||
return ret;
|
||||
return result;
|
||||
} catch (CoreException ce) {
|
||||
} catch (IOException e) {
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
package org.eclipse.cdt.core.parser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
|
@ -62,49 +61,29 @@ public class ParserUtil
|
|||
return null;
|
||||
}
|
||||
|
||||
public static CodeReader createReader( String finalPath, Iterator<IWorkingCopy> workingCopies )
|
||||
{
|
||||
public static CodeReader createReader(String path, Iterator<IWorkingCopy> workingCopies) {
|
||||
// check to see if the file which this path points to points to an
|
||||
// IResource in the workspace
|
||||
try
|
||||
{
|
||||
IResource resultingResource = getResourceForFilename(finalPath);
|
||||
|
||||
if( resultingResource != null && resultingResource.getType() == IResource.FILE )
|
||||
{
|
||||
// this is the file for sure
|
||||
// check the working copy
|
||||
if( workingCopies != null && workingCopies.hasNext() )
|
||||
{
|
||||
char[] buffer = findWorkingCopy( resultingResource, workingCopies );
|
||||
if( buffer != null )
|
||||
return new CodeReader(finalPath, buffer);
|
||||
}
|
||||
InputStream in = null;
|
||||
try
|
||||
{
|
||||
in = ((IFile)resultingResource).getContents();
|
||||
return new CodeReader(finalPath, ((IFile)resultingResource).getCharset(), in);
|
||||
} finally {
|
||||
if (in != null)
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
try {
|
||||
IResource file = getResourceForFilename(path);
|
||||
if (file instanceof IFile) {
|
||||
// check for a working copy
|
||||
if (workingCopies != null && workingCopies.hasNext()) {
|
||||
char[] buffer = findWorkingCopy(file, workingCopies);
|
||||
if (buffer != null)
|
||||
return new CodeReader(InternalParserUtil.normalizePath(path, (IFile) file), buffer);
|
||||
}
|
||||
return InternalParserUtil.createWorkspaceFileReader(path, (IFile) file);
|
||||
}
|
||||
return InternalParserUtil.createExternalFileReader(path);
|
||||
} catch (CoreException ce) {
|
||||
} catch (IOException e) {
|
||||
} catch (IllegalStateException e) {
|
||||
}
|
||||
catch( CoreException ce )
|
||||
{
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
}
|
||||
catch( IllegalStateException e )
|
||||
{
|
||||
}
|
||||
return InternalParserUtil.createFileReader(finalPath);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static IResource getResourceForFilename(String finalPath) {
|
||||
IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||
if( workspace == null )
|
||||
|
|
Loading…
Add table
Reference in a new issue