Skip to content

Commit 9c919f5

Browse files
committed
Merge pull request #969 from retailcoder/CodeExplorer
Resolver fixes, mostly
2 parents 6bbb31c + ffc5206 commit 9c919f5

File tree

13 files changed

+523
-207
lines changed

13 files changed

+523
-207
lines changed

RetailCoder.VBE/App.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ public App(VBE vbe, IMessageBox messageBox,
6464
_configService.SettingsChanged += _configService_SettingsChanged;
6565
_parser.State.StateChanged += Parser_StateChanged;
6666
_stateBar.Refresh += _stateBar_Refresh;
67+
68+
UiDispatcher.Initialize();
6769
}
6870

6971
private Keys _firstStepHotKey;

RetailCoder.VBE/Extension.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public void OnConnection(object Application, ext_ConnectMode ConnectMode, object
3939
_kernel.Load(new RubberduckModule(_kernel, (VBE)Application, (AddIn)AddInInst));
4040
_kernel.Load(new UI.SourceControl.SourceControlBindings());
4141
_kernel.Load(new CommandBarsModule(_kernel));
42+
43+
var app = _kernel.Get<App>();
44+
app.Startup();
4245
}
4346
catch (Exception exception)
4447
{
@@ -48,8 +51,6 @@ public void OnConnection(object Application, ext_ConnectMode ConnectMode, object
4851

4952
public void OnStartupComplete(ref Array custom)
5053
{
51-
var app = _kernel.Get<App>();
52-
app.Startup();
5354
}
5455

5556
public void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)

RetailCoder.VBE/Navigation/CodeExplorer/CodeExplorerViewModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public ObservableCollection<CodeExplorerProjectViewModel> Projects
7575
private void ParserState_StateChanged(object sender, ParserStateEventArgs e)
7676
{
7777
IsBusy = e.State == ParserState.Parsing;
78-
if (e.State != ParserState.Resolving) // ParserState.Parsed state is too volatile
78+
if (e.State != ParserState.Parsed)
7979
{
8080
return;
8181
}

RetailCoder.VBE/Rubberduck.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@
465465
<Compile Include="UI\Command\MenuItems\RefactorIntroduceParameterCommandMenuItem.cs" />
466466
<Compile Include="UI\Command\MenuItems\RefactorMoveCloserToUsageCommandMenuItem.cs" />
467467
<Compile Include="UI\Command\MenuItems\RegexSearchReplaceCommandMenuItem.cs" />
468+
<Compile Include="UI\Command\MenuItems\UiDispatcher.cs" />
468469
<Compile Include="UI\Command\NavigateCommand.cs" />
469470
<Compile Include="UI\Command\OptionsCommand.cs" />
470471
<Compile Include="UI\Command\MenuItems\OptionsCommandMenuItem.cs" />

RetailCoder.VBE/UI/CodeInspections/InspectionResultsViewModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ private async void ExecuteRefreshCommandAsync(object parameter)
156156
IsBusy = true;
157157

158158
_state.StateChanged += _state_StateChanged;
159-
_state.OnParseRequested();
159+
//_state.OnParseRequested();
160160
}
161161

162162
private bool CanExecuteRefreshCommand(object parameter)
@@ -203,7 +203,7 @@ private void ExecuteQuickFixCommand(object parameter)
203203

204204
private bool CanExecuteQuickFixCommand(object parameter)
205205
{
206-
return true; //!IsBusy && SelectedItem is IInspection;
206+
return !IsBusy && SelectedItem is IInspection;
207207
}
208208

209209
private bool _canExecuteQuickFixInModule;

RetailCoder.VBE/UI/Command/MenuItems/ParserStateCommandBar.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using System.Linq;
55
using System.Text;
66
using System.Threading.Tasks;
7+
using System.Windows.Forms;
8+
using System.Windows.Threading;
79
using Microsoft.Office.Core;
810
using Microsoft.Vbe.Interop;
911
using Rubberduck.Parsing;
@@ -36,7 +38,7 @@ public void SetStatusText(string value)
3638

3739
private void State_StateChanged(object sender, ParserStateEventArgs e)
3840
{
39-
_statusButton.Caption = e.State.ToString();
41+
UiDispatcher.Invoke(() => _statusButton.Caption = e.State.ToString());
4042
}
4143

4244
public event EventHandler Refresh;
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Threading;
3+
4+
namespace Rubberduck.UI.Command.MenuItems
5+
{
6+
public static class UiDispatcher
7+
{
8+
// thanks to Pellared on http://stackoverflow.com/a/12909070/1188513
9+
10+
private static SynchronizationContext UiContext { get; set; }
11+
12+
public static void Initialize()
13+
{
14+
if (UiContext == null)
15+
{
16+
UiContext = SynchronizationContext.Current;
17+
}
18+
}
19+
20+
/// <summary>
21+
/// Invokes an action asynchronously on the UI thread.
22+
/// </summary>
23+
/// <param name="action">The action that must be executed.</param>
24+
public static void InvokeAsync(Action action)
25+
{
26+
CheckInitialization();
27+
28+
UiContext.Post(x => action(), null);
29+
}
30+
31+
/// <summary>
32+
/// Executes an action on the UI thread. If this method is called
33+
/// from the UI thread, the action is executed immendiately. If the
34+
/// method is called from another thread, the action will be enqueued
35+
/// on the UI thread's dispatcher and executed asynchronously.
36+
/// <para>For additional operations on the UI thread, you can get a
37+
/// reference to the UI thread's context thanks to the property
38+
/// <see cref="UiContext" /></para>.
39+
/// </summary>
40+
/// <param name="action">The action that will be executed on the UI
41+
/// thread.</param>
42+
public static void Invoke(Action action)
43+
{
44+
CheckInitialization();
45+
46+
if (UiContext == SynchronizationContext.Current)
47+
{
48+
action();
49+
}
50+
else
51+
{
52+
InvokeAsync(action);
53+
}
54+
}
55+
56+
private static void CheckInitialization()
57+
{
58+
if (UiContext == null) throw new InvalidOperationException("UiDispatcher is not initialized. Invoke Initialize() from UI thread first.");
59+
}
60+
}
61+
}

Rubberduck.Parsing/Symbols/Declaration.cs

Lines changed: 134 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public Declaration(QualifiedMemberName qualifiedName, Declaration parentDeclarat
2929
{
3030
_qualifiedName = qualifiedName;
3131
_parentDeclaration = parentDeclaration;
32-
_parentScope = parentScope;
32+
_parentScope = parentScope ?? string.Empty;
3333
_identifierName = qualifiedName.MemberName;
3434
_asTypeName = asTypeName;
3535
_isSelfAssigned = isSelfAssigned;
@@ -57,6 +57,10 @@ public Declaration(QualifiedMemberName qualifiedName, Declaration parentDeclarat
5757
result = value;
5858
}
5959
_customFolder = result;
60+
61+
_isArray = IsArray();
62+
_hasTypeHint = HasTypeHint();
63+
_isTypeSpecified = IsTypeSpecified();
6064
}
6165

6266
/// <summary>
@@ -210,13 +214,33 @@ public void AddMemberCall(IdentifierReference reference)
210214
/// </remarks>
211215
public string AsTypeName { get { return _asTypeName; } }
212216

217+
private bool? _isArray;
218+
213219
public bool IsArray()
214220
{
215-
if (Context == null)
221+
if (Context == null || _isArray.HasValue && !_isArray.Value)
216222
{
217223
return false;
218224
}
219225

226+
if (_isArray.HasValue)
227+
{
228+
return _isArray.Value;
229+
}
230+
231+
//var variableContext = Context as VBAParser.VariableSubStmtContext;
232+
//if (variableContext != null)
233+
//{
234+
// return variableContext.LPAREN() != null && variableContext.RPAREN() != null;
235+
//}
236+
237+
//var typeElementContext = Context as VBAParser.TypeStmt_ElementContext;
238+
//if (typeElementContext != null)
239+
//{
240+
// return typeElementContext.LPAREN() != null && typeElementContext.RPAREN() != null;
241+
//}
242+
//return false;
243+
220244
try
221245
{
222246
var declaration = (dynamic)Context;
@@ -228,16 +252,61 @@ public bool IsArray()
228252
}
229253
}
230254

255+
private bool? _isTypeSpecified;
256+
231257
public bool IsTypeSpecified()
232258
{
233-
if (Context == null)
259+
if (Context == null || _isTypeSpecified.HasValue && !_isTypeSpecified.Value)
234260
{
235261
return false;
236262
}
237263

264+
if (_isTypeSpecified.HasValue)
265+
{
266+
return _isTypeSpecified.Value;
267+
}
268+
269+
//var variableContext = Context as VBAParser.VariableSubStmtContext;
270+
//if (variableContext != null)
271+
//{
272+
// return variableContext.asTypeClause() != null || HasTypeHint();
273+
//}
274+
275+
//var argContext = Context as VBAParser.ArgContext;
276+
//if (argContext != null)
277+
//{
278+
// return argContext.asTypeClause() != null || HasTypeHint();
279+
//}
280+
281+
//var constContext = Context as VBAParser.ConstSubStmtContext;
282+
//if (constContext != null)
283+
//{
284+
// return constContext.asTypeClause() != null || HasTypeHint();
285+
//}
286+
287+
//var functionContext = Context as VBAParser.FunctionStmtContext;
288+
//if (functionContext != null)
289+
//{
290+
// return functionContext.asTypeClause() != null || HasTypeHint();
291+
//}
292+
293+
//var getterContext = Context as VBAParser.PropertyGetStmtContext;
294+
//if (getterContext != null)
295+
//{
296+
// return getterContext.asTypeClause() != null || HasTypeHint();
297+
//}
298+
299+
//var typeElementContext = Context as VBAParser.TypeStmt_ElementContext;
300+
//if (typeElementContext != null)
301+
//{
302+
// return typeElementContext.asTypeClause() != null || HasTypeHint();
303+
//}
304+
305+
//return false;
306+
238307
try
239308
{
240-
var asType = ((dynamic) Context).asTypeClause() as VBAParser.AsTypeClauseContext;
309+
var asType = ((dynamic)Context).asTypeClause() as VBAParser.AsTypeClauseContext;
241310
return asType != null || HasTypeHint();
242311
}
243312
catch (RuntimeBinderException)
@@ -246,8 +315,15 @@ public bool IsTypeSpecified()
246315
}
247316
}
248317

318+
private bool? _hasTypeHint;
319+
249320
public bool HasTypeHint()
250321
{
322+
if (_hasTypeHint.HasValue)
323+
{
324+
return _hasTypeHint.Value;
325+
}
326+
251327
string token;
252328
return HasTypeHint(out token);
253329
}
@@ -260,6 +336,47 @@ public bool HasTypeHint(out string token)
260336
return false;
261337
}
262338

339+
//VBAParser.TypeHintContext hint = null;
340+
//var variableContext = Context as VBAParser.VariableSubStmtContext;
341+
//if (variableContext != null)
342+
//{
343+
// hint = variableContext.typeHint();
344+
//}
345+
346+
////var argContext = Context as VBAParser.ArgContext;
347+
////if (argContext != null)
348+
////{
349+
//// hint = argContext.typeHint();
350+
////}
351+
352+
//var constContext = Context as VBAParser.ConstSubStmtContext;
353+
//if (constContext != null)
354+
//{
355+
// hint = constContext.typeHint();
356+
//}
357+
358+
//var functionContext = Context as VBAParser.FunctionStmtContext;
359+
//if (functionContext != null)
360+
//{
361+
// hint = functionContext.typeHint();
362+
//}
363+
364+
//var getterContext = Context as VBAParser.PropertyGetStmtContext;
365+
//if (getterContext != null)
366+
//{
367+
// hint = getterContext.typeHint();
368+
//}
369+
370+
////var typeElementContext = Context as VBAParser.TypeStmt_ElementContext;
371+
////if (typeElementContext != null)
372+
////{
373+
//// hint = typeElementContext.typeHint();
374+
////}
375+
376+
//token = hint == null ? null : hint.GetText();
377+
//return hint != null;
378+
379+
263380
try
264381
{
265382
var hint = ((dynamic)Context).typeHint() as VBAParser.TypeHintContext;
@@ -350,7 +467,8 @@ public bool Equals(Declaration other)
350467
&& other.IdentifierName == IdentifierName
351468
&& other.DeclarationType == DeclarationType
352469
&& other.Scope == Scope
353-
&& other.ParentScope == ParentScope;
470+
&& other.ParentScope == ParentScope
471+
&& other.Selection.Equals(Selection);
354472
}
355473

356474
public override bool Equals(object obj)
@@ -360,7 +478,17 @@ public override bool Equals(object obj)
360478

361479
public override int GetHashCode()
362480
{
363-
return string.Concat(QualifiedName.QualifiedModuleName.ProjectHashCode, _identifierName, _declarationType, Scope, _parentScope).GetHashCode();
481+
unchecked
482+
{
483+
var hash = 17;
484+
hash = hash*23 + QualifiedName.QualifiedModuleName.ProjectHashCode;
485+
hash = hash*23 + _identifierName.GetHashCode();
486+
hash = hash*23 + _declarationType.GetHashCode();
487+
hash = hash*23 + Scope.GetHashCode();
488+
hash = hash*23 + _parentScope == null ? 0 : _parentScope.GetHashCode();
489+
hash = hash*23 + _selection.GetHashCode();
490+
return hash;
491+
}
364492
}
365493
}
366494
}

0 commit comments

Comments
 (0)