Skip to content

Commit c8700fe

Browse files
committed
Cleanup for ParserState when starting beginning to parse a component
1 parent c1e8929 commit c8700fe

File tree

5 files changed

+73
-38
lines changed

5 files changed

+73
-38
lines changed

Rubberduck.Parsing/Rubberduck.Parsing.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@
179179
<Compile Include="Symbols\ValuedDeclaration.cs" />
180180
<Compile Include="VBA\AttributeParser.cs" />
181181
<Compile Include="VBA\Attributes.cs" />
182+
<Compile Include="VBA\CombinedParseTreeListener.cs" />
183+
<Compile Include="VBA\ComponentParseTask.cs" />
182184
<Compile Include="VBA\EnumerableExtensions.cs" />
183185
<Compile Include="VBA\IAttributeParser.cs" />
184186
<Compile Include="VBA\IModuleExporter.cs" />

Rubberduck.Parsing/VBA/ComponentParseTask.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public void Start(CancellationToken token)
9393
{
9494
Debug.WriteLine("Operation was Cancelled", cancel);
9595
// no results to be used, so no results "returned"
96-
ParseCompleted.Invoke(this, new ParseCompletionArgs());
96+
//ParseCompleted.Invoke(this, new ParseCompletionArgs());
9797
}
9898
}
9999

@@ -151,7 +151,7 @@ public class ParseFailureArgs
151151
public Exception Cause { get; internal set; }
152152
}
153153

154-
private class CommentListener : VBABaseListener
154+
private class CommentListener : VBAParserBaseListener
155155
{
156156
private readonly IList<VBAParser.RemCommentContext> _remComments = new List<VBAParser.RemCommentContext>();
157157
public IEnumerable<VBAParser.RemCommentContext> RemComments { get { return _remComments; } }

Rubberduck.Parsing/VBA/RubberduckParser.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020

2121
namespace Rubberduck.Parsing.VBA
2222
{
23-
public class RubberduckParser : IRubberduckParser
23+
public class RubberduckParserLegacy : IRubberduckParser
2424
{
2525
private readonly ReferencedDeclarationsCollector _comReflector;
2626

27-
public RubberduckParser(VBE vbe, RubberduckParserState state, IAttributeParser attributeParser)
27+
public RubberduckParserLegacy(VBE vbe, RubberduckParserState state, IAttributeParser attributeParser)
2828
{
2929
_vbe = vbe;
3030
_state = state;

Rubberduck.Parsing/VBA/RubberduckParserReimpl.cs

Lines changed: 61 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
namespace Rubberduck.Parsing.VBA
1919
{
20-
class RubberduckParserReimpl : IRubberduckParser
20+
public class RubberduckParser : IRubberduckParser
2121
{
2222
public RubberduckParserState State
2323
{
@@ -27,8 +27,8 @@ public RubberduckParserState State
2727
}
2828
}
2929

30-
private readonly CancellationTokenSource _central = new CancellationTokenSource();
31-
private readonly CancellationTokenSource _resolverTokenSource; // linked to _central later
30+
private CancellationTokenSource _central = new CancellationTokenSource();
31+
private CancellationTokenSource _resolverTokenSource; // linked to _central later
3232
private readonly Dictionary<VBComponent, Tuple<Task, CancellationTokenSource>> _currentTasks = new Dictionary<VBComponent, Tuple<Task, CancellationTokenSource>>();
3333

3434
private readonly Dictionary<VBComponent, IParseTree> _parseTrees = new Dictionary<VBComponent, IParseTree>();
@@ -45,7 +45,7 @@ private readonly IDictionary<VBComponent, IDictionary<Tuple<string, DeclarationT
4545
private readonly RubberduckParserState _state;
4646
private readonly IAttributeParser _attributeParser;
4747

48-
public RubberduckParserReimpl(VBE vbe, RubberduckParserState state, IAttributeParser attributeParser)
48+
public RubberduckParser(VBE vbe, RubberduckParserState state, IAttributeParser attributeParser)
4949
{
5050
_resolverTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_central.Token);
5151
_vbe = vbe;
@@ -60,11 +60,13 @@ public RubberduckParserReimpl(VBE vbe, RubberduckParserState state, IAttributePa
6060

6161
private void StateOnStateChanged(object sender, EventArgs e)
6262
{
63-
var args = e as ParserStateEventArgs;
63+
ParserStateEventArgs args = e as ParserStateEventArgs;
64+
Debug.WriteLine("RubberduckParser handles OnStateChanged ({0})", _state.Status);
65+
// why access _state and not pass through EventArgs?
6466
if (args.State == ParserState.Parsed)
6567
{
68+
Debug.WriteLine("(handling OnStateChanged) Starting resolver task");
6669
Task.Run(() => Resolve(_central.Token));
67-
// Resolving should be triggered.. not our job?
6870
}
6971
}
7072

@@ -79,7 +81,18 @@ private void ReparseRequested(object sender, EventArgs e)
7981
else
8082
{
8183
Cancel(args.Component);
82-
ParseAsync(args.Component, CancellationToken.None, _state.GetRewriter(args.Component));
84+
ParseAsync(args.Component, CancellationToken.None);
85+
}
86+
}
87+
88+
public void Parse()
89+
{
90+
try
91+
{
92+
ParseAll();
93+
} catch (Exception e)
94+
{
95+
Debug.WriteLine(e);
8396
}
8497
}
8598

@@ -103,16 +116,20 @@ private void ParseAll()
103116
{
104117
while (!_state.ClearDeclarations(vbComponent)) { }
105118

106-
ParseAsync(vbComponent, CancellationToken.None, _state.GetRewriter(vbComponent));
119+
ParseAsync(vbComponent, CancellationToken.None);
107120
}
108121
}
109122

110123
public Task ParseAsync(VBComponent component, CancellationToken token, TokenStreamRewriter rewriter = null)
111124
{
112-
// FIXME remove invalidated "things"from _state
113-
// this includes: Declarations, Comments, Attributes, "InspectionResults" (ObsoleteCall, ObsoleteLet, EmptyStringLiteral, ArgLists with OneByRef) and possibly more...
125+
// Remove invalidated "things" from _state
126+
// this includes: Declarations, Comments, Attributes, Exceptions, ParseTree and TokenStream
127+
// how that works with the Inspecion results is not quite clear
114128
_state.ClearDeclarations(component);
115-
_state.SetModuleState(component, ParserState.Pending);
129+
_state.AddParseTree(component, null);
130+
_state.AddTokenStream(component, null);
131+
132+
_state.SetModuleState(component, ParserState.Pending); // also clears module-exceptions
116133
_state.SetModuleComments(component, Enumerable.Empty<CommentNode>());
117134
_state.SetModuleAttributes(component, new Dictionary<Tuple<string, DeclarationType>, Attributes>());
118135

@@ -127,35 +144,49 @@ public Task ParseAsync(VBComponent component, CancellationToken token, TokenStre
127144
}
128145

129146
public void Cancel(VBComponent component = null)
130-
{
131-
if (component == null)
132-
{
133-
_central.Cancel(false);
134-
}
135-
else
136-
{
137-
_resolverTokenSource.Cancel(false);
138-
Tuple<Task, CancellationTokenSource> result;
139-
if (_currentTasks.TryGetValue(component, out result))
147+
{
148+
lock (_central)
149+
lock (_resolverTokenSource)
140150
{
141-
result.Item2.Cancel(false);
151+
if (component == null)
152+
{
153+
_central.Cancel(false);
154+
155+
_central.Dispose();
156+
_central = new CancellationTokenSource();
157+
_resolverTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_central.Token);
158+
}
159+
else
160+
{
161+
_resolverTokenSource.Cancel(false);
162+
_resolverTokenSource.Dispose();
163+
164+
_resolverTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_central.Token);
165+
Tuple<Task, CancellationTokenSource> result;
166+
if (_currentTasks.TryGetValue(component, out result))
167+
{
168+
result.Item2.Cancel(false);
169+
result.Item2.Dispose();
170+
}
171+
}
172+
142173
}
143-
}
144174
}
145175

146176
private void ParseAsyncInternal(VBComponent component, CancellationToken token, TokenStreamRewriter rewriter = null)
147177
{
148178
var preprocessor = new VBAPreprocessor(double.Parse(_vbe.Version, CultureInfo.InvariantCulture));
149-
var parser = new ComponentParseTask(component, preprocessor, _attributeParser, _state.GetRewriter(component));
179+
var parser = new ComponentParseTask(component, preprocessor, _attributeParser, rewriter);
150180
parser.ParseFailure += (sender, e) => _state.SetModuleState(component, ParserState.Error, e.Cause as SyntaxErrorException);
151181
parser.ParseCompleted += (sender, e) =>
152182
{
153183
// possibly lock _state
154-
_state.SetModuleState(component, ParserState.Parsed);
155184
_state.SetModuleAttributes(component, e.Attributes);
156185
_state.AddParseTree(component, e.ParseTree);
157186
_state.AddTokenStream(component, e.Tokens);
158187
_state.SetModuleComments(component, e.Comments);
188+
// This really needs to go last
189+
_state.SetModuleState(component, ParserState.Parsed);
159190
};
160191
_state.SetModuleState(component, ParserState.Parsing);
161192
parser.Start(token);
@@ -219,7 +250,7 @@ private void ResolveDeclarations(VBComponent component, IParseTree tree)
219250
_state.ArgListsWithOneByRefParam = argListWithOneByRefParamListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
220251
_state.EmptyStringLiterals = emptyStringLiteralListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
221252
_state.ObsoleteLetContexts = obsoleteLetStatementListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
222-
_state.ObsoleteCallContexts = obsoleteCallStatementListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context))
253+
_state.ObsoleteCallContexts = obsoleteCallStatementListener.Contexts.Select(context => new QualifiedContext(qualifiedModuleName, context));
223254
}
224255

225256
private void ResolveReferences(DeclarationFinder finder, VBComponent component, IParseTree tree)
@@ -255,7 +286,7 @@ private void ResolveReferences(DeclarationFinder finder, VBComponent component,
255286
}
256287

257288
#region Listener classes
258-
private class ObsoleteCallStatementListener : VBABaseListener
289+
private class ObsoleteCallStatementListener : VBAParserBaseListener
259290
{
260291
private readonly IList<VBAParser.ExplicitCallStmtContext> _contexts = new List<VBAParser.ExplicitCallStmtContext>();
261292
public IEnumerable<VBAParser.ExplicitCallStmtContext> Contexts { get { return _contexts; } }
@@ -279,7 +310,7 @@ public override void ExitExplicitCallStmt(VBAParser.ExplicitCallStmtContext cont
279310
}
280311
}
281312

282-
private class ObsoleteLetStatementListener : VBABaseListener
313+
private class ObsoleteLetStatementListener : VBAParserBaseListener
283314
{
284315
private readonly IList<VBAParser.LetStmtContext> _contexts = new List<VBAParser.LetStmtContext>();
285316
public IEnumerable<VBAParser.LetStmtContext> Contexts { get { return _contexts; } }
@@ -293,7 +324,7 @@ public override void ExitLetStmt(VBAParser.LetStmtContext context)
293324
}
294325
}
295326

296-
private class EmptyStringLiteralListener : VBABaseListener
327+
private class EmptyStringLiteralListener : VBAParserBaseListener
297328
{
298329
private readonly IList<VBAParser.LiteralContext> _contexts = new List<VBAParser.LiteralContext>();
299330
public IEnumerable<VBAParser.LiteralContext> Contexts { get { return _contexts; } }
@@ -308,7 +339,7 @@ public override void ExitLiteral(VBAParser.LiteralContext context)
308339
}
309340
}
310341

311-
private class ArgListWithOneByRefParamListener : VBABaseListener
342+
private class ArgListWithOneByRefParamListener : VBAParserBaseListener
312343
{
313344
private readonly IList<VBAParser.ArgListContext> _contexts = new List<VBAParser.ArgListContext>();
314345
public IEnumerable<VBAParser.ArgListContext> Contexts { get { return _contexts; } }

Rubberduck.Parsing/VBA/RubberduckParserState.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,14 @@ public IReadOnlyList<Tuple<VBComponent, SyntaxErrorException>> ModuleExceptions
6969
get { return _moduleExceptions.Select(kvp => Tuple.Create(kvp.Key, kvp.Value)).Where(item => item.Item2 != null).ToList(); }
7070
}
7171

72-
public event EventHandler StateChanged;
72+
public event EventHandler<ParserStateEventArgs> StateChanged;
7373

74-
private void OnStateChanged()
74+
private void OnStateChanged(ParserState state = ParserState.Pending)
7575
{
7676
var handler = StateChanged;
7777
if (handler != null)
7878
{
79-
handler.Invoke(this, EventArgs.Empty);
79+
handler.Invoke(this, new ParserStateEventArgs(state));
8080
}
8181
}
8282
public event EventHandler<ParseProgressEventArgs> ModuleStateChanged;
@@ -99,6 +99,8 @@ public void SetModuleState(VBComponent component, ParserState state, SyntaxError
9999
Debug.WriteLine("Module '{0}' state is changing to '{1}' (thread {2})", component.Name, state, Thread.CurrentThread.ManagedThreadId);
100100
OnModuleStateChanged(component, state);
101101
Status = EvaluateParserState();
102+
103+
OnStateChanged(Status);
102104
}
103105

104106
private ParserState EvaluateParserState()
@@ -128,7 +130,7 @@ private set
128130
{
129131
_status = value;
130132
Debug.WriteLine("ParserState changed to '{0}', raising OnStateChanged", value);
131-
OnStateChanged();
133+
OnStateChanged(_status);
132134
}
133135
}
134136
}

0 commit comments

Comments
 (0)