From 0442fec7c535124fb60f412c9c499ee11eaea5ea Mon Sep 17 00:00:00 2001 From: wuestholz Date: Sun, 14 Jul 2013 17:53:26 -0700 Subject: DafnyExtension: Worked on integrating BVD. --- Source/DafnyExtension/ProgressMargin.cs | 61 ++++++++++-------- Source/DafnyExtension/ResolverTagger.cs | 41 +++++++----- Source/DafnyMenu/BvdToolWindow.cs | 59 ++++++++++++++++++ Source/DafnyMenu/DafnyMenu.csproj | 22 +++++-- Source/DafnyMenu/DafnyMenu.vsct | 10 +++ Source/DafnyMenu/DafnyMenuPackage.cs | 106 ++++++++++++++++++++++++-------- Source/DafnyMenu/Guids.cs | 6 ++ Source/DafnyMenu/PkgCmdID.cs | 3 +- Source/DafnyMenu/Resources.Designer.cs | 2 +- Source/DafnyMenu/Resources/Images.png | Bin 989 -> 0 bytes Source/DafnyMenu/Resources/Package.ico | Bin 2998 -> 0 bytes Source/DafnyMenu/VSPackage.resx | 14 ----- 12 files changed, 234 insertions(+), 90 deletions(-) create mode 100644 Source/DafnyMenu/BvdToolWindow.cs delete mode 100644 Source/DafnyMenu/Resources/Images.png delete mode 100644 Source/DafnyMenu/Resources/Package.ico (limited to 'Source') diff --git a/Source/DafnyExtension/ProgressMargin.cs b/Source/DafnyExtension/ProgressMargin.cs index 6ee12d95..8f4a22a2 100644 --- a/Source/DafnyExtension/ProgressMargin.cs +++ b/Source/DafnyExtension/ProgressMargin.cs @@ -96,6 +96,7 @@ namespace DafnyLanguage ErrorListProvider _errorProvider; ITextBuffer _buffer; ITextDocument _document; + private bool m_disposed; readonly DispatcherTimer timer; @@ -126,31 +127,34 @@ namespace DafnyLanguage private void Dispose(bool disposing) { - if (!m_disposed) + lock (this) { - if (disposing) + if (!m_disposed) { - if (lastRequestId != null) - { - Microsoft.Boogie.ExecutionEngine.CancelRequest(lastRequestId); - } - if (_document.FilePath != null) + if (disposing) { - ProgressTaggers.Remove(_document.FilePath); - } - _buffer.Changed -= buffer_Changed; - timer.Tick -= UponIdle; - _errorProvider.Dispose(); - _errorProvider = null; - ClearCachedVerificationResults(); - if (resolver != null) - { - resolver.Dispose(); - resolver = null; + if (lastRequestId != null) + { + Microsoft.Boogie.ExecutionEngine.CancelRequest(lastRequestId); + } + if (_document.FilePath != null) + { + ProgressTaggers.Remove(_document.FilePath); + } + _buffer.Changed -= buffer_Changed; + timer.Tick -= UponIdle; + _errorProvider.Dispose(); + _errorProvider = null; + ClearCachedVerificationResults(); + if (resolver != null) + { + resolver.Dispose(); + resolver = null; + } } - } - m_disposed = true; + m_disposed = true; + } } } @@ -320,14 +324,17 @@ namespace DafnyLanguage { bool success = DafnyDriver.Verify(program, errorListHolder, GetHashCode().ToString(), requestId, errorInfo => { - errorInfo.BoogieErrorCode = null; - if (errorInfo.RequestId != null && RequestIdToSnapshot.ContainsKey(errorInfo.RequestId)) + if (!m_disposed) { - var s = RequestIdToSnapshot[errorInfo.RequestId]; - errorListHolder.AddError(new DafnyError(errorInfo.Tok.line - 1, errorInfo.Tok.col - 1, ErrorCategory.VerificationError, errorInfo.FullMsg, s, errorInfo.Model.ToString()), errorInfo.ImplementationName, requestId); - foreach (var aux in errorInfo.Aux) + errorInfo.BoogieErrorCode = null; + if (errorInfo.RequestId != null && RequestIdToSnapshot.ContainsKey(errorInfo.RequestId)) { - errorListHolder.AddError(new DafnyError(aux.Tok.line - 1, aux.Tok.col - 1, ErrorCategory.AuxInformation, aux.FullMsg, s), errorInfo.ImplementationName, requestId); + var s = RequestIdToSnapshot[errorInfo.RequestId]; + errorListHolder.AddError(new DafnyError(errorInfo.Tok.line - 1, errorInfo.Tok.col - 1, ErrorCategory.VerificationError, errorInfo.FullMsg, s, errorInfo.Model.ToString()), errorInfo.ImplementationName, requestId); + foreach (var aux in errorInfo.Aux) + { + errorListHolder.AddError(new DafnyError(aux.Tok.line - 1, aux.Tok.col - 1, ErrorCategory.AuxInformation, aux.FullMsg, s), errorInfo.ImplementationName, requestId); + } } } }); @@ -357,7 +364,7 @@ namespace DafnyLanguage } public event EventHandler TagsChanged; - private bool m_disposed; + IEnumerable> ITagger.GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) yield break; var targetSnapshot = spans[0].Snapshot; diff --git a/Source/DafnyExtension/ResolverTagger.cs b/Source/DafnyExtension/ResolverTagger.cs index 4f5f70fb..aad7217c 100644 --- a/Source/DafnyExtension/ResolverTagger.cs +++ b/Source/DafnyExtension/ResolverTagger.cs @@ -89,6 +89,7 @@ namespace DafnyLanguage readonly ITextBuffer _buffer; readonly ITextDocument _document; ErrorListProvider _errorProvider; + private bool m_disposed; // The 'Snapshot' and 'Program' fields should be updated and read together, so they are protected by "this" public ITextSnapshot Snapshot; // may be null @@ -172,7 +173,7 @@ namespace DafnyLanguage } } - public static readonly IDictionary Programs = new ConcurrentDictionary(); + public static readonly IDictionary ResolverTaggers = new ConcurrentDictionary(); internal ResolverTagger(ITextBuffer buffer, IServiceProvider serviceProvider, ITextDocumentFactoryService textDocumentFactory) { @@ -193,27 +194,34 @@ namespace DafnyLanguage private void Dispose(bool disposing) { - if (!m_disposed) + lock (this) { - if (disposing) + if (!m_disposed) { - if (_errorProvider != null) + if (disposing) { - try + if (_errorProvider != null) { - _errorProvider.Tasks.Clear(); + try + { + _errorProvider.Tasks.Clear(); + } + catch (InvalidOperationException) + { + // this may occur if the SVsServiceProvider somehow has been uninstalled before our Dispose method is called + } + _errorProvider.Dispose(); + _errorProvider = null; } - catch (InvalidOperationException) + BufferIdleEventUtil.RemoveBufferIdleEventListener(_buffer, ResolveBuffer); + if (_document != null) { - // this may occur if the SVsServiceProvider somehow has been uninstalled before our Dispose method is called + ResolverTaggers.Remove(_document.FilePath); } - _errorProvider.Dispose(); - _errorProvider = null; } - BufferIdleEventUtil.RemoveBufferIdleEventListener(_buffer, ResolveBuffer); - } - m_disposed = true; + m_disposed = true; + } } } @@ -262,7 +270,6 @@ namespace DafnyLanguage } public event EventHandler TagsChanged; - private bool m_disposed; /// /// Calls the Dafny parser/resolver/type checker on the contents of the buffer, updates the Error List accordingly. @@ -295,11 +302,11 @@ namespace DafnyLanguage if (program != null && _document != null) { - Programs[_document.FilePath] = program; + ResolverTaggers[_document.FilePath] = this; } else if (_document != null) { - Programs.Remove(_document.FilePath); + ResolverTaggers.Remove(_document.FilePath); } _resolutionErrors = newErrors; @@ -311,7 +318,7 @@ namespace DafnyLanguage { lock (this) { - if (_errorProvider != null) + if (_errorProvider != null && !m_disposed) { _errorProvider.SuspendRefresh(); // reduce flickering _errorProvider.Tasks.Clear(); diff --git a/Source/DafnyMenu/BvdToolWindow.cs b/Source/DafnyMenu/BvdToolWindow.cs new file mode 100644 index 00000000..0316d558 --- /dev/null +++ b/Source/DafnyMenu/BvdToolWindow.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Windows; +using System.Runtime.InteropServices; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Shell; + +namespace DafnyLanguage.DafnyMenu +{ + /// + /// This class implements the tool window exposed by this package and hosts a user control. + /// + /// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane, + /// usually implemented by the package implementer. + /// + /// This class derives from the ToolWindowPane class provided from the MPF in order to use its + /// implementation of the IVsUIElementPane interface. + /// + [Guid(GuidList.guidToolWindowPersistanceString)] + public class BvdToolWindow : ToolWindowPane + { + private static readonly Lazy bvdInstance = new Lazy(() => new Microsoft.Boogie.ModelViewer.Main(new string[] { }, true)); + + /// + /// Standard constructor for the tool window. + /// + public BvdToolWindow() : + base(null) + { + // Set the window title reading it from the resources. + this.Caption = "Boogie Verification Debugger"; + // Set the image that will appear on the tab of the window frame + // when docked with an other window + // The resource ID correspond to the one defined in the resx file + // while the Index is the offset in the bitmap strip. Each image in + // the strip being 16x16. + // this.BitmapResourceID = 301; + // this.BitmapIndex = 1; + + // This is the user control hosted by the tool window; Note that, even if this class implements IDisposable, + // we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on + // the object returned by the Content property. + // base.Content = new MyControl(); + } + + public override System.Windows.Forms.IWin32Window Window + { + get { return bvdInstance.Value; } + } + + public static Microsoft.Boogie.ModelViewer.Main BVD + { + get { return bvdInstance.Value; } + } + } +} diff --git a/Source/DafnyMenu/DafnyMenu.csproj b/Source/DafnyMenu/DafnyMenu.csproj index 6cd493c6..7fb6cfab 100644 --- a/Source/DafnyMenu/DafnyMenu.csproj +++ b/Source/DafnyMenu/DafnyMenu.csproj @@ -52,13 +52,23 @@ + + True + + + ..\..\..\boogie\Binaries\ModelViewer.dll + + + + + @@ -72,6 +82,7 @@ + True @@ -92,6 +103,7 @@ true VSPackage + Designer @@ -102,20 +114,18 @@ Menus.ctmenu + Designer - - - - - - {6e9a5e14-0763-471c-a129-80a879d9e7ba} DafnyExtension + + + true diff --git a/Source/DafnyMenu/DafnyMenu.vsct b/Source/DafnyMenu/DafnyMenu.vsct index 5cb2975d..25c8dea9 100644 --- a/Source/DafnyMenu/DafnyMenu.vsct +++ b/Source/DafnyMenu/DafnyMenu.vsct @@ -103,6 +103,15 @@ + + @@ -133,6 +142,7 @@ +