diff --git a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java index f8726c488cc..14b97cc9ed1 100644 --- a/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java +++ b/codan/org.eclipse.cdt.codan.core.cxx/src/org/eclipse/cdt/codan/core/cxx/internal/externaltool/ExternalToolInvoker.java @@ -28,6 +28,7 @@ import org.eclipse.core.runtime.NullProgressMonitor; * Invokes an external tool to perform checks on a single file. */ public class ExternalToolInvoker { + private static final String DEFAULT_CONTEXT_MENU_ID = "org.eclipse.cdt.ui.CDTBuildConsole"; //$NON-NLS-1$ private static final String[] ENV = {}; private static final NullProgressMonitor NULL_PROGRESS_MONITOR = new NullProgressMonitor(); @@ -49,23 +50,25 @@ public class ExternalToolInvoker { throws InvocationFailure, Throwable { Command command = commandBuilder.buildCommand(parameters, settings, argsSeparator); try { - launchCommand(command, parsers, parameters); + launchCommand(command, parsers, parameters, settings); } finally { shutDown(parsers); } } private void launchCommand(Command command, IConsoleParser[] parsers, - InvocationParameters parameters) throws InvocationFailure, CoreException { + InvocationParameters parameters, ConfigurationSettings settings) + throws InvocationFailure, CoreException { IProject project = parameters.getActualFile().getProject(); - IConsole c = startConsole(project); + IConsole c = startConsole(project, settings.getExternalToolName()); ConsoleOutputSniffer sniffer = new ConsoleOutputSniffer(c.getOutputStream(), c.getErrorStream(), parsers); ICommandLauncher launcher = commandLauncher(project); Process p = launcher.execute(command.getPath(), command.getArgs(), ENV, parameters.getWorkingDirectory(), NULL_PROGRESS_MONITOR); if (p == null) { - throw new InvocationFailure("Unable to launch external tool. Cause unknown."); //$NON-NLS-1$ + String format = "Unable to launch external tool '%s'. Cause unknown."; //$NON-NLS-1$ + throw new InvocationFailure(String.format(format, settings.getExternalToolName())); } try { p.getOutputStream().close(); @@ -77,8 +80,8 @@ public class ExternalToolInvoker { } } - private IConsole startConsole(IProject project) { - IConsole console = CCorePlugin.getDefault().getConsole(); + private IConsole startConsole(IProject project, String externalToolName) { + IConsole console = CCorePlugin.getDefault().getConsole(null, DEFAULT_CONTEXT_MENU_ID, externalToolName, null); console.start(project); return console; } diff --git a/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/CodanPartListener.java b/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/CodanPartListener.java new file mode 100644 index 00000000000..1e1105fe927 --- /dev/null +++ b/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/CodanPartListener.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2009, 2012 Alena Laskavaia 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: + * Alena Laskavaia - initial API and implementation + * Alex Ruiz (Google) + * Sergey Prigogin (Google) + *******************************************************************************/ +package org.eclipse.cdt.codan.internal.ui.cxx; + +import org.eclipse.cdt.codan.core.model.CheckerLaunchMode; +import org.eclipse.cdt.codan.internal.core.CodanRunner; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.ui.editor.CEditor; +import org.eclipse.cdt.internal.ui.editor.IPostSaveListener; +import org.eclipse.cdt.ui.ICEditor; +import org.eclipse.core.resources.IResource; +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; +import org.eclipse.osgi.util.NLS; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartReference; + +/** + * Enables Codan's "run as you type", "run on file save" and "run on file open" launch modes. + */ +class CodanPartListener implements IPartListener2 { + private CodanCReconciler reconciler; + private IPostSaveListener postSaveListener; + + @Override + public void partActivated(IWorkbenchPartReference partRef) { + } + + @Override + public void partDeactivated(IWorkbenchPartReference partRef) { + } + + @Override + public void partOpened(IWorkbenchPartReference partRef) { + IWorkbenchPart part = partRef.getPart(false); + if (isCEditor(part)) { + CEditor editor = (CEditor) part; + if (reconciler == null) { + reconciler = new CodanCReconciler(); + } + reconciler.install(editor); + if (postSaveListener == null) { + postSaveListener = new IPostSaveListener() { + @Override + public void saved(ITranslationUnit translationUnit, IProgressMonitor monitor) { + processResource(translationUnit.getResource(), CheckerLaunchMode.RUN_ON_FILE_SAVE); + } + }; + } + editor.addPostSaveListener(postSaveListener); + IResource resource = (IResource) editor.getEditorInput().getAdapter(IResource.class); + processResource(resource, CheckerLaunchMode.RUN_ON_FILE_OPEN); + } + } + + private void processResource(final IResource resource, final CheckerLaunchMode launchMode) { + if (resource != null) { + Job job = new Job(NLS.bind(Messages.Startup_AnalyzingFile, resource.getName())) { + @Override + protected IStatus run(IProgressMonitor monitor) { + CodanRunner.processResource(resource, launchMode, monitor); + return Status.OK_STATUS; + } + }; + job.setRule(resource); + job.setSystem(true); + job.schedule(); + } + } + + @Override + public void partHidden(IWorkbenchPartReference partRef) { + } + + @Override + public void partVisible(IWorkbenchPartReference partRef) { + } + + @Override + public void partClosed(IWorkbenchPartReference partRef) { + IWorkbenchPart part = partRef.getPart(false); + if (reconciler != null && isCEditor(part)) { + reconciler.uninstall((CEditor) part); + } + } + + private boolean isCEditor(IWorkbenchPart part) { + // We need to be very careful since this code may be executed in an environment where CDT is + // installed, but is not actively used. + // By checking for ICEditor first we avoid loading CEditor class if the part is not a C/C++ + // editor. Loading of CEditor class can be very expensive since it triggers loading of many + // other classes. + return part instanceof ICEditor && part instanceof CEditor; + } + + @Override + public void partBroughtToTop(IWorkbenchPartReference partRef) { + } + + @Override + public void partInputChanged(IWorkbenchPartReference partRef) { + } +} \ No newline at end of file diff --git a/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Startup.java b/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Startup.java index 675ddcc4990..c31956a4aa3 100644 --- a/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Startup.java +++ b/codan/org.eclipse.cdt.codan.ui.cxx/src/org/eclipse/cdt/codan/internal/ui/cxx/Startup.java @@ -12,23 +12,10 @@ *******************************************************************************/ package org.eclipse.cdt.codan.internal.ui.cxx; -import org.eclipse.cdt.codan.core.model.CheckerLaunchMode; -import org.eclipse.cdt.codan.internal.core.CodanRunner; -import org.eclipse.cdt.internal.ui.editor.CEditor; -import org.eclipse.cdt.ui.ICEditor; -import org.eclipse.core.resources.IResource; -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; -import org.eclipse.osgi.util.NLS; import org.eclipse.ui.IEditorReference; -import org.eclipse.ui.IPartListener2; import org.eclipse.ui.IStartup; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; @@ -51,80 +38,10 @@ public class Startup implements IStartup { public void run() { IWorkbenchWindow active = workbench.getActiveWorkbenchWindow(); final IWorkbenchPage page = active.getActivePage(); - IPartListener2 partListener = new IPartListener2() { - CodanCReconciler reconciler; - - @Override - public void partActivated(IWorkbenchPartReference partRef) { - } - - @Override - public void partDeactivated(IWorkbenchPartReference partRef) { - } - - @Override - public void partOpened(IWorkbenchPartReference partRef) { - IWorkbenchPart part = partRef.getPart(false); - // We need to be very careful since this code may be executed in - // an invironement where CDT is installed, but is not actively used. - // By checking for ICEditor first we avoid loading CEditor class if - // the part is not a C/C++ editor. Loading of CEditor class can be very - // expensive since it triggers loading of many other classes. - if (part instanceof ICEditor && part instanceof CEditor) { - CEditor editor = (CEditor) part; - if (reconciler == null) { - reconciler = new CodanCReconciler(); - } - reconciler.install(editor); - IResource resource = (IResource) editor.getEditorInput().getAdapter(IResource.class); - if (resource != null) { - processResource(resource); - } - } - } - - private void processResource(final IResource resource) { - Job job = new Job(NLS.bind(Messages.Startup_AnalyzingFile, resource.getName())) { - @Override - protected IStatus run(IProgressMonitor monitor) { - CodanRunner.processResource(resource, CheckerLaunchMode.RUN_ON_FILE_OPEN, monitor); - return Status.OK_STATUS; - } - }; - job.setRule(resource); - job.setSystem(true); - job.schedule(); - } - - @Override - public void partHidden(IWorkbenchPartReference partRef) { - } - - @Override - public void partVisible(IWorkbenchPartReference partRef) { - } - - @Override - public void partClosed(IWorkbenchPartReference partRef) { - IWorkbenchPart part = partRef.getPart(false); - if (reconciler != null && part instanceof ICEditor && part instanceof CEditor) { - reconciler.uninstall((CEditor) part); - } - } - - @Override - public void partBroughtToTop(IWorkbenchPartReference partRef) { - } - - @Override - public void partInputChanged(IWorkbenchPartReference partRef) { - } - }; - + CodanPartListener partListener = new CodanPartListener(); page.addPartListener(partListener); // Check current open editors. - IEditorReference[] editorReferences = page.getEditorReferences(); - for (IEditorReference ref : editorReferences) { + for (IEditorReference ref : page.getEditorReferences()) { partListener.partOpened(ref); } } diff --git a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/LaunchModesPropertyPage.java b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/LaunchModesPropertyPage.java index b703df8bc80..3986d653b6e 100644 --- a/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/LaunchModesPropertyPage.java +++ b/codan/org.eclipse.cdt.codan.ui/src/org/eclipse/cdt/codan/internal/ui/preferences/LaunchModesPropertyPage.java @@ -54,13 +54,17 @@ public class LaunchModesPropertyPage extends FieldEditorPreferencePage { @Override protected void createFieldEditors() { if (runInEditor) { - addField(new BooleanFieldEditor(CheckerLaunchMode.RUN_AS_YOU_TYPE.name(), CodanUIMessages.LaunchModesPropertyPage_RunAsYouType, getFieldEditorParent())); + addEditor(CheckerLaunchMode.RUN_AS_YOU_TYPE, CodanUIMessages.LaunchModesPropertyPage_RunAsYouType); } - addField(new BooleanFieldEditor(CheckerLaunchMode.RUN_ON_FILE_OPEN.name(), CodanUIMessages.LaunchModesPropertyPage_RunOnFileOpen, getFieldEditorParent())); - addField(new BooleanFieldEditor(CheckerLaunchMode.RUN_ON_FILE_SAVE.name(), CodanUIMessages.LaunchModesPropertyPage_RunOnFileSave, getFieldEditorParent())); - addField(new BooleanFieldEditor(CheckerLaunchMode.RUN_ON_INC_BUILD.name(), CodanUIMessages.LaunchModesPropertyPage_RunOnIncrementalBuild, getFieldEditorParent())); - addField(new BooleanFieldEditor(CheckerLaunchMode.RUN_ON_FULL_BUILD.name(), CodanUIMessages.LaunchModesPropertyPage_RunOnFullBuild, getFieldEditorParent())); - addField(new BooleanFieldEditor(CheckerLaunchMode.RUN_ON_DEMAND.name(), CodanUIMessages.LaunchModesPropertyPage_RunOnDemand, getFieldEditorParent())); + addEditor(CheckerLaunchMode.RUN_ON_FILE_OPEN, CodanUIMessages.LaunchModesPropertyPage_RunOnFileOpen); + addEditor(CheckerLaunchMode.RUN_ON_FILE_SAVE, CodanUIMessages.LaunchModesPropertyPage_RunOnFileSave); + addEditor(CheckerLaunchMode.RUN_ON_INC_BUILD, CodanUIMessages.LaunchModesPropertyPage_RunOnIncrementalBuild); + addEditor(CheckerLaunchMode.RUN_ON_FULL_BUILD, CodanUIMessages.LaunchModesPropertyPage_RunOnFullBuild); + addEditor(CheckerLaunchMode.RUN_ON_DEMAND, CodanUIMessages.LaunchModesPropertyPage_RunOnDemand); + } + + private void addEditor(CheckerLaunchMode launchMode, String label) { + addField(new BooleanFieldEditor(launchMode.name(), label, getFieldEditorParent())); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java index ecfd7b7c4f2..7af2137518f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerPreferences.java @@ -8,6 +8,7 @@ * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) + * Anton Gorenkov - Enable the "Index unused headers" preference by default (Bug 377992) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.indexer; @@ -317,7 +318,7 @@ public class IndexerPreferences { Preferences prefs= defaultPreferences.node(INDEXER_NODE); prefs.put(KEY_INDEXER_ID, IPDOMManager.ID_FAST_INDEXER); prefs.putBoolean(KEY_INDEX_ALL_FILES, true); - prefs.putBoolean(KEY_INDEX_UNUSED_HEADERS_WITH_DEFAULT_LANG, false); + prefs.putBoolean(KEY_INDEX_UNUSED_HEADERS_WITH_DEFAULT_LANG, true); prefs.putBoolean(KEY_INDEX_UNUSED_HEADERS_WITH_ALTERNATE_LANG, false); prefs.putBoolean(KEY_INDEX_ON_OPEN, false); prefs.putBoolean(KEY_INCLUDE_HEURISTICS, true); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java index 934f4518fc3..5616c0e569a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java @@ -1413,6 +1413,8 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi private final IndexerPreferenceListener fIndexerPreferenceListener; + private final ListenerList fPostSaveListeners; + private static final Set angularIntroducers = new HashSet(); static { angularIntroducers.add("template"); //$NON-NLS-1$ @@ -1449,6 +1451,7 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi fCEditorErrorTickUpdater = new CEditorErrorTickUpdater(this); fIndexerPreferenceListener = new IndexerPreferenceListener(); + fPostSaveListeners = new ListenerList(); } /** @@ -3766,4 +3769,29 @@ public class CEditor extends TextEditor implements ICEditor, ISelectionChangedLi }}); } } + + @Override + protected void editorSaved() { + super.editorSaved(); + ITranslationUnit translationUnit = getInputCElement().getOriginalElement(); + if (translationUnit != null) { + for (Object listener : fPostSaveListeners.getListeners()) { + ((IPostSaveListener) listener).saved(translationUnit, getProgressMonitor()); + } + } + } + + /** + * @since 5.4 + */ + public void addPostSaveListener(IPostSaveListener listener) { + fPostSaveListeners.add(listener); + } + + /** + * @since 5.4 + */ + public void removePostSaveListener(IPostSaveListener listener) { + fPostSaveListeners.remove(listener); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IPostSaveListener.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IPostSaveListener.java new file mode 100644 index 00000000000..94623018d1f --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IPostSaveListener.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2012 Google, Inc 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: + * Alex Ruiz (Google) - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.editor; + +import org.eclipse.core.runtime.IProgressMonitor; + +import org.eclipse.cdt.core.model.ITranslationUnit; + +/** + * Listener that is informed when a translation unit is saved. + *

+ * The difference between this interface and JDT's {@code IPostSaveListener} is that CDT does not + * allow post-save listeners to make changes to the saved file. + *

+ * + * @since 5.4 + */ +public interface IPostSaveListener { + /** + * Informs this post-save listener that the given translation unit has been saved. The listener + * should not modify the given translation unit. + * + * @param translationUnit the translation unit which was saved + * @param monitor the progress monitor for reporting progress + */ + void saved(ITranslationUnit translationUnit, IProgressMonitor monitor); +} diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index 64a8096db78..16b824cf325 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -2367,7 +2367,7 @@ label="%StartTracing.name" style="push"> - + - +