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.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName; 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.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.IIndexName;
import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.index.IndexLocationFactory; 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.ICElement;
import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
@ -1323,4 +1325,29 @@ public class IndexBugsTests extends BaseTestCase {
fIndex.releaseReadLock(); 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) { if (index != null && (style & AST_SKIP_INDEXED_HEADERS) != 0) {
IndexBasedCodeReaderFactory ibcf= new IndexBasedCodeReaderFactory(index, new ProjectIndexerInputAdapter(getCProject()), linkageID, codeReaderFactory); IndexBasedCodeReaderFactory ibcf= new IndexBasedCodeReaderFactory(index, new ProjectIndexerInputAdapter(getCProject()), linkageID, codeReaderFactory);
if ((style & AST_CONFIGURE_USING_SOURCE_CONTEXT) != 0) {
ibcf.setSupportFillGapFromContextToHeader(true);
}
codeReaderFactory= ibcf; codeReaderFactory= ibcf;
} }

View file

@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.index;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -47,6 +48,7 @@ import org.eclipse.core.runtime.CoreException;
*/ */
public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderFactory { public final class IndexBasedCodeReaderFactory 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 final IIndex fIndex; private final IIndex fIndex;
private int fLinkage; private int fLinkage;
@ -55,6 +57,7 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
private final ICodeReaderFactory fFallBackFactory; private final ICodeReaderFactory fFallBackFactory;
private final ASTFilePathResolver fPathResolver; private final ASTFilePathResolver fPathResolver;
private final AbstractIndexerTask fRelatedIndexerTask; private final AbstractIndexerTask fRelatedIndexerTask;
private boolean fSupportFillGapFromContextToHeader= false;
public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage, public IndexBasedCodeReaderFactory(IIndex index, ASTFilePathResolver pathResolver, int linkage,
ICodeReaderFactory fallbackFactory) { ICodeReaderFactory fallbackFactory) {
@ -70,9 +73,25 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
fLinkage= linkage; fLinkage= linkage;
} }
public void setSupportFillGapFromContextToHeader(boolean val) {
fSupportFillGapFromContextToHeader= val;
}
public void setLinkage(int linkageID) {
fLinkage= linkageID;
}
public void cleanupAfterTranslationUnit() {
fIncludedFiles.clear();
}
public int getUniqueIdentifier() { public int getUniqueIdentifier() {
return 0; return 0;
} }
public ICodeReaderCache getCodeReaderCache() {
return null;
}
public CodeReader createCodeReaderForTranslationUnit(String path) { public CodeReader createCodeReaderForTranslationUnit(String path) {
if (fFallBackFactory != null) { if (fFallBackFactory != null) {
@ -91,7 +110,12 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
public boolean getInclusionExists(String path) { public boolean getInclusionExists(String path) {
return fPathResolver.doesIncludeFileExist(path); return fPathResolver.doesIncludeFileExist(path);
} }
public boolean hasFileBeenIncludedInCurrentTranslationUnit(String path) {
IIndexFileLocation ifl= fPathResolver.resolveASTPath(path);
return fIncludedFiles.contains(ifl);
}
public IncludeFileContent getContentForInclusion(String path) { public IncludeFileContent getContentForInclusion(String path) {
IIndexFileLocation ifl= fPathResolver.resolveIncludeFile(path); IIndexFileLocation ifl= fPathResolver.resolveIncludeFile(path);
if (ifl == null) { if (ifl == null) {
@ -136,11 +160,7 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
return null; 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 { private void collectFileContent(IIndexFile file, Map<IIndexFileLocation, FileContent> macroMap, List<IIndexFile> files, boolean checkIncluded) throws CoreException, NeedToParseException {
IIndexFileLocation ifl= file.getLocation(); IIndexFileLocation ifl= file.getLocation();
if (macroMap.containsKey(ifl) || (checkIncluded && fIncludedFiles.contains(ifl))) { if (macroMap.containsKey(ifl) || (checkIncluded && fIncludedFiles.contains(ifl))) {
@ -163,8 +183,7 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
// follow the includes // follow the includes
IIndexInclude[] includeDirectives= file.getIncludes(); IIndexInclude[] includeDirectives= file.getIncludes();
for (int i = 0; i < includeDirectives.length; i++) { for (final IIndexInclude indexInclude : includeDirectives) {
final IIndexInclude indexInclude = includeDirectives[i];
IIndexFile includedFile= fIndex.resolveInclude(indexInclude); IIndexFile includedFile= fIndex.resolveInclude(indexInclude);
if (includedFile != null) { if (includedFile != null) {
collectFileContent(includedFile, macroMap, files, true); collectFileContent(includedFile, macroMap, files, true);
@ -172,15 +191,108 @@ public final class IndexBasedCodeReaderFactory implements IIndexBasedCodeReaderF
} }
} }
public void cleanupAfterTranslationUnit() { public IncludeFileContent getContentForContextToHeaderGap(String path) {
fIncludedFiles.clear(); 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; return null;
} }
public void setLinkage(int linkageID) { private IIndexFile findContext(IIndexFile file) throws CoreException {
fLinkage= linkageID; 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.CharArrayMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; 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.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.Lexer.LexerOptions;
import org.eclipse.cdt.internal.core.parser.scanner.MacroDefinitionParser.InvalidMacroDefinitionException; import org.eclipse.cdt.internal.core.parser.scanner.MacroDefinitionParser.InvalidMacroDefinitionException;
import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IAdaptable;
@ -135,11 +136,13 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
private final ScannerContext fRootContext; private final ScannerContext fRootContext;
private ScannerContext fCurrentContext; private ScannerContext fCurrentContext;
private boolean isCancelled = false; private boolean isCancelled= false;
private boolean fIsFirstFetchToken= true;
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;
@ -201,6 +204,9 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
public boolean getInclusionExists(String path) { public boolean getInclusionExists(String path) {
return readerFactory.createCodeReaderForInclusion(path) != null; 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() { private void handlePreIncludedFiles() {
final String[] imacro= fPreIncludedFiles[0]; final String[] imacro= fPreIncludedFiles[0];
if (imacro != null && imacro.length > 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. * Returns the next token from the preprocessor without concatenating string literals.
*/ */
private Token fetchToken() throws OffsetLimitReachedException { private Token fetchToken() throws OffsetLimitReachedException {
if (fPreIncludedFiles != null) { if (fIsFirstFetchToken) {
handlePreIncludedFiles(); beforeFirstFetchToken();
fIsFirstFetchToken= false;
} }
Token t= fPrefetchedTokens; Token t= fPrefetchedTokens;
if (t != null) { if (t != null) {

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.internal.core.parser.scanner; package org.eclipse.cdt.internal.core.parser.scanner;
import org.eclipse.cdt.core.dom.ICodeReaderFactory; 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. * 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 * @since 5.0
*/ */
boolean getInclusionExists(String finalPath); 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);
} }