From 45152faccdcad20533c3ff1d791c4f643bc17d96 Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Mon, 24 Apr 2006 18:54:15 +0000 Subject: [PATCH] A little ctags clean up. Added delta handling for Ctags. Looks a lot like Fast and Full, no? --- .../pdom/indexer/ctags/CtagsHandleDelta.java | 164 ++++++++++++++++++ .../core/pdom/indexer/ctags/CtagsIndexer.java | 107 ------------ .../pdom/indexer/ctags/CtagsIndexerJob.java | 147 ++++++++++++++++ .../core/pdom/indexer/ctags/CtagsReindex.java | 17 +- 4 files changed, 315 insertions(+), 120 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java new file mode 100644 index 00000000000..26b510b10f4 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsHandleDelta.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2006 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 + * + * Contributors: + * QNX - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.pdom.indexer.ctags; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMFile; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; + +/** + * @author Doug Schaefer + * + */ +public class CtagsHandleDelta extends CtagsIndexerJob { + + private final ICElementDelta delta; + + private List added = new ArrayList(); + private List changed = new ArrayList(); + private List removed = new ArrayList(); + + public CtagsHandleDelta(CtagsIndexer indexer, ICElementDelta delta) { + super(indexer); + this.delta = delta; + } + + protected IStatus run(IProgressMonitor monitor) { + try { + long start = System.currentTimeMillis(); + + processDelta(delta); + + int count = changed.size() + added.size() + removed.size(); + + if (count > 0) { + monitor.beginTask("Indexing", count); + + Iterator i = changed.iterator(); + while (i.hasNext()) { + ITranslationUnit tu = (ITranslationUnit)i.next(); + monitor.subTask(tu.getElementName()); + changeTU(tu); + monitor.worked(1); + } + + i = added.iterator(); + while (i.hasNext()) { + ITranslationUnit tu = (ITranslationUnit)i.next(); + monitor.subTask(tu.getElementName()); + addTU(tu); + monitor.worked(1); + } + + i = removed.iterator(); + while (i.hasNext()) { + ITranslationUnit tu = (ITranslationUnit)i.next(); + monitor.subTask(tu.getElementName()); + removeTU(tu); + monitor.worked(1); + } + + String showTimings = Platform.getDebugOption(CCorePlugin.PLUGIN_ID + + "/debug/pdomtimings"); //$NON-NLS-1$ + if (showTimings != null && showTimings.equalsIgnoreCase("true")) //$NON-NLS-1$ + System.out.println("PDOM Full Delta Time: " + (System.currentTimeMillis() - start)); //$NON-NLS-1$ + } + + return Status.OK_STATUS; + } catch (CoreException e) { + return e.getStatus(); + } catch (InterruptedException e) { + return Status.CANCEL_STATUS; + } + } + + protected void processDelta(ICElementDelta delta) throws CoreException { + int flags = delta.getFlags(); + + if ((flags & ICElementDelta.F_CHILDREN) != 0) { + ICElementDelta[] children = delta.getAffectedChildren(); + for (int i = 0; i < children.length; ++i) { + processDelta(children[i]); + } + } + + ICElement element = delta.getElement(); + switch (element.getElementType()) { + case ICElement.C_UNIT: + ITranslationUnit tu = (ITranslationUnit)element; + switch (delta.getKind()) { + case ICElementDelta.CHANGED: + if ((flags & ICElementDelta.F_CONTENT) != 0) + changed.add(tu); + break; + case ICElementDelta.ADDED: + if (!tu.isWorkingCopy()) + added.add(tu); + break; + case ICElementDelta.REMOVED: + if (!tu.isWorkingCopy()) + removed.add(tu); + break; + } + break; + } + } + + protected void addTU(ITranslationUnit tu) throws CoreException, InterruptedException { + IPath path = ((IFile)tu.getResource()).getLocation(); + runCtags(path); + } + + protected void changeTU(ITranslationUnit tu) throws CoreException, InterruptedException { + IPath path = ((IFile)tu.getResource()).getLocation(); + pdom.acquireWriteLock(); + try { + // Remove the old symbols in the tu + PDOMFile file = pdom.getFile(path); + if (file != null) + file.clear(); + + } finally { + pdom.releaseWriteLock(); + } + + // Add the new symbols + runCtags(path); + } + + protected void removeTU(ITranslationUnit tu) throws CoreException, InterruptedException { + pdom.acquireWriteLock(); + try { + IPath path = ((IFile)tu.getResource()).getLocation(); + PDOMFile file = pdom.getFile(path); + if (file != null) + file.clear(); + } finally { + pdom.releaseWriteLock(); + } + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java index 82af11d9fde..48da84cc3e3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexer.java @@ -11,25 +11,14 @@ package org.eclipse.cdt.internal.core.pdom.indexer.ctags; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.StringTokenizer; - import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOM; import org.eclipse.cdt.core.dom.IPDOMIndexer; -import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; -import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.internal.core.pdom.PDOM; -import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.core.runtime.preferences.IPreferencesService; @@ -65,102 +54,6 @@ public class CtagsIndexer implements IPDOMIndexer { return pdom; } - // Indexing functions - void runCtags(IPath sourcePath) { - String ctagsFileName = getResolvedCtagsFileName(); - String[] cmd = new String[] { - getResolvedCtagsCommand(), - "--excmd=number", //$NON-NLS-1$ - "--format=2", //$NON-NLS-1$ - "--sort=no", //$NON-NLS-1$ - "--fields=aiKlmnsSz", //$NON-NLS-1$ - "--c-types=cdefgmnpstuvx", //$NON-NLS-1$ - "--c++-types=cdefgmnpstuvx", //$NON-NLS-1$ - "--languages=c,c++", //$NON-NLS-1$ - "-f", //$NON-NLS-1$ - ctagsFileName, - "-R", //$NON-NLS-2$ - sourcePath.toOSString() // Give absolute path so that tag file entries will be absolute - }; - - try { - // Run ctags - Process p = Runtime.getRuntime().exec(cmd); - p.waitFor(); - - // Parse the ctags file - processCtagsFile(ctagsFileName); - } catch (InterruptedException e) { - return; - } catch (IOException e) { - CCorePlugin.log(e); - return; - } catch (CoreException e) { - CCorePlugin.log(e); - return; - } - } - - private void processCtagsFile(String ctagsFileName) throws IOException, CoreException { - BufferedReader reader = new BufferedReader(new FileReader(ctagsFileName)); - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - if (line.charAt(0) == '!') - // skip over header - continue; - - String elementName = null; - String fileName = null; - int lineNum = -1; - Map fields = new HashMap(); - - StringTokenizer tokenizer = new StringTokenizer(line, "\t"); //$NON-NLS-1$ - for (int state = 0; tokenizer.hasMoreTokens(); ++state) { - String token = tokenizer.nextToken(); - switch (state) { - case 0: - // element name - elementName = token; - break; - case 1: - // file name - fileName = token; - break; - case 2: - // line number - try { - token = token.trim(); - int i = token.indexOf(';'); - lineNum = Integer.parseInt(token.substring(0, i)) - 1; // Make it 0 based - } catch (NumberFormatException e) { - // Not sure what the line number is. - lineNum = -1; - } - break; - - default: - // extension field - int i = token.indexOf(':'); - if (i != -1) { - String key = token.substring(0, i); - String value = token.substring(i + 1); - fields.put(key, value); - } - } - } - - if (elementName != null && fileName != null) { - String languageName = (String)fields.get("language"); //$NON-NLS-1$ - if (languageName.equals("C++")) { //$NON-NLS-1$ - PDOMLinkage linkage = pdom.getLinkage(new GPPLanguage()); - new CtagsCPPName(linkage, fileName, lineNum, elementName, fields).addToPDOM(); - } else { - PDOMLinkage linkage = pdom.getLinkage(new GCCLanguage()); - new CtagsCName(linkage, fileName, lineNum, elementName, fields).addToPDOM(); - } - } - } - } - // Preference Management private static final String useCtagsOnPathId = "useCtagsOnPath"; //$NON-NLS-1$ private static final String ctagsCommandId = "ctagsCommand"; //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java new file mode 100644 index 00000000000..dd3e07da636 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsIndexerJob.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2006 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 + * + * Contributors: + * QNX - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.pdom.indexer.ctags; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; +import org.eclipse.cdt.internal.core.pdom.PDOM; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.jobs.Job; + +/** + * @author Doug Schaefer + * + */ +public abstract class CtagsIndexerJob extends Job { + + protected final CtagsIndexer indexer; + protected final PDOM pdom; + + public CtagsIndexerJob(CtagsIndexer indexer) { + super("ctags Indexer: " + ((PDOM)indexer.getPDOM()).getProject().getElementName()); + this.indexer = indexer; + this.pdom = (PDOM)indexer.getPDOM(); + setRule(CCorePlugin.getPDOMManager().getIndexerSchedulingRule()); + } + + // Indexing functions + void runCtags(IPath sourcePath) { + String ctagsFileName = indexer.getResolvedCtagsFileName(); + String[] cmd = new String[] { + indexer.getResolvedCtagsCommand(), + "--excmd=number", //$NON-NLS-1$ + "--format=2", //$NON-NLS-1$ + "--sort=no", //$NON-NLS-1$ + "--fields=aiKlmnsSz", //$NON-NLS-1$ + "--c-types=cdefgmnpstuvx", //$NON-NLS-1$ + "--c++-types=cdefgmnpstuvx", //$NON-NLS-1$ + "--languages=c,c++", //$NON-NLS-1$ + "-f", //$NON-NLS-1$ + ctagsFileName, + "-R", //$NON-NLS-2$ + sourcePath.toOSString() // Give absolute path so that tag file entries will be absolute + }; + + try { + // Run ctags + Process p = Runtime.getRuntime().exec(cmd); + p.waitFor(); + + // Parse the ctags file + pdom.acquireWriteLock(); + try { + processCtagsFile(ctagsFileName); + } finally { + pdom.releaseWriteLock(); + } + } catch (InterruptedException e) { + return; + } catch (IOException e) { + CCorePlugin.log(e); + return; + } catch (CoreException e) { + CCorePlugin.log(e); + return; + } + } + + private void processCtagsFile(String ctagsFileName) throws IOException, CoreException { + BufferedReader reader = new BufferedReader(new FileReader(ctagsFileName)); + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (line.charAt(0) == '!') + // skip over header + continue; + + String elementName = null; + String fileName = null; + int lineNum = -1; + Map fields = new HashMap(); + + StringTokenizer tokenizer = new StringTokenizer(line, "\t"); //$NON-NLS-1$ + for (int state = 0; tokenizer.hasMoreTokens(); ++state) { + String token = tokenizer.nextToken(); + switch (state) { + case 0: + // element name + elementName = token; + break; + case 1: + // file name + fileName = token; + break; + case 2: + // line number + try { + token = token.trim(); + int i = token.indexOf(';'); + lineNum = Integer.parseInt(token.substring(0, i)) - 1; // Make it 0 based + } catch (NumberFormatException e) { + // Not sure what the line number is. + lineNum = -1; + } + break; + + default: + // extension field + int i = token.indexOf(':'); + if (i != -1) { + String key = token.substring(0, i); + String value = token.substring(i + 1); + fields.put(key, value); + } + } + } + + if (elementName != null && fileName != null) { + String languageName = (String)fields.get("language"); //$NON-NLS-1$ + if (languageName.equals("C++")) { //$NON-NLS-1$ + PDOMLinkage linkage = pdom.getLinkage(new GPPLanguage()); + new CtagsCPPName(linkage, fileName, lineNum, elementName, fields).addToPDOM(); + } else { + PDOMLinkage linkage = pdom.getLinkage(new GCCLanguage()); + new CtagsCName(linkage, fileName, lineNum, elementName, fields).addToPDOM(); + } + } + } + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java index ec1354a82fa..b09843878e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/ctags/CtagsReindex.java @@ -11,33 +11,24 @@ package org.eclipse.cdt.internal.core.pdom.indexer.ctags; -import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IIncludeReference; import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.parser.util.ArrayUtil; -import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; /** * @author Doug Schaefer * */ -public class CtagsReindex extends Job { +public class CtagsReindex extends CtagsIndexerJob { - private final CtagsIndexer indexer; - private final PDOM pdom; - public CtagsReindex(CtagsIndexer indexer) { - super("ctags Indexer: " + ((PDOM)indexer.getPDOM()).getProject().getElementName()); - this.indexer = indexer; - this.pdom = (PDOM)indexer.getPDOM(); - setRule(CCorePlugin.getPDOMManager().getIndexerSchedulingRule()); + super(indexer); } protected IStatus run(IProgressMonitor monitor) { @@ -84,7 +75,7 @@ public class CtagsReindex extends Job { if (monitor.isCanceled()) return Status.CANCEL_STATUS; monitor.subTask(includes[i].getElementName()); - indexer.runCtags(includes[i].getPath()); + runCtags(includes[i].getPath()); monitor.worked(1); } @@ -96,7 +87,7 @@ public class CtagsReindex extends Job { if (monitor.isCanceled()) return Status.CANCEL_STATUS; monitor.subTask(sourceRoot.getElementName()); - indexer.runCtags(sourcePath); + runCtags(sourcePath); monitor.worked(1); } }