diff options
10 files changed, 516 insertions, 59 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexSymbols.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexSymbols.java new file mode 100644 index 00000000000..d8516d0e04e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexSymbols.java @@ -0,0 +1,43 @@ +package org.eclipse.cdt.core.index; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; +import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; + +/** + * A container for symbols that should be added to a linkage in the persisted index. Contributors + * of the org.eclipse.cdt.core.PDOMASTProcessor extension-point are provided the opportunity + * to process the parsed AST translation units. Elements of interest are added to an + * implementation of this interface. + * + * @since 5.6 + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + */ +public interface IIndexSymbols { + /** + * Return true if the map contains no symbols and false otherwise. + */ + public boolean isEmpty(); + + /** + * Adds an IASTName along with an optional referencing IASTName to the map. The names + * will be associated with the optional owning include statement. + * + * @param owner The optional include statement that provides context for the given + * names. Can be null. + * @param name The name that is being added to the map, cannot be null. + * @param caller The optional name that references the name being added. Can be null. + */ + public void add(IASTPreprocessorIncludeStatement owner, IASTName name, IASTName caller); + + /** + * Creates an association from the caller include statement to the owning context. + */ + public void add(IASTPreprocessorIncludeStatement owner, IASTPreprocessorIncludeStatement caller); + + /** + * Creates an association from the caller preprocessor statement to the owning context. + */ + public void add(IASTPreprocessorIncludeStatement owner, IASTPreprocessorStatement caller); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IPDOMASTProcessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IPDOMASTProcessor.java new file mode 100644 index 00000000000..6390d24d336 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IPDOMASTProcessor.java @@ -0,0 +1,44 @@ +package org.eclipse.cdt.core.index; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.internal.core.pdom.dom.IPDOMLinkageFactory; +import org.eclipse.core.runtime.CoreException; + +/** + * The PDOMASTProcessor extension point allows contributors to the org.eclipse.cdt.core.PDOMASTProcessor + * extension-point to store their own information in the persisted index. The intent is for + * contributors to define their own ILinkage to avoid managing conflicts with the storage format + * for existing Linkages. + * <p> + * NOTE: The existing org.eclipse.cdt.core.language extension-point, allows new pdomLinkageFactories + * to be added. However, the {@link IPDOMLinkageFactory} interface which must be implemented is + * in an internal package. + * + * @since 5.6 + * @noimplement Clients should extend {@link IPDOMASTProcessor.Abstract}. + */ +public interface IPDOMASTProcessor { + /** + * Process the input ast by adding significant symbols to the given output map. Return the + * linkage id that should be used to store the result, or {@link ILinkage#NO_LINKAGE_ID} if + * the AST contained nothing of significance to this processor. + * + * @param ast The input AST to be processed. + * @param symbols The output map of significant symbols. + * @return The linkage-id in which to store the symbols or {@link ILinkage#NO_LINKAGE_ID} + * if the AST contained nothing of significance. + */ + public int process(IASTTranslationUnit ast, IIndexSymbols symbols) throws CoreException; + + /** + * An abstract class that should be extended by contributors of the extension-point. Extending + * this class means that contributors will get default implementations for future additions. + */ + public static abstract class Abstract implements IPDOMASTProcessor { + @Override + public int process(IASTTranslationUnit ast, IIndexSymbols symbols) throws CoreException { + return ILinkage.NO_LINKAGE_ID; + } + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java index d509b6b16e1..b44872ece24 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java @@ -28,6 +28,7 @@ import java.util.Map; import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; @@ -39,6 +40,7 @@ import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexInclude; import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexManager; +import org.eclipse.cdt.core.index.IPDOMASTProcessor; import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.model.AbstractLanguage; import org.eclipse.cdt.core.model.ILanguage; @@ -1196,7 +1198,19 @@ public abstract class AbstractIndexerTask extends PDOMWriter { FileInAST[] fileKeys= orderedFileKeys.toArray(new FileInAST[orderedFileKeys.size()]); try { - addSymbols(ast, fileKeys, fIndex, false, ctx, fTodoTaskUpdater, pm); + // The default processing is handled by the indexer task. + PDOMWriter.Data data = new PDOMWriter.Data(ast, fileKeys, fIndex); + int storageLinkageID = process(ast, data); + if (storageLinkageID != ILinkage.NO_LINKAGE_ID) + addSymbols(data, storageLinkageID, ctx, fTodoTaskUpdater, pm); + + // Contributed processors now have an opportunity to examine the AST. + for(IPDOMASTProcessor processor : PDOMASTProcessorManager.getProcessors(ast)) { + data = new PDOMWriter.Data(ast, fileKeys, fIndex); + storageLinkageID = processor.process(ast, data); + if (storageLinkageID != ILinkage.NO_LINKAGE_ID) + addSymbols(data, storageLinkageID, ctx, fTodoTaskUpdater, pm); + } } catch (CoreException e) { // Avoid parsing files again, that caused an exception to be thrown. withdrawRequests(linkageID, fileKeys); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorDesc.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorDesc.java new file mode 100644 index 00000000000..a614f44e4d8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorDesc.java @@ -0,0 +1,141 @@ +package org.eclipse.cdt.internal.core.pdom; + +import java.util.Arrays; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.index.IPDOMASTProcessor; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ILanguage; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.expressions.EvaluationContext; +import org.eclipse.core.expressions.EvaluationResult; +import org.eclipse.core.expressions.Expression; +import org.eclipse.core.expressions.ExpressionConverter; +import org.eclipse.core.expressions.ExpressionTagNames; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; + +/** + * Internal container for extensions of org.eclipse.cdt.core.PDOMASTProcessor. The implementation + * of the processor is instantiated only after checking the enablement expression (if present) for + * the given AST translation unit. This avoids activating the contributing plugin until it is + * actually needed. + */ +public class PDOMASTProcessorDesc { + private static final String Attr_Class = "class"; //$NON-NLS-1$ + + private final IConfigurationElement element; + private final Expression enablementExpression; + private Boolean fStatus = null; + + private String id; + private IPDOMASTProcessor processor; + + private static final String VAR_PROJECTNATURES = "projectNatures"; //$NON-NLS-1$ + private static final String VAR_LANGUAGEID = "languageId"; //$NON-NLS-1$ + + /** + * An empty implementation of the processor used as a placeholder in descriptors that are unable + * to load the contributed class. + */ + private static final IPDOMASTProcessor NULL_PROCESSOR = new IPDOMASTProcessor.Abstract() { + }; + + public PDOMASTProcessorDesc(IConfigurationElement element) { + this.element = element; + + Expression expr = null; + IConfigurationElement[] children = element.getChildren(ExpressionTagNames.ENABLEMENT); + switch (children.length) { + case 0: + fStatus = Boolean.TRUE; + break; + case 1: + try { + ExpressionConverter parser = ExpressionConverter.getDefault(); + expr = parser.perform(children[0]); + } catch (CoreException e) { + CCorePlugin.log("Error in enablement expression of " + id, e); //$NON-NLS-1$ + } + break; + default: + CCorePlugin.log("Too many enablement expressions for " + id); //$NON-NLS-1$ + fStatus = Boolean.FALSE; + break; + } + enablementExpression = expr; + } + + private boolean matches(ITranslationUnit tu) { + // If the enablement expression is missing or structurally invalid, then return immediately + if (fStatus != null) + return fStatus.booleanValue(); + + // If there is no tu, then the enablement expression cannot be evaluated, assume that all + // taggers are needed + if (tu == null) + return true; + + if (enablementExpression != null) + try { + IProject project = null; + ICProject cProject = tu.getCProject(); + if (cProject != null) + project = cProject.getProject(); + + EvaluationContext evalContext = new EvaluationContext(null, project); + + // if the project is not accessible, then only taggers that don't care about it will + // get a chance to run + if (project != null) { + String[] natures = project.getDescription().getNatureIds(); + evalContext.addVariable(VAR_PROJECTNATURES, Arrays.asList(natures)); + } + + ILanguage language = tu.getLanguage(); + if (language != null) + evalContext.addVariable(VAR_LANGUAGEID, language.getId()); + + return enablementExpression.evaluate(evalContext) == EvaluationResult.TRUE; + } catch (CoreException e) { + CCorePlugin.log("Error while evaluating enablement expression for " + id, e); //$NON-NLS-1$ + } + + fStatus = Boolean.FALSE; + return false; + } + + private IPDOMASTProcessor getProcessor() { + if (processor == null) + synchronized (this) { + if (processor == null) { + try { + processor = (IPDOMASTProcessor) element.createExecutableExtension(Attr_Class); + } catch (CoreException e) { + String id = element.getDeclaringExtension().getNamespaceIdentifier() + '.' + + element.getDeclaringExtension().getSimpleIdentifier(); + CCorePlugin.log("Error in class attribute of " + id, e); //$NON-NLS-1$ + + // mark the tagger with an empty implementation to prevent future load attempts + processor = NULL_PROCESSOR; + } + } + } + + return processor; + } + + // Activates the plugin if needed. + public IPDOMASTProcessor getProcessorFor(IASTTranslationUnit ast) { + // If there isn't an ast with an AST-TU accessible, then there is no way to defer processing, + // just return the processor and let it try to sort things out. E.g., this happens for built-in + // things. + if (ast == null) + return getProcessor(); + + // Otherwise evaluate the enablement expression for this TU + return matches(ast.getOriginatingTranslationUnit()) ? getProcessor() : null; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorManager.java new file mode 100644 index 00000000000..945e9b81258 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorManager.java @@ -0,0 +1,52 @@ +package org.eclipse.cdt.internal.core.pdom; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.index.IPDOMASTProcessor; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.Platform; + +/** + * An internal manager for the org.eclipse.cdt.core.PDOMASTProcessor extension-point. + * + * @see #getProcessors(IASTTranslationUnit) + */ +public class PDOMASTProcessorManager { + + private static final String EXTENSION_POINT = "PDOMASTProcessor"; //$NON-NLS-1$ + + private static final List<PDOMASTProcessorDesc> processors = new ArrayList<PDOMASTProcessorDesc>(); + static { + // Load the extensions + IConfigurationElement[] elements + = Platform.getExtensionRegistry().getConfigurationElementsFor(CCorePlugin.PLUGIN_ID, EXTENSION_POINT); + for (IConfigurationElement element : elements) + processors.add(new PDOMASTProcessorDesc(element)); + } + + private PDOMASTProcessorManager() { + } + + /** + * Returns a list of the contributed PDOMASTProcessors that should be used with the + * specific AST. Does not return null. + */ + public static List<IPDOMASTProcessor> getProcessors(IASTTranslationUnit ast) { + List<IPDOMASTProcessor> list = null; + + for (PDOMASTProcessorDesc desc : processors) { + IPDOMASTProcessor processor = desc.getProcessorFor(ast); + if (processor != null) { + if (list == null) + list = new ArrayList<IPDOMASTProcessor>(); + list.add(processor); + } + } + + return list == null ? Collections.<IPDOMASTProcessor>emptyList() : list; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java index 2f78c6eaa0c..69ffd2aba2e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -48,6 +49,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; 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.IIndexSymbols; +import org.eclipse.cdt.core.index.IPDOMASTProcessor; import org.eclipse.cdt.core.parser.FileContent; import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.ISignificantMacros; @@ -72,7 +75,7 @@ import org.eclipse.osgi.util.NLS; * Abstract class to write information from AST. * @since 4.0 */ -abstract public class PDOMWriter { +abstract public class PDOMWriter implements IPDOMASTProcessor { private static final boolean REPORT_UNKNOWN_BUILTINS = false; public static class FileInAST { @@ -135,7 +138,7 @@ abstract public class PDOMWriter { final ArrayList<IASTPreprocessorIncludeStatement> fIncludes= new ArrayList<IASTPreprocessorIncludeStatement>(); } - private static class Data { + protected static class Data implements IIndexSymbols { final IASTTranslationUnit fAST; final FileInAST[] fSelectedFiles; final IWritableIndex fIndex; @@ -147,6 +150,44 @@ abstract public class PDOMWriter { fAST= ast; fSelectedFiles= selectedFiles; fIndex= index; + + for(FileInAST file : selectedFiles) + fSymbolMap.put(file.includeStatement, new Symbols()); + } + + @Override + public boolean isEmpty() { + if (fSymbolMap.isEmpty()) + return true; + + for (Symbols symbols : fSymbolMap.values()) + if (!symbols.fNames.isEmpty() + || !symbols.fIncludes.isEmpty() + || !symbols.fMacros.isEmpty()) + return false; + + return true; + } + + @Override + public void add(IASTPreprocessorIncludeStatement owner, IASTName name, IASTName caller) { + Symbols lists= fSymbolMap.get(owner); + if (lists != null) + lists.fNames.add(new IASTName[]{ name, caller }); + } + + @Override + public void add(IASTPreprocessorIncludeStatement owner, IASTPreprocessorIncludeStatement thing) { + Symbols lists= fSymbolMap.get(owner); + if (lists != null) + lists.fIncludes.add(thing); + } + + @Override + public void add(IASTPreprocessorIncludeStatement owner, IASTPreprocessorStatement thing) { + Symbols lists= fSymbolMap.get(owner); + if (lists != null) + lists.fMacros.add(thing); } } @@ -203,50 +244,45 @@ abstract public class PDOMWriter { } /** - * Extracts symbols from the given AST and adds them to the index. - * + * Extracts symbols from the given AST and adds them to the index. Ignores Data maps that are + * empty and ones where storageLinkageID == {@link ILinkage#NO_LINKAGE_ID}. + * <p> * When flushIndex is set to <code>false</code>, you must make sure to flush * the index after your last write operation. */ - final protected void addSymbols(IASTTranslationUnit ast, FileInAST[] selectedFiles, - IWritableIndex index, boolean flushIndex, FileContext ctx, - ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException, + final protected void addSymbols(Data data, int storageLinkageID, FileContext ctx, ITodoTaskUpdater taskUpdater, IProgressMonitor pm) throws InterruptedException, CoreException { + if (data.isEmpty() + || storageLinkageID == ILinkage.NO_LINKAGE_ID) + return; + if (fShowProblems) { fShowInclusionProblems= true; fShowScannerProblems= true; fShowSyntaxProblems= true; } - Data data= new Data(ast, selectedFiles, index); - for (FileInAST file : selectedFiles) { - data.fSymbolMap.put(file.includeStatement, new Symbols()); - } - - // Extract symbols from AST. - extractSymbols(data); - // Name resolution. resolveNames(data, pm); // Index update. - storeSymbolsInIndex(data, ctx, flushIndex, pm); + storeSymbolsInIndex(data, storageLinkageID, ctx, pm); // Tasks update. if (taskUpdater != null) { Set<IIndexFileLocation> locations= new HashSet<IIndexFileLocation>(); - for (FileInAST file : selectedFiles) { + for (FileInAST file : data.fSelectedFiles) { locations.add(file.fileContentKey.getLocation()); } - taskUpdater.updateTasks(ast.getComments(), locations.toArray(new IIndexFileLocation[locations.size()])); + taskUpdater.updateTasks(data.fAST.getComments(), locations.toArray(new IIndexFileLocation[locations.size()])); } if (!data.fStati.isEmpty()) { List<IStatus> stati = data.fStati; String path= null; - if (selectedFiles.length > 0) { - path= selectedFiles[selectedFiles.length - 1].fileContentKey.getLocation().getURI().getPath(); + if (data.fSelectedFiles.length > 0) { + path= data.fSelectedFiles[data.fSelectedFiles.length - 1].fileContentKey.getLocation().getURI().getPath(); } else { - path= ast.getFilePath().toString(); + path= data.fAST.getFilePath().toString(); } String msg= NLS.bind(Messages.PDOMWriter_errorWhileParsing, path); if (stati.size() == 1) { @@ -262,10 +298,9 @@ abstract public class PDOMWriter { } } - private void storeSymbolsInIndex(final Data data, FileContext ctx, boolean flushIndex, IProgressMonitor pm) + private void storeSymbolsInIndex(final Data data, int storageLinkageID, FileContext ctx, IProgressMonitor pm) throws InterruptedException, CoreException { final IIndexFragmentFile newFile= ctx == null ? null : ctx.fNewFile; - final int linkageID= data.fAST.getLinkage().getLinkageID(); for (int i= 0; i < data.fSelectedFiles.length; i++) { if (pm.isCanceled()) return; @@ -276,13 +311,13 @@ abstract public class PDOMWriter { trace("Indexer: adding " + fileInAST.fileContentKey.getLocation().getURI()); //$NON-NLS-1$ } Throwable th= null; - YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, flushIndex); + YieldableIndexLock lock = new YieldableIndexLock(data.fIndex, false); lock.acquire(); try { final boolean isReplacement= ctx != null && fileInAST.includeStatement == null; IIndexFragmentFile ifile= null; if (!isReplacement || newFile == null) { - ifile= storeFileInIndex(data, fileInAST, linkageID, lock); + ifile= storeFileInIndex(data, fileInAST, storageLinkageID, lock); reportFileWrittenToIndex(fileInAST, ifile); } @@ -389,9 +424,17 @@ abstract public class PDOMWriter { fStatistics.fResolutionTime += System.currentTimeMillis() - start; } - private void extractSymbols(Data data) throws CoreException { + @Override + public int process(final IASTTranslationUnit ast, final IIndexSymbols symbols) throws CoreException { + if (!(symbols instanceof Data)) { + // TODO Fix this case -- the old implementation relies on the symbol map being exactly + // as expected. + CCorePlugin.log(IStatus.ERROR, "Default processor must receive expected Data type"); //$NON-NLS-1$ + return ILinkage.NO_LINKAGE_ID; + } + int unresolvedIncludes= 0; - final IASTTranslationUnit ast = data.fAST; + Data data = (Data) symbols; final Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap = data.fSymbolMap; IASTPreprocessorStatement[] stmts = ast.getAllPreprocessorStatements(); @@ -404,7 +447,7 @@ abstract public class PDOMWriter { IASTPreprocessorIncludeStatement owner = astLoc.getContextInclusionStatement(); final boolean updateSource= symbolMap.containsKey(owner); if (updateSource) { - addToMap(symbolMap, owner, include); + symbols.add(owner, include); } if (include.isActive()) { if (!include.isResolved()) { @@ -421,7 +464,7 @@ abstract public class PDOMWriter { IASTFileLocation sourceLoc = stmt.getFileLocation(); if (sourceLoc != null) { // skip built-ins and command line macros IASTPreprocessorIncludeStatement owner = sourceLoc.getContextInclusionStatement(); - addToMap(symbolMap, owner, stmt); + symbols.add(owner, stmt); } } } @@ -444,7 +487,7 @@ abstract public class PDOMWriter { IASTFileLocation nameLoc = name.getFileLocation(); if (nameLoc != null) { IASTPreprocessorIncludeStatement owner= nameLoc.getContextInclusionStatement(); - addToMap(symbolMap, owner, new IASTName[] { name, caller }); + symbols.add(owner, name, caller); } } } @@ -459,7 +502,7 @@ abstract public class PDOMWriter { IASTFileLocation nameLoc = name.getFileLocation(); if (nameLoc != null) { IASTPreprocessorIncludeStatement owner= nameLoc.getContextInclusionStatement(); - addToMap(symbolMap, owner, new IASTName[] { name, null }); + symbols.add(owner, name, null); } } } @@ -484,6 +527,8 @@ abstract public class PDOMWriter { reportProblem(problem); } } + + return ast.getLinkage().getLinkageID(); } protected final boolean isRequiredReference(IASTName name) { @@ -516,26 +561,7 @@ abstract public class PDOMWriter { return false; } - private void addToMap(Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap, IASTPreprocessorIncludeStatement owner, IASTName[] thing) { - Symbols lists= symbolMap.get(owner); - if (lists != null) - lists.fNames.add(thing); - } - - private void addToMap(Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap, IASTPreprocessorIncludeStatement owner, IASTPreprocessorIncludeStatement thing) { - Symbols lists= symbolMap.get(owner); - if (lists != null) - lists.fIncludes.add(thing); - } - - private void addToMap(Map<IASTPreprocessorIncludeStatement, Symbols> symbolMap, - IASTPreprocessorIncludeStatement owner, IASTPreprocessorStatement thing) { - Symbols lists= symbolMap.get(owner); - if (lists != null) - lists.fMacros.add(thing); - } - - private IIndexFragmentFile storeFileInIndex(Data data, FileInAST astFile, int linkageID, + private IIndexFragmentFile storeFileInIndex(Data data, FileInAST astFile, int storageLinkageID, YieldableIndexLock lock) throws CoreException, InterruptedException { final IWritableIndex index = data.fIndex; IIndexFragmentFile file; @@ -548,8 +574,8 @@ abstract public class PDOMWriter { IIndexFileLocation location = fileKey.getLocation(); ISignificantMacros significantMacros = fileKey.getSignificantMacros(); - IIndexFragmentFile oldFile = index.getWritableFile(linkageID, location, significantMacros); - file= index.addUncommittedFile(linkageID, location, significantMacros); + IIndexFragmentFile oldFile = index.getWritableFile(storageLinkageID, location, significantMacros); + file= index.addUncommittedFile(storageLinkageID, location, significantMacros); try { boolean pragmaOnce= owner != null ? owner.hasPragmaOnceSemantics() : data.fAST.hasPragmaOnceSemantics(); file.setPragmaOnceSemantics(pragmaOnce); @@ -584,7 +610,7 @@ abstract public class PDOMWriter { } } IncludeInformation[] includeInfoArray= includeInfos.toArray(new IncludeInformation[includeInfos.size()]); - index.setFileContent(file, linkageID, includeInfoArray, macros, names, fResolver, lock); + index.setFileContent(file, storageLinkageID, includeInfoArray, macros, names, fResolver, lock); } file.setTimestamp(astFile.hasError ? 0 : astFile.timestamp); file.setSourceReadTime(astFile.sourceReadTime); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index b6e2d68c186..c5d8997fc73 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -56,8 +56,12 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; /** - * This class represents a collection of symbols that can be linked together at - * link time. These are generally global symbols specific to a given language. + * The top-level node in the PDOM storage format. A linkage is a collection of nodes + * that can be linked with references. Several linkages can be created for an input + * AST. + * + * TODO Move this to a public interface and discuss the extension point (that already + * exists). */ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage, IIndexBindingConstants { // Record offsets. @@ -84,13 +88,13 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage fDatabase= pdom.getDB(); } - protected PDOMLinkage(PDOM pdom, String languageId, char[] name) throws CoreException { + protected PDOMLinkage(PDOM pdom, String linkageID, char[] name) throws CoreException { super(pdom.getDB(), name); final Database db= pdom.getDB(); fPDOM= pdom; fDatabase= db; - db.putRecPtr(record + ID_OFFSET, db.newString(languageId).getRecord()); + db.putRecPtr(record + ID_OFFSET, db.newString(linkageID).getRecord()); pdom.insertLinkage(this); } diff --git a/core/org.eclipse.cdt.core/plugin.properties b/core/org.eclipse.cdt.core/plugin.properties index e6208db94b6..f06189e829e 100755 --- a/core/org.eclipse.cdt.core/plugin.properties +++ b/core/org.eclipse.cdt.core/plugin.properties @@ -122,6 +122,7 @@ projectConverter.name = Project converter CIndex.name = C/C++ Index externalSettingsProvider.name = External Settings provider tagger.name = Parser Node Tagger Extension Point +PDOMASTProcessor.name = PDOM AST Processor Extension Point GeneratePDOMApplication.name = GeneratePDOM defaultProvider.name = Default Provider templatesExtensionPoint.name = Templates Extension point diff --git a/core/org.eclipse.cdt.core/plugin.xml b/core/org.eclipse.cdt.core/plugin.xml index 0d4bbd6b960..3d6764c38ec 100644 --- a/core/org.eclipse.cdt.core/plugin.xml +++ b/core/org.eclipse.cdt.core/plugin.xml @@ -43,6 +43,7 @@ <extension-point id="CIndex" name="%CIndex.name" schema="schema/CIndex.exsd"/> <extension-point id="externalSettingsProvider" name="%externalSettingsProvider.name" schema="schema/externalSettingsProvider.exsd"/> <extension-point id="tagger" name="%tagger.name" schema="schema/tagger.exsd"/> + <extension-point id="PDOMASTProcessor" name="%PDOMASTProcessor.name" schema="schema/PDOMASTProcessor.exsd"/> <!-- =================================================================================== --> <!-- CProjectDescriptionStorage provides addition types of project description storage --> <!-- =================================================================================== --> diff --git a/core/org.eclipse.cdt.core/schema/PDOMASTProcessor.exsd b/core/org.eclipse.cdt.core/schema/PDOMASTProcessor.exsd new file mode 100644 index 00000000000..fb087747692 --- /dev/null +++ b/core/org.eclipse.cdt.core/schema/PDOMASTProcessor.exsd @@ -0,0 +1,131 @@ +<?xml version='1.0' encoding='UTF-8'?> +<!-- Schema file written by PDE --> +<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema"> +<annotation> + <appInfo> + <meta.schema plugin="org.eclipse.cdt.core" id="PDOMASTProcessor" name="PDOM AST Processor"/> + </appInfo> + <documentation> + This extension point allows extensions to contribute to the information that is written to the .pdom file. After the AST has been parsed, all contributors are provided a chance to process the AST's translation units while the .pdom is being updated. + </documentation> + </annotation> + + <include schemaLocation="schema://org.eclipse.core.expressions/schema/expressionLanguage.exsd"/> + + <element name="extension"> + <annotation> + <appInfo> + <meta.element /> + </appInfo> + </annotation> + <complexType> + <sequence> + <element ref="processor" minOccurs="1" maxOccurs="unbounded"/> + </sequence> + <attribute name="point" type="string" use="required"> + <annotation> + <documentation> + a fully qualified identifier of the target extension point + </documentation> + </annotation> + </attribute> + <attribute name="id" type="string"> + <annotation> + <documentation> + an optional identifier of the extension instance + </documentation> + </annotation> + </attribute> + <attribute name="name" type="string"> + <annotation> + <documentation> + an optional name of the extension instance + </documentation> + <appInfo> + <meta.attribute translatable="true"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <element name="processor"> + <complexType> + <sequence> + <element ref="enablement" minOccurs="0" maxOccurs="1"/> + </sequence> + <attribute name="class" type="string" use="required"> + <annotation> + <documentation> + + </documentation> + <appInfo> + <meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.index.IPDOMASTProcessor"/> + </appInfo> + </annotation> + </attribute> + </complexType> + </element> + + <annotation> + <appInfo> + <meta.section type="since"/> + </appInfo> + <documentation> + 8.3 + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="examples"/> + </appInfo> + <documentation> + The following is an example of a Tagger contribution: +<p> +<pre> +<extension + point="org.eclipse.cdt.core.PDOMASTProcessor" + id="example" + name="Example PDOM AST Processor"> + <bindingTagger + local-id="my-processor" + class="com.example.internal.ExamplePDOMASTProcessor"> + <enablement> + <with variable="projectNatures"> + <iterate operator="or"> + <equals value="com.example.my-nature"/> + </iterate> + </with> + </enablement> + </bindingTagger> +</extension> +</pre> +</p> + </documentation> + </annotation> + + <annotation> + <appInfo> + <meta.section type="apiInfo"/> + </appInfo> + <documentation> + The contributed class must implement <code>org.eclipse.cdt.core.index.IPDOMASTProcessor</code> interface. + </documentation> + </annotation> + + + <annotation> + <appInfo> + <meta.section type="copyright"/> + </appInfo> + <documentation> + Copyright (c) 2013 QNX Software Systems 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 + </documentation> + </annotation> + +</schema> |