summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Eidsness2013-11-28 15:23:42 (EST)
committer Doug Schaefer2013-11-29 00:27:15 (EST)
commit5e130ab883b6239ce9275b76036a2eea0e98d958 (patch)
tree5a9a57cf20235ca36a1726961e5f6faeffaa2bd8
parent08c7d10763cae343176d74699cc732da13dfe6bf (diff)
downloadorg.eclipse.cdt-5e130ab883b6239ce9275b76036a2eea0e98d958.zip
org.eclipse.cdt-5e130ab883b6239ce9275b76036a2eea0e98d958.tar.gz
org.eclipse.cdt-5e130ab883b6239ce9275b76036a2eea0e98d958.tar.bz2
Bug 422804: Allow contributors to add data to the PDOMrefs/changes/89/19089/2
The CDT persists an index of source code relationships by processing the AST produced by the parser. There is an existing extension-point that allows contributors to create new linkages in this persisted file. However there is no mechanism allowing contributors to influence the data that is stored to the file. This introduces a new extension-point allowing contributors to participate in processing the AST that is being persisted to the index. The intent is for this to be used to store data into the contributor's new Linkage. There is no change in functionality for existing linkages. A contributor will soon be added in the Qt plugin. Change-Id: I845c90cbf7c713e23319e2ed1168eb7d74db5868 Signed-off-by: Andrew Eidsness <eclipse@jfront.com> Reviewed-on: https://git.eclipse.org/r/19089 Tested-by: Hudson CI Reviewed-by: Doug Schaefer <dschaefer@qnx.com> IP-Clean: Doug Schaefer <dschaefer@qnx.com>
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexSymbols.java43
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IPDOMASTProcessor.java44
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/AbstractIndexerTask.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorDesc.java141
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMASTProcessorManager.java52
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMWriter.java134
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java12
-rwxr-xr-xcore/org.eclipse.cdt.core/plugin.properties1
-rw-r--r--core/org.eclipse.cdt.core/plugin.xml1
-rw-r--r--core/org.eclipse.cdt.core/schema/PDOMASTProcessor.exsd131
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 0000000..d8516d0
--- /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 0000000..6390d24
--- /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 d509b6b..b44872e 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 0000000..a614f44
--- /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 0000000..945e9b8
--- /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 2f78c6e..69ffd2a 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 b6e2d68..c5d8997 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 e6208db..f06189e 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 0d4bbd6..3d6764c 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 0000000..fb08774
--- /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&apos;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:
+&lt;p&gt;
+&lt;pre&gt;
+&lt;extension
+ point=&quot;org.eclipse.cdt.core.PDOMASTProcessor&quot;
+ id=&quot;example&quot;
+ name=&quot;Example PDOM AST Processor&quot;&gt;
+ &lt;bindingTagger
+ local-id=&quot;my-processor&quot;
+ class=&quot;com.example.internal.ExamplePDOMASTProcessor&quot;&gt;
+ &lt;enablement&gt;
+ &lt;with variable=&quot;projectNatures&quot;&gt;
+ &lt;iterate operator=&quot;or&quot;&gt;
+ &lt;equals value=&quot;com.example.my-nature&quot;/&gt;
+ &lt;/iterate&gt;
+ &lt;/with&gt;
+ &lt;/enablement&gt;
+ &lt;/bindingTagger&gt;
+&lt;/extension&gt;
+&lt;/pre&gt;
+&lt;/p&gt;
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ The contributed class must implement &lt;code&gt;org.eclipse.cdt.core.index.IPDOMASTProcessor&lt;/code&gt; 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>