diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java index 93034bc3c82..19de2ee13ec 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/ILanguage.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.core.model; +import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; @@ -64,7 +65,22 @@ public interface ILanguage extends IAdaptable { * @param style * @return */ - public IASTTranslationUnit getASTTranslationUnit(ITranslationUnit file, int style); + public IASTTranslationUnit getASTTranslationUnit( + ITranslationUnit file, + int style); + + /** + * Create the AST for the given file with the given style with a given + * code reader factory. + * + * @param file + * @param style + * @return + */ + public IASTTranslationUnit getASTTranslationUnit( + ITranslationUnit file, + ICodeReaderFactory codeReaderFactory, + int style); /** * Return the AST Completion Node for the given working copy at the given diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java index 4f7911ac0e2..1c679186108 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/GCCLanguage.java @@ -79,6 +79,20 @@ public class GCCLanguage extends PlatformObject implements ILanguage { } public IASTTranslationUnit getASTTranslationUnit(ITranslationUnit file, int style) { + ICodeReaderFactory fileCreator; + if ((style & (ILanguage.AST_SKIP_INDEXED_HEADERS | ILanguage.AST_SKIP_ALL_HEADERS)) != 0) { + PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(file.getCProject()).getAdapter(PDOM.class); + fileCreator = new PDOMCodeReaderFactory(pdom); + } else + fileCreator = SavedCodeReaderFactory.getInstance(); + + return getASTTranslationUnit(file, fileCreator, style); + } + + public IASTTranslationUnit getASTTranslationUnit( + ITranslationUnit file, + ICodeReaderFactory codeReaderFactory, + int style) { IResource resource = file.getResource(); ICProject project = file.getCProject(); IProject rproject = project.getProject(); @@ -97,12 +111,6 @@ public class GCCLanguage extends PlatformObject implements ILanguage { } PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(project).getAdapter(PDOM.class); - ICodeReaderFactory fileCreator; - if ((style & (ILanguage.AST_SKIP_INDEXED_HEADERS | ILanguage.AST_SKIP_ALL_HEADERS)) != 0) - fileCreator = new PDOMCodeReaderFactory(pdom); - else - fileCreator = SavedCodeReaderFactory.getInstance(); - CodeReader reader; IFile rfile = (IFile)file.getResource(); if (file instanceof IWorkingCopy) { @@ -113,7 +121,7 @@ public class GCCLanguage extends PlatformObject implements ILanguage { = rfile != null ? rfile.getLocation().toOSString() : file.getPath().toOSString(); - reader = fileCreator.createCodeReaderForTranslationUnit(path); + reader = codeReaderFactory.createCodeReaderForTranslationUnit(path); if (reader == null) return null; } @@ -122,7 +130,7 @@ public class GCCLanguage extends PlatformObject implements ILanguage { = C_GNU_SCANNER_EXTENSION; IScanner scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE, - ParserLanguage.C, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator ); + ParserLanguage.C, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, codeReaderFactory); //assume GCC ISourceCodeParser parser = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE, ParserUtil.getParserLogService(), new GCCParserExtensionConfiguration() ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java index 8d2dffaaef1..27946be0b1b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/cpp/GPPLanguage.java @@ -78,6 +78,20 @@ public class GPPLanguage extends PlatformObject implements ILanguage { } public IASTTranslationUnit getASTTranslationUnit(ITranslationUnit file, int style) { + ICodeReaderFactory fileCreator; + if ((style & (ILanguage.AST_SKIP_INDEXED_HEADERS | ILanguage.AST_SKIP_ALL_HEADERS)) != 0) { + PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(file.getCProject()).getAdapter(PDOM.class); + fileCreator = new PDOMCodeReaderFactory(pdom); + } else + fileCreator = SavedCodeReaderFactory.getInstance(); + + return getASTTranslationUnit(file, fileCreator, style); + } + + public IASTTranslationUnit getASTTranslationUnit( + ITranslationUnit file, + ICodeReaderFactory codeReaderFactory, + int style) { IResource resource = file.getResource(); ICProject project = file.getCProject(); IProject rproject = project.getProject(); @@ -96,11 +110,6 @@ public class GPPLanguage extends PlatformObject implements ILanguage { } PDOM pdom = (PDOM)CCorePlugin.getPDOMManager().getPDOM(project).getAdapter(PDOM.class); - ICodeReaderFactory fileCreator; - if ((style & (ILanguage.AST_SKIP_INDEXED_HEADERS | ILanguage.AST_SKIP_ALL_HEADERS)) != 0) - fileCreator = new PDOMCodeReaderFactory(pdom); - else - fileCreator = SavedCodeReaderFactory.getInstance(); CodeReader reader; IFile rfile = (IFile)file.getResource(); @@ -109,7 +118,7 @@ public class GPPLanguage extends PlatformObject implements ILanguage { // get the working copy contents reader = new CodeReader(path, file.getContents()); } else { - reader = fileCreator.createCodeReaderForTranslationUnit(path); + reader = codeReaderFactory.createCodeReaderForTranslationUnit(path); if (reader == null) return null; } @@ -118,7 +127,7 @@ public class GPPLanguage extends PlatformObject implements ILanguage { = CPP_GNU_SCANNER_EXTENSION; IScanner scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE, - ParserLanguage.CPP, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator ); + ParserLanguage.CPP, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, codeReaderFactory); //assume GCC ISourceCodeParser parser = new GNUCPPSourceParser( scanner, ParserMode.COMPLETE_PARSE, ParserUtil.getParserLogService(), new GPPParserExtensionConfiguration() ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java index cb1b6a498b0..83745efa9c7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMCodeReaderFactory.java @@ -39,7 +39,8 @@ import org.eclipse.core.runtime.Status; public class PDOMCodeReaderFactory implements ICodeReaderFactory { private final PDOM pdom; - private List workingCopies; + private List workingCopies = new ArrayList(1); + private Set skippedHeaders = new HashSet(); public PDOMCodeReaderFactory(PDOM pdom) { this.pdom = pdom; @@ -47,7 +48,6 @@ public class PDOMCodeReaderFactory implements ICodeReaderFactory { public PDOMCodeReaderFactory(PDOM pdom, IWorkingCopy workingCopy) { this(pdom); - workingCopies = new ArrayList(1); workingCopies.add(workingCopy); } @@ -55,6 +55,10 @@ public class PDOMCodeReaderFactory implements ICodeReaderFactory { return 0; } + public Set getSkippedHeaders() { + return skippedHeaders; + } + public CodeReader createCodeReaderForTranslationUnit(String path) { return ParserUtil.createReader(path, workingCopies != null ? workingCopies.iterator() : null); @@ -101,6 +105,7 @@ public class PDOMCodeReaderFactory implements ICodeReaderFactory { if (file != null) { // Already got things from here, pass in a magic // buffer with the macros in it + skippedHeaders.add(path); StringBuffer buffer = new StringBuffer(); fillMacros(file, buffer, new HashSet()); int length = buffer.length(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java index a604d9cdc7b..1e05f16eccb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/fast/PDOMFastIndexerJob.java @@ -11,11 +11,21 @@ package org.eclipse.cdt.internal.core.pdom.indexer.fast; +import java.util.Set; + import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.PDOMCodeReaderFactory; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.jobs.Job; @@ -38,24 +48,152 @@ public abstract class PDOMFastIndexerJob extends Job { if (language == null) return null; + PDOMCodeReaderFactory codeReaderFactory = new PDOMCodeReaderFactory(pdom); + // get the AST in a "Fast" way return language.getASTTranslationUnit(tu, - ILanguage.AST_USE_INDEX - | ILanguage.AST_SKIP_INDEXED_HEADERS - | ILanguage.AST_SKIP_IF_NO_BUILD_INFO); + codeReaderFactory, + ILanguage.AST_USE_INDEX | ILanguage.AST_SKIP_IF_NO_BUILD_INFO); } protected void addTU(ITranslationUnit tu) throws InterruptedException, CoreException { - IASTTranslationUnit ast = parse(tu); + ILanguage language = tu.getLanguage(); + if (language == null) + return; + + PDOMCodeReaderFactory codeReaderFactory = new PDOMCodeReaderFactory(pdom); + + // get the AST in a "Fast" way + IASTTranslationUnit ast = language.getASTTranslationUnit(tu, + codeReaderFactory, + ILanguage.AST_USE_INDEX | ILanguage.AST_SKIP_IF_NO_BUILD_INFO); if (ast == null) return; + + Set skippedHeaders = codeReaderFactory.getSkippedHeaders(); pdom.acquireWriteLock(); try { - pdom.addSymbols(tu.getLanguage(), ast); + final PDOMLinkage linkage = pdom.getLinkage(language); + if (linkage == null) + return; + + // Add in the includes + IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives(); + for (int i = 0; i < includes.length; ++i) { + IASTPreprocessorIncludeStatement include = includes[i]; + + IASTFileLocation sourceLoc = include.getFileLocation(); + String sourcePath + = sourceLoc != null + ? sourceLoc.getFileName() + : ast.getFilePath(); // command-line includes + + PDOMFile sourceFile = pdom.addFile(sourcePath); + String destPath = include.getPath(); + PDOMFile destFile = pdom.addFile(destPath); + sourceFile.addIncludeTo(destFile); + } + + // Add in the macros + IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions(); + for (int i = 0; i < macros.length; ++i) { + IASTPreprocessorMacroDefinition macro = macros[i]; + + IASTFileLocation sourceLoc = macro.getFileLocation(); + if (sourceLoc == null) + continue; // skip built-ins and command line macros + + String filename = sourceLoc.getFileName(); + if (skippedHeaders.contains(filename)) + continue; + + PDOMFile sourceFile = pdom.getFile(filename); + if (sourceFile != null) // not sure why this would be null + sourceFile.addMacro(macro); + } + + // Add in the names + ast.accept(new ASTVisitor() { + { + shouldVisitNames = true; + shouldVisitDeclarations = true; + } + + public int visit(IASTName name) { + try { + linkage.addName(name); + return PROCESS_CONTINUE; + } catch (CoreException e) { + CCorePlugin.log(e); + return PROCESS_ABORT; + } + }; + });; + + // Tell the world + pdom.fireChange(); } finally { pdom.releaseWriteLock(); } } + public void addSymbols(ILanguage language, IASTTranslationUnit ast) throws CoreException { + final PDOMLinkage linkage = pdom.getLinkage(language); + if (linkage == null) + return; + + // Add in the includes + IASTPreprocessorIncludeStatement[] includes = ast.getIncludeDirectives(); + for (int i = 0; i < includes.length; ++i) { + IASTPreprocessorIncludeStatement include = includes[i]; + + IASTFileLocation sourceLoc = include.getFileLocation(); + String sourcePath + = sourceLoc != null + ? sourceLoc.getFileName() + : ast.getFilePath(); // command-line includes + + PDOMFile sourceFile = pdom.addFile(sourcePath); + String destPath = include.getPath(); + PDOMFile destFile = pdom.addFile(destPath); + sourceFile.addIncludeTo(destFile); + } + + // Add in the macros + IASTPreprocessorMacroDefinition[] macros = ast.getMacroDefinitions(); + for (int i = 0; i < macros.length; ++i) { + IASTPreprocessorMacroDefinition macro = macros[i]; + + IASTFileLocation sourceLoc = macro.getFileLocation(); + if (sourceLoc == null) + continue; // skip built-ins and command line macros + + PDOMFile sourceFile = pdom.getFile(sourceLoc.getFileName()); + if (sourceFile != null) // not sure why this would be null + sourceFile.addMacro(macro); + } + + // Add in the names + ast.accept(new ASTVisitor() { + { + shouldVisitNames = true; + shouldVisitDeclarations = true; + } + + public int visit(IASTName name) { + try { + linkage.addName(name); + return PROCESS_CONTINUE; + } catch (CoreException e) { + CCorePlugin.log(e); + return PROCESS_ABORT; + } + }; + });; + + // Tell the world + pdom.fireChange(); + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java index 53981630722..d76b9934ba3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/full/PDOMFullReindex.java @@ -44,6 +44,8 @@ public class PDOMFullReindex extends PDOMFullIndexerJob { final int[] count = { 0 }; pdom.getProject().accept(new ICElementVisitor() { public boolean visit(ICElement element) throws CoreException { + if (monitor.isCanceled()) + throw new CoreException(Status.CANCEL_STATUS); switch (element.getElementType()) { case ICElement.C_UNIT: ++count[0]; @@ -61,6 +63,8 @@ public class PDOMFullReindex extends PDOMFullIndexerJob { // First index all the source files (i.e. not headers) pdom.getProject().accept(new ICElementVisitor() { public boolean visit(ICElement element) throws CoreException { + if (monitor.isCanceled()) + throw new CoreException(Status.CANCEL_STATUS); switch (element.getElementType()) { case ICElement.C_UNIT: ITranslationUnit tu = (ITranslationUnit)element; @@ -85,6 +89,8 @@ public class PDOMFullReindex extends PDOMFullIndexerJob { // Now add in the header files but only if they aren't already indexed pdom.getProject().accept(new ICElementVisitor() { public boolean visit(ICElement element) throws CoreException { + if (monitor.isCanceled()) + throw new CoreException(Status.CANCEL_STATUS); switch (element.getElementType()) { case ICElement.C_UNIT: ITranslationUnit tu = (ITranslationUnit)element;