Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/RetailCoder.VBE/App.cs b/RetailCoder.VBE/App.cs
- index 69dbf04..1180eb8 100644
- --- a/RetailCoder.VBE/App.cs
- +++ b/RetailCoder.VBE/App.cs
- @@ -1,6 +1,7 @@
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- +using System.Diagnostics;
- using System.Globalization;
- using System.Linq;
- using System.Runtime.InteropServices;
- @@ -8,10 +9,13 @@ using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using Microsoft.Vbe.Interop;
- +using Nito.AsyncEx;
- using NLog;
- using Rubberduck.Common;
- using Rubberduck.Inspections;
- using Rubberduck.Parsing;
- +using Rubberduck.Parsing.Symbols;
- +using Rubberduck.Parsing.VBA;
- using Rubberduck.Settings;
- using Rubberduck.UI;
- using Rubberduck.UI.Command.MenuItems;
- @@ -36,8 +40,8 @@ namespace Rubberduck
- private Configuration _config;
- - private readonly ConcurrentDictionary<VBComponent, CancellationTokenSource> _tokenSources =
- - new ConcurrentDictionary<VBComponent, CancellationTokenSource>();
- + //private readonly ConcurrentDictionary<VBComponent, CancellationTokenSource> _tokenSources =
- + // new ConcurrentDictionary<VBComponent, CancellationTokenSource>();
- public App(VBE vbe, IMessageBox messageBox,
- IParserErrorsPresenterFactory parserErrorsPresenterFactory,
- @@ -67,7 +71,7 @@ namespace Rubberduck
- private void _stateBar_Refresh(object sender, EventArgs e)
- {
- - Task.Run(() => ParseAll());
- + //Task.Run(() => ParseAll());
- }
- private void Parser_StateChanged(object sender, EventArgs e)
- @@ -77,38 +81,86 @@ namespace Rubberduck
- private async void _hook_KeyPressed(object sender, KeyHookEventArgs e)
- {
- - await ParseComponentAsync(e.Component);
- + try
- + {
- + await ParseComponentAsync(e.Component, resolve: true);
- + }
- + catch (SyntaxErrorException ex)
- + {
- + Debug.WriteLine(ex.Message);
- + }
- + finally
- + {
- + _parser.State.SetModuleState(e.Component, ParserState.Ready);
- + }
- }
- + //private readonly Dictionary<VBComponent, Task> _parseTasks = new Dictionary<VBComponent, Task>();
- +
- + private readonly AsyncLock _lock = new AsyncLock();
- +
- + private CancellationTokenSource _cancellationTokenSource;
- +
- + private Task _parseTask;
- +
- private async Task ParseComponentAsync(VBComponent component, bool resolve = true)
- {
- - var tokenSource = RenewTokenSource(component);
- + _cancellationTokenSource?.Cancel();
- - var token = tokenSource.Token;
- - await _parser.ParseAsync(component, token);
- + using (await _lock.LockAsync())
- + {
- + _cancellationTokenSource = new CancellationTokenSource();
- + _parseTask = ParseTaskHelper(component, resolve, _cancellationTokenSource.Token);
- + }
- - if (resolve && !token.IsCancellationRequested)
- + try
- {
- - using (var source = new CancellationTokenSource())
- - {
- - _parser.Resolve(source.Token);
- - }
- + await _parseTask;
- + }
- + catch (OperationCanceledException e)
- + {
- + Debug.WriteLine(e.Message);
- }
- }
- - private CancellationTokenSource RenewTokenSource(VBComponent component)
- + private async Task ParseTaskHelper(VBComponent component, bool resolve, CancellationToken cancellationToken)
- {
- - if (_tokenSources.ContainsKey(component))
- + try
- {
- - CancellationTokenSource existingTokenSource;
- - _tokenSources.TryRemove(component, out existingTokenSource);
- - existingTokenSource.Cancel();
- - existingTokenSource.Dispose();
- + if (_parseTask != null)
- + {
- + await _parseTask;
- + }
- }
- + catch (OperationCanceledException)
- + {
- + }
- + catch (Exception e)
- + {
- + Debugger.Break();
- + }
- +
- + //cancellationToken.ThrowIfCancellationRequested();
- - var tokenSource = new CancellationTokenSource();
- - _tokenSources[component] = tokenSource;
- - return tokenSource;
- + try
- + {
- + // Parse is a long-running, blocking, CPU-bound operation.
- + // Offload the work to the thread pool to keep the UI responsive.
- + await Task.Run(() => _parser.Parse(component, cancellationToken), cancellationToken);
- +
- + //if (resolve)
- + //{
- + // cancellationToken.ThrowIfCancellationRequested();
- + // await Task.Run(() => _parser.Resolve(cancellationToken), cancellationToken);
- + //}
- + }
- + catch (OperationCanceledException)
- + {
- + }
- + catch (Exception e)
- + {
- + //Debugger.Break();
- + }
- }
- public void Startup()
- @@ -132,15 +184,15 @@ namespace Rubberduck
- var components = _vbe.VBProjects.Cast<VBProject>()
- .SelectMany(project => project.VBComponents.Cast<VBComponent>());
- - var result = Parallel.ForEach(components, async component => { await ParseComponentAsync(component, false); });
- + //var result = Parallel.ForEach(components, component => ParseComponentAsync(component, false));
- - if (result.IsCompleted)
- - {
- - using (var tokenSource = new CancellationTokenSource())
- - {
- - _parser.Resolve(tokenSource.Token);
- - }
- - }
- + //if (result.IsCompleted)
- + //{
- + // using (var tokenSource = new CancellationTokenSource())
- + // {
- + // _parser.Resolve(tokenSource.Token);
- + // }
- + //}
- }
- private void CleanReloadConfig()
- @@ -186,14 +238,14 @@ namespace Rubberduck
- _configService.SettingsChanged -= _configService_SettingsChanged;
- _parser.State.StateChanged -= Parser_StateChanged;
- - if (_tokenSources.Any())
- - {
- - foreach (var tokenSource in _tokenSources)
- - {
- - tokenSource.Value.Cancel();
- - tokenSource.Value.Dispose();
- - }
- - }
- + //if (_tokenSources.Any())
- + //{
- + // foreach (var tokenSource in _tokenSources)
- + // {
- + // tokenSource.Value.Cancel();
- + // tokenSource.Value.Dispose();
- + // }
- + //}
- }
- }
- }
- diff --git a/RetailCoder.VBE/Common/KeyHook.cs b/RetailCoder.VBE/Common/KeyHook.cs
- index cb2b15d..df6254d 100644
- --- a/RetailCoder.VBE/Common/KeyHook.cs
- +++ b/RetailCoder.VBE/Common/KeyHook.cs
- @@ -1,7 +1,9 @@
- using System;
- +using System.Collections.Concurrent;
- using System.Diagnostics;
- using System.Linq;
- using System.Runtime.InteropServices;
- +using System.Threading;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using Microsoft.Vbe.Interop;
- @@ -20,17 +22,13 @@ namespace Rubberduck.Common
- private readonly VBE _vbe;
- // reference: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx
- - private const int WH_KEYBOARD_LL = 13;
- - private const int WM_KEYDOWN = 0x0100;
- - private const int WM_KEYUP = 0x0101;
- -
- - private readonly LowLevelKeyboardProc _proc;
- + private readonly HookProcedure _proc;
- private static IntPtr HookId = IntPtr.Zero;
- - private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
- + private delegate IntPtr HookProcedure(int nCode, IntPtr wParam, IntPtr lParam);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- - private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
- + private static extern IntPtr SetWindowsHookEx(int idHook, HookProcedure lpfn, IntPtr hMod, uint dwThreadId);
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- [return: MarshalAs(UnmanagedType.Bool)]
- @@ -39,22 +37,14 @@ namespace Rubberduck.Common
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
- - [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
- - private static extern IntPtr GetModuleHandle(string lpModuleName);
- -
- - [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
- - private static extern IntPtr GetForegroundWindow();
- -
- - [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
- - private static extern IntPtr GetWindowThreadProcessId(IntPtr handle, out int processID);
- + [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
- + public static extern int GetCurrentThreadId();
- - private static IntPtr SetHook(LowLevelKeyboardProc proc)
- + private static IntPtr SetHook(HookProcedure procedure)
- {
- - using (var curProcess = Process.GetCurrentProcess())
- - using (var curModule = curProcess.MainModule)
- - {
- - return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
- - }
- + const int WH_KEYBOARD = 2;
- + var threadId = (uint)GetCurrentThreadId();
- + return SetWindowsHookEx(WH_KEYBOARD, procedure, IntPtr.Zero, threadId);
- }
- private static readonly Keys[] IgnoredKeys =
- @@ -79,30 +69,46 @@ namespace Rubberduck.Common
- Keys.RControlKey,
- };
- - private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
- + private readonly BlockingCollection<Keys> _keys = new BlockingCollection<Keys>(new ConcurrentQueue<Keys>());
- +
- + private void ConsumeKeys()
- {
- - var vkCode = Marshal.ReadInt32(lParam);
- - var key = (Keys)vkCode;
- + foreach (var key in _keys.GetConsumingEnumerable())
- + {
- + if (IgnoredKeys.Contains(key))
- + {
- + continue;
- + }
- +
- + VBComponent component;
- + try
- + {
- + component = _vbe.ActiveCodePane?.CodeModule?.Parent;
- + }
- + catch (COMException)
- + {
- + continue;
- + }
- +
- + if (component == null)
- + {
- + continue;
- + }
- - var windowHandle = GetForegroundWindow();
- - var vbeWindow = _vbe.MainWindow.HWnd;
- - var codePane = _vbe.ActiveCodePane;
- + OnKeyPressed(new KeyHookEventArgs(key, component));
- + }
- + }
- - Task.Run(() =>
- + private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
- + {
- + if (nCode >= 0)
- {
- - if (windowHandle != (IntPtr) vbeWindow
- - || wParam != (IntPtr) WM_KEYUP
- - || nCode < 0
- - || codePane == null
- - || IgnoredKeys.Contains(key))
- + if (((int) lParam & (1 << 31)) != 0)
- {
- - return;
- + var key = (Keys) wParam;
- + _keys.Add(key);
- }
- -
- - var component = codePane.CodeModule.Parent;
- - var args = new KeyHookEventArgs(key, component);
- - OnKeyPressed(args);
- - });
- + }
- return CallNextHookEx(HookId, nCode, wParam, lParam);
- }
- @@ -115,11 +121,13 @@ namespace Rubberduck.Common
- public void Attach()
- {
- + new Thread(() => ConsumeKeys()).Start();
- HookId = SetHook(_proc);
- }
- public void Detach()
- {
- + _keys.CompleteAdding();
- UnhookWindowsHookEx(HookId);
- }
- diff --git a/RetailCoder.VBE/Rubberduck.csproj b/RetailCoder.VBE/Rubberduck.csproj
- index 07e333d..cd7574f 100644
- --- a/RetailCoder.VBE/Rubberduck.csproj
- +++ b/RetailCoder.VBE/Rubberduck.csproj
- @@ -237,6 +237,18 @@
- <Reference Include="Ninject.Extensions.NamedScope">
- <HintPath>..\packages\Ninject.Extensions.NamedScope.3.2.0.0\lib\net45-full\Ninject.Extensions.NamedScope.dll</HintPath>
- </Reference>
- + <Reference Include="Nito.AsyncEx, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
- + <HintPath>..\packages\Nito.AsyncEx.3.0.1\lib\net45\Nito.AsyncEx.dll</HintPath>
- + <Private>True</Private>
- + </Reference>
- + <Reference Include="Nito.AsyncEx.Concurrent, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
- + <HintPath>..\packages\Nito.AsyncEx.3.0.1\lib\net45\Nito.AsyncEx.Concurrent.dll</HintPath>
- + <Private>True</Private>
- + </Reference>
- + <Reference Include="Nito.AsyncEx.Enlightenment, Version=3.0.1.0, Culture=neutral, processorArchitecture=MSIL">
- + <HintPath>..\packages\Nito.AsyncEx.3.0.1\lib\net45\Nito.AsyncEx.Enlightenment.dll</HintPath>
- + <Private>True</Private>
- + </Reference>
- <Reference Include="PresentationCore" />
- <Reference Include="PresentationFramework" />
- <Reference Include="stdole, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
- diff --git a/RetailCoder.VBE/packages.config b/RetailCoder.VBE/packages.config
- index 51e53e7..98f4be8 100644
- --- a/RetailCoder.VBE/packages.config
- +++ b/RetailCoder.VBE/packages.config
- @@ -7,6 +7,7 @@
- <package id="Ninject.Extensions.Conventions" version="3.2.0.0" targetFramework="net45" />
- <package id="Ninject.Extensions.Factory" version="3.2.1.0" targetFramework="net45" />
- <package id="Ninject.Extensions.NamedScope" version="3.2.0.0" targetFramework="net45" />
- + <package id="Nito.AsyncEx" version="3.0.1" targetFramework="net45" />
- <package id="NLog" version="4.0.1" targetFramework="net45" />
- <package id="NLog.Schema" version="4.0.1" targetFramework="net45" />
- </packages>
- \ No newline at end of file
- diff --git a/Rubberduck.Parsing/IRubberduckParser.cs b/Rubberduck.Parsing/IRubberduckParser.cs
- index e175182..d683afc 100644
- --- a/Rubberduck.Parsing/IRubberduckParser.cs
- +++ b/Rubberduck.Parsing/IRubberduckParser.cs
- @@ -1,5 +1,4 @@
- using System.Threading;
- -using System.Threading.Tasks;
- using Microsoft.Vbe.Interop;
- using Rubberduck.Parsing.VBA;
- @@ -8,7 +7,7 @@ namespace Rubberduck.Parsing
- public interface IRubberduckParser
- {
- RubberduckParserState State { get; }
- - Task ParseAsync(VBComponent component, CancellationToken token);
- + void Parse(VBComponent component, CancellationToken token);
- void Resolve(CancellationToken token);
- }
- }
- \ No newline at end of file
- diff --git a/Rubberduck.Parsing/Symbols/Declaration.cs b/Rubberduck.Parsing/Symbols/Declaration.cs
- index 415115e..805c581 100644
- --- a/Rubberduck.Parsing/Symbols/Declaration.cs
- +++ b/Rubberduck.Parsing/Symbols/Declaration.cs
- @@ -319,6 +319,16 @@ namespace Rubberduck.Parsing.Symbols
- public bool Equals(Declaration other)
- {
- + if (object.ReferenceEquals(other, null))
- + {
- + return false;
- + }
- +
- + if (object.ReferenceEquals(other, this))
- + {
- + return true;
- + }
- +
- return other.Project == Project
- && other.IdentifierName == IdentifierName
- && other.DeclarationType == DeclarationType
- @@ -333,7 +343,29 @@ namespace Rubberduck.Parsing.Symbols
- public override int GetHashCode()
- {
- - return string.Concat(QualifiedName.QualifiedModuleName.ProjectHashCode, _identifierName, _declarationType, Scope, _parentScope).GetHashCode();
- + unchecked
- + {
- + var hash = 17;
- + if (Project != null)
- + {
- + hash = hash * 23 + Project.GetHashCode();
- + }
- + if (IdentifierName != null)
- + {
- + hash = hash * 23 + IdentifierName.GetHashCode();
- + }
- + hash = hash * 23 + DeclarationType.GetHashCode();
- + if (Scope != null)
- + {
- + hash = hash * 23 + Scope.GetHashCode();
- + }
- + if (ParentScope != null)
- + {
- + hash = hash * 23 + ParentScope.GetHashCode();
- + }
- + return hash;
- + }
- + //return string.Concat(QualifiedName.QualifiedModuleName.ProjectHashCode, _identifierName, _declarationType, Scope, _parentScope).GetHashCode();
- }
- }
- }
- diff --git a/Rubberduck.Parsing/VBA/RubberduckParser.cs b/Rubberduck.Parsing/VBA/RubberduckParser.cs
- index c1801dd..c022372 100644
- --- a/Rubberduck.Parsing/VBA/RubberduckParser.cs
- +++ b/Rubberduck.Parsing/VBA/RubberduckParser.cs
- @@ -1,7 +1,5 @@
- -using System;
- -using System.Collections.Generic;
- +using System.Collections.Generic;
- using System.Linq;
- -using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- @@ -33,24 +31,54 @@ namespace Rubberduck.Parsing.VBA
- private readonly RubberduckParserState _state;
- public RubberduckParserState State { get { return _state; } }
- - public async Task ParseAsync(VBComponent vbComponent, CancellationToken token)
- + public void Parse(VBComponent vbComponent, CancellationToken token)
- {
- - var component = vbComponent;
- + _state.ClearDeclarations(vbComponent, token);
- - var parseTask = Task.Run(() => ParseInternal(component, token), token);
- + token.ThrowIfCancellationRequested();
- - try
- - {
- - await parseTask;
- - }
- - catch (SyntaxErrorException exception)
- - {
- - State.SetModuleState(component, ParserState.Error, exception);
- - }
- - catch (OperationCanceledException)
- + State.SetModuleState(vbComponent, ParserState.Parsing);
- +
- + var qualifiedName = new QualifiedModuleName(vbComponent);
- + _state.SetModuleComments(vbComponent, ParseComments(qualifiedName));
- +
- + var obsoleteCallsListener = new ObsoleteCallStatementListener();
- + var obsoleteLetListener = new ObsoleteLetStatementListener();
- +
- + var listeners = new IParseTreeListener[]
- {
- - // no need to blow up
- - }
- + obsoleteCallsListener,
- + obsoleteLetListener
- + };
- +
- + token.ThrowIfCancellationRequested();
- +
- + ITokenStream stream;
- + var code = string.Join("\r\n", vbComponent.CodeModule.Code());
- + var tree = ParseInternal(code, listeners, out stream);
- +
- + token.ThrowIfCancellationRequested();
- + _state.AddTokenStream(vbComponent, stream);
- + _state.AddParseTree(vbComponent, tree);
- +
- + // cannot locate declarations in one pass *the way it's currently implemented*,
- + // because the context in EnterSubStmt() doesn't *yet* have child nodes when the context enters.
- + // so we need to EnterAmbiguousIdentifier() and evaluate the parent instead - this *might* work.
- + var declarationsListener = new DeclarationSymbolsListener(qualifiedName, Accessibility.Implicit, vbComponent.Type, _state.Comments, token);
- +
- + token.ThrowIfCancellationRequested();
- + declarationsListener.NewDeclaration += declarationsListener_NewDeclaration;
- + declarationsListener.CreateModuleDeclarations();
- +
- + token.ThrowIfCancellationRequested();
- + var walker = new ParseTreeWalker();
- + walker.Walk(declarationsListener, tree);
- + declarationsListener.NewDeclaration -= declarationsListener_NewDeclaration;
- +
- + _state.ObsoleteCallContexts = obsoleteCallsListener.Contexts.Select(context => new QualifiedContext(qualifiedName, context));
- + _state.ObsoleteLetContexts = obsoleteLetListener.Contexts.Select(context => new QualifiedContext(qualifiedName, context));
- +
- + State.SetModuleState(vbComponent, ParserState.Parsed);
- }
- public void Resolve(CancellationToken token)
- @@ -104,53 +132,6 @@ namespace Rubberduck.Parsing.VBA
- }
- }
- - private void ParseInternal(VBComponent vbComponent, CancellationToken token)
- - {
- - _state.ClearDeclarations(vbComponent);
- - State.SetModuleState(vbComponent, ParserState.Parsing);
- -
- - var qualifiedName = new QualifiedModuleName(vbComponent);
- - _state.SetModuleComments(vbComponent, ParseComments(qualifiedName));
- -
- - var obsoleteCallsListener = new ObsoleteCallStatementListener();
- - var obsoleteLetListener = new ObsoleteLetStatementListener();
- -
- - var listeners = new IParseTreeListener[]
- - {
- - obsoleteCallsListener,
- - obsoleteLetListener
- - };
- -
- - token.ThrowIfCancellationRequested();
- -
- - ITokenStream stream;
- - var code = string.Join("\r\n", vbComponent.CodeModule.Code());
- - var tree = ParseInternal(code, listeners, out stream);
- -
- - token.ThrowIfCancellationRequested();
- - _state.AddTokenStream(vbComponent, stream);
- - _state.AddParseTree(vbComponent, tree);
- -
- - // cannot locate declarations in one pass *the way it's currently implemented*,
- - // because the context in EnterSubStmt() doesn't *yet* have child nodes when the context enters.
- - // so we need to EnterAmbiguousIdentifier() and evaluate the parent instead - this *might* work.
- - var declarationsListener = new DeclarationSymbolsListener(qualifiedName, Accessibility.Implicit, vbComponent.Type, _state.Comments, token);
- -
- - token.ThrowIfCancellationRequested();
- - declarationsListener.NewDeclaration += declarationsListener_NewDeclaration;
- - declarationsListener.CreateModuleDeclarations();
- -
- - token.ThrowIfCancellationRequested();
- - var walker = new ParseTreeWalker();
- - walker.Walk(declarationsListener, tree);
- - declarationsListener.NewDeclaration -= declarationsListener_NewDeclaration;
- -
- - _state.ObsoleteCallContexts = obsoleteCallsListener.Contexts.Select(context => new QualifiedContext(qualifiedName, context));
- - _state.ObsoleteLetContexts = obsoleteLetListener.Contexts.Select(context => new QualifiedContext(qualifiedName, context));
- -
- - State.SetModuleState(vbComponent, ParserState.Parsed);
- - }
- -
- private IParseTree ParseInternal(string code, IEnumerable<IParseTreeListener> listeners, out ITokenStream outStream)
- {
- var input = new AntlrInputStream(code);
- diff --git a/Rubberduck.Parsing/VBA/RubberduckParserState.cs b/Rubberduck.Parsing/VBA/RubberduckParserState.cs
- index 4f9ccaf..e648c90 100644
- --- a/Rubberduck.Parsing/VBA/RubberduckParserState.cs
- +++ b/Rubberduck.Parsing/VBA/RubberduckParserState.cs
- @@ -1,7 +1,9 @@
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- +using System.Diagnostics;
- using System.Linq;
- +using System.Threading;
- using Antlr4.Runtime;
- using Antlr4.Runtime.Tree;
- using Microsoft.Vbe.Interop;
- @@ -45,14 +47,20 @@ namespace Rubberduck.Parsing.VBA
- _moduleStates[component] = state;
- _moduleExceptions[component] = parserError;
- - Status = _moduleStates.Values.Any(value => value == ParserState.Error)
- - ? ParserState.Error
- - : _moduleStates.Values.Any(value => value == ParserState.Parsing)
- - ? ParserState.Parsing
- - : _moduleStates.Values.Any(value => value == ParserState.Resolving)
- - ? ParserState.Resolving
- - : ParserState.Ready;
- + var states = _moduleStates.Values.GroupBy(x => x)
- + .ToDictionary(x => x.Key, x => x.Count());
- + foreach (var x in new[] {ParserState.Error, ParserState.Parsing, ParserState.Resolving})
- + {
- + int count;
- + if (states.TryGetValue(x, out count) && count > 0)
- + {
- + Status = x;
- + return;
- + }
- + }
- +
- + Status = ParserState.Ready;
- }
- public ParserState GetModuleState(VBComponent component)
- @@ -61,7 +69,23 @@ namespace Rubberduck.Parsing.VBA
- }
- private ParserState _status;
- - public ParserState Status { get { return _status; } private set { if(_status != value) {_status = value; OnStateChanged();} } }
- +
- + public ParserState Status
- + {
- + get
- + {
- + return _status;
- + }
- +
- + private set
- + {
- + if (_status != value)
- + {
- + _status = value;
- + OnStateChanged();
- + }
- + }
- + }
- private IEnumerable<QualifiedContext> _obsoleteCallContexts = new List<QualifiedContext>();
- @@ -122,17 +146,27 @@ namespace Rubberduck.Parsing.VBA
- }
- }
- - public void ClearDeclarations(VBComponent component)
- + public void ClearDeclarations(VBComponent component, CancellationToken token)
- {
- - var declarations = _declarations.Keys.Where(k =>
- - k.QualifiedName.QualifiedModuleName.Project == component.Collection.Parent
- - && k.ComponentName == component.Name);
- + var sw = Stopwatch.StartNew();
- +
- + var declarations = _declarations.Keys.AsParallel()
- + .WithCancellation(token)
- + .Where(k =>
- + k.QualifiedName.QualifiedModuleName.Project == component.Collection.Parent
- + && k.ComponentName == component.Name)
- + .ToArray();
- foreach (var declaration in declarations)
- {
- + token.ThrowIfCancellationRequested();
- +
- ResolutionState state;
- _declarations.TryRemove(declaration, out state);
- }
- +
- + sw.Stop();
- + Debug.WriteLine($"{sw.ElapsedMilliseconds}ms");
- }
- public void AddTokenStream(VBComponent component, ITokenStream stream)
Advertisement
Add Comment
Please, Sign In to add comment