1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Improved setup of macro dictionary for headers opened in editor, bug 228012

This commit is contained in:
Markus Schorn 2008-04-25 12:45:14 +00:00
parent b89383e939
commit d844f5e24a
5 changed files with 186 additions and 18 deletions

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -49,6 +50,7 @@ import org.eclipse.cdt.core.index.IIndexManager;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.index.IndexLocationFactory;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
@ -1323,4 +1325,29 @@ public class IndexBugsTests extends BaseTestCase {
fIndex.releaseReadLock();
}
}
// #define BUG ok
// int BUG;
// #include "common.h"
// #include "header.h"
public void testCommonHeader_Bug228012() throws Exception {
String[] contents= getContentsForTest(3);
final IIndexManager indexManager = CCorePlugin.getIndexManager();
TestSourceReader.createFile(fCProject.getProject(), "common.h", contents[0]);
IFile hfile= TestSourceReader.createFile(fCProject.getProject(), "header.h", contents[1]);
TestSourceReader.createFile(fCProject.getProject(), "source.cpp", contents[2]);
indexManager.reindex(fCProject);
waitForIndexer();
ITranslationUnit tu= (ITranslationUnit) CoreModel.getDefault().create(hfile);
fIndex.acquireReadLock();
try {
IASTTranslationUnit ast= tu.getAST(fIndex, ITranslationUnit.AST_CONFIGURE_USING_SOURCE_CONTEXT | ITranslationUnit.AST_SKIP_INDEXED_HEADERS);
IASTSimpleDeclaration decl= (IASTSimpleDeclaration) ast.getDeclarations()[0];
assertEquals("ok", decl.getDeclarators()[0].getName().toString());
} finally {
fIndex.releaseReadLock();
}
}
}

View file

@ -843,6 +843,9 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) {
IndexBasedCodeReaderFactory ibcf= new IndexBasedCodeReaderFactory(index, new ProjectIndexerInputAdapter(getCProject()), linkageID, codeReaderFactory);
if ((style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
ibcf.setSupportFillGapFromContextToHeader(true);
}
codeReaderFactory= ibcf;
}

View file

@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.index;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@ -47,6 +48,7 @@ import org.eclipse.core.runtime.CoreException;
*/
public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory {
private static final class NeedToParseException extends Exception {}
private static final String GAP = "__gap__"; //$NON-NLS-1$
private final IIndex fIndex;
private int fLinkage;
@ -55,6 +57,7 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
private final ICodeReaderFactory fFallBackFactory;
private final ASTFilePathResolver fPathResolver;
private final AbstractIndexerTask fRelatedIndexerTask;
private boolean fSupportFillGapFromContextToHeader= false;
public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage,
ICodeReaderFactory fallbackFactory) {
@ -70,9 +73,25 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
fLinkage= linkage;
}
public void setSupportFillGapFromContextToHeader(boolean val) {
fSupportFillGapFromContextToHeader= val;
}
public void setLinkage(int linkageID) {
fLinkage= linkageID;
}
public void cleanupAfterTranslationUnit() {
fIncludedFiles.clear();
}
public int getUniqueIdentifier() {
return 0;
}
public ICodeReaderCache getCodeReaderCache() {
return null;
}
public CodeReader createCodeReaderForTranslationUnit(String path) {
if (fFallBackFactory != null) {
@ -91,7 +110,12 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
public boolean getInclusionExists(String path) {
return fPathResolver.doesIncludeFileExist(path);
}
public boolean hasFileBeenIncludedInCurrentTranslationUnit(String path) {
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
return fIncludedFiles.contains(ifl);
}
public IncludeFileContent getContentForInclusion(String path) {
IIndexFileLocation ifl= fPathResolver.resolveIncludeFile(path);
if (ifl == null) {
@ -136,11 +160,7 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
return null;
}
public boolean hasFileBeenIncludedInCurrentTranslationUnit(String path) {
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
return fIncludedFiles.contains(ifl);
}
private void collectFileContent(IIndexFile file, Map<IIndexFileLocation, FileContent> macroMap, List<IIndexFile> files, boolean checkIncluded) throws CoreException, NeedToParseException {
IIndexFileLocation ifl= file.getLocation();
if (macroMap.containsKey(ifl) || (checkIncluded && fIncludedFiles.contains(ifl))) {
@ -163,8 +183,7 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
// follow the includes
IIndexInclude[] includeDirectives= file.getIncludes();
for (int i = 0; i < includeDirectives.length; i++) {
final IIndexInclude indexInclude = includeDirectives[i];
for (final IIndexInclude indexInclude : includeDirectives) {
IIndexFile includedFile= fIndex.resolveInclude(indexInclude);
if (includedFile != null) {
collectFileContent(includedFile, macroMap, files, true);
@ -172,15 +191,108 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
}
}
public void cleanupAfterTranslationUnit() {
fIncludedFiles.clear();
}
public IncludeFileContent getContentForContextToHeaderGap(String path) {
if (!fSupportFillGapFromContextToHeader) {
return null;
}
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
if (ifl == null) {
return null;
}
try {
IIndexFile targetFile= fIndex.getFile(fLinkage, ifl);
if (targetFile == null) {
return null;
}
IIndexFile contextFile= findContext(targetFile);
if (contextFile == targetFile || contextFile == null) {
return null;
}
HashSet<IIndexFile> filesIncluded= new HashSet<IIndexFile>();
ArrayList<IIndexMacro> macros= new ArrayList<IIndexMacro>();
ArrayList<ICPPUsingDirective> directives= new ArrayList<ICPPUsingDirective>();
if (!collectFileContentForGap(contextFile, ifl, filesIncluded, macros, directives)) {
return null;
}
public ICodeReaderCache getCodeReaderCache() {
// mark the files in the gap as included
for (IIndexFile file : filesIncluded) {
fIncludedFiles.add(file.getLocation());
}
Collections.reverse(macros);
return new IncludeFileContent(GAP, macros, directives, new ArrayList<IIndexFile>(filesIncluded));
}
catch (CoreException e) {
CCorePlugin.log(e);
}
return null;
}
public void setLinkage(int linkageID) {
fLinkage= linkageID;
private IIndexFile findContext(IIndexFile file) throws CoreException {
final HashSet<IIndexFile> ifiles= new HashSet<IIndexFile>();
ifiles.add(file);
IIndexInclude include= file.getParsedInContext();
while (include != null) {
final IIndexFile context= include.getIncludedBy();
if (!ifiles.add(context)) {
return file;
}
file= context;
}
return file;
}
private boolean collectFileContentForGap(IIndexFile from, IIndexFileLocation to,
Set<IIndexFile> filesIncluded, List<IIndexMacro> macros,
List<ICPPUsingDirective> directives) throws CoreException {
final IIndexFileLocation ifl= from.getLocation();
if (ifl.equals(to)) {
return true;
}
if (fIncludedFiles.contains(ifl) || !filesIncluded.add(from)) {
return false;
}
final IIndexInclude[] includeDirectives= from.getIncludes();
IIndexInclude success= null;
for (IIndexInclude indexInclude : includeDirectives) {
IIndexFile includedFile= fIndex.resolveInclude(indexInclude);
if (includedFile != null) {
if (collectFileContentForGap(includedFile, to, filesIncluded, macros, directives)) {
success= indexInclude;
break;
}
}
}
IIndexMacro[] mymacros= from.getMacros();
ICPPUsingDirective[] mydirectives= from.getUsingDirectives();
int startm, startd;
if (success == null) {
startm= mymacros.length-1;
startd= mydirectives.length-1;
}
else {
startm= startd= -1;
final int offset= success.getNameOffset();
for (IIndexMacro macro : from.getMacros()) {
if (macro.getFileLocation().getNodeOffset() < offset) {
startm++;
}
}
}
for (int i= startm; i >= 0; i--) {
macros.add(mymacros[i]);
}
for (int i= startd; i >= 0; i--) {
directives.add(mydirectives[i]);
}
return success != null;
}
}

View file

@ -45,6 +45,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayIntMap;
import org.eclipse.cdt.core.parser.util.CharArrayMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
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.Lexer.LexerOptions;
import org.eclipse.cdt.internal.core.parser.scanner.MacroDefinitionParser.InvalidMacroDefinitionException;
import org.eclipse.core.runtime.IAdaptable;
@ -135,11 +136,13 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
private final ScannerContext fRootContext;
private ScannerContext fCurrentContext;
private boolean isCancelled = false;
private boolean isCancelled= false;
private boolean fIsFirstFetchToken= true;
private Token fPrefetchedTokens;
private Token fLastToken;
public CPreprocessor(CodeReader reader, IScannerInfo info, ParserLanguage language, IParserLogService log,
IScannerExtensionConfiguration configuration, ICodeReaderFactory readerFactory) {
fLog = log;
@ -201,6 +204,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
public boolean getInclusionExists(String path) {
return readerFactory.createCodeReaderForInclusion(path) != null;
}
public IncludeFileContent getContentForContextToHeaderGap(String fileLocation) {
return null;
}
};
}
@ -296,6 +302,17 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
}
private void beforeFirstFetchToken() {
if (fPreIncludedFiles != null) {
handlePreIncludedFiles();
}
final String location = fLocationMap.getTranslationUnitPath();
IncludeFileContent content= fCodeReaderFactory.getContentForContextToHeaderGap(location);
if (content != null && content.getKind() == InclusionKind.FOUND_IN_INDEX) {
processInclusionFromIndex(0, location, content);
}
}
private void handlePreIncludedFiles() {
final String[] imacro= fPreIncludedFiles[0];
if (imacro != null && imacro.length > 0) {
@ -377,8 +394,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
* Returns the next token from the preprocessor without concatenating string literals.
*/
private Token fetchToken() throws OffsetLimitReachedException {
if (fPreIncludedFiles != null) {
handlePreIncludedFiles();
if (fIsFirstFetchToken) {
beforeFirstFetchToken();
fIsFirstFetchToken= false;
}
Token t= fPrefetchedTokens;
if (t != null) {

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.dom.ICodeReaderFactory;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent.InclusionKind;
/**
* The index based code-reader factory fakes the inclusion of files that are already indexed.
@ -36,4 +37,11 @@ public interface IIndexBasedCodeReaderFactory extends ICodeReaderFactory {
* @since 5.0
*/
boolean getInclusionExists(String finalPath);
/**
* Returns a file-content object of kind {@link InclusionKind#FOUND_IN_INDEX}, representing
* the content from the context of the given file up to where the file actually gets included.
* @since 5.0
*/
IncludeFileContent getContentForContextToHeaderGap(String fileLocation);
}