11using System ;
22using System . Collections . Generic ;
33using System . Threading ;
4+ using Rubberduck . Parsing . Common ;
45using Rubberduck . Parsing . VBA . Parsing . ParsingExceptions ;
56using Rubberduck . VBEditor ;
67
@@ -36,23 +37,32 @@ protected ParseRunnerBase(
3637 _parser = parser ;
3738 }
3839
40+ public void ParseModules ( IReadOnlyCollection < QualifiedModuleName > modules , CancellationToken token )
41+ {
42+ var parsingStageTimer = ParsingStageTimer . StartNew ( ) ;
43+
44+ var parseResults = ModulePareResults ( modules , token ) ;
45+ SaveModuleParseResultsOnState ( parseResults , token ) ;
3946
40- public abstract void ParseModules ( IReadOnlyCollection < QualifiedModuleName > modules , CancellationToken token ) ;
47+ parsingStageTimer . Stop ( ) ;
48+ parsingStageTimer . Log ( "Parsed user modules in {0}ms." ) ;
49+ }
4150
51+ protected abstract IReadOnlyCollection < ( QualifiedModuleName module , ModuleParseResults results ) > ModulePareResults ( IReadOnlyCollection < QualifiedModuleName > modules , CancellationToken token ) ;
4252
43- protected void ParseModule ( QualifiedModuleName module , CancellationToken token )
53+ protected ModuleParseResults ModuleParseResults ( QualifiedModuleName module , CancellationToken token )
4454 {
4555 _state . ClearStateCache ( module ) ;
4656 try
4757 {
48- var parseResults = _parser . Parse ( module , token ) ;
49- SaveModuleParseResultsOnState ( module , parseResults , token ) ;
58+ return _parser . Parse ( module , token ) ;
5059 }
5160 catch ( SyntaxErrorException syntaxErrorException )
5261 {
5362 //In contrast to the situation in the success scenario, the overall parser state is reevaluated immediately.
54- //This sets the state directly on the state because it is the sole instance where we have to pass the SyntaxErorException .
63+ //This sets the state directly on the state because it is the sole instance where we have to pass the SyntaxErrorException .
5564 _state . SetModuleState ( module , ParserState . Error , token , syntaxErrorException ) ;
65+ return default ;
5666 }
5767 catch ( Exception exception )
5868 {
@@ -61,30 +71,40 @@ protected void ParseModule(QualifiedModuleName module, CancellationToken token)
6171 }
6272 }
6373
64- private void SaveModuleParseResultsOnState ( QualifiedModuleName module , ModuleParseResults results , CancellationToken token )
74+ private void SaveModuleParseResultsOnState ( IReadOnlyCollection < ( QualifiedModuleName module , ModuleParseResults results ) > parseResults , CancellationToken token )
6575 {
66- lock ( _state )
76+ foreach ( var ( module , result ) in parseResults )
6777 {
68- token . ThrowIfCancellationRequested ( ) ;
78+ if ( result . CodePaneParseTree == null )
79+ {
80+ continue ;
81+ }
6982
70- //This has to come first because it creates the module state if not present.
71- _state . AddModuleStateIfNotPresent ( module ) ;
83+ SaveModuleParseResultsOnState ( module , result , token ) ;
84+ }
85+ }
7286
73- _state . SaveContentHash ( module ) ;
74- _state . AddParseTree ( module , results . CodePaneParseTree ) ;
75- _state . AddParseTree ( module , results . AttributesParseTree , CodeKind . AttributesCode ) ;
76- _state . SetModuleComments ( module , results . Comments ) ;
77- _state . SetModuleAnnotations ( module , results . Annotations ) ;
78- _state . SetModuleAttributes ( module , results . Attributes ) ;
79- _state . SetMembersAllowingAttributes ( module , results . MembersAllowingAttributes ) ;
80- _state . SetCodePaneTokenStream ( module , results . CodePaneTokenStream ) ;
81- _state . SetAttributesTokenStream ( module , results . AttributesTokenStream ) ;
87+ private void SaveModuleParseResultsOnState ( QualifiedModuleName module , ModuleParseResults results , CancellationToken token )
88+ {
89+ token . ThrowIfCancellationRequested ( ) ;
8290
83- // This really needs to go last
84- //It does not reevaluate the overall parer state to avoid concurrent evaluation of all module states and for performance reasons.
85- //The evaluation has to be triggered manually in the calling procedure.
86- StateManager . SetModuleState ( module , ParserState . Parsed , token , false ) ; //Note that this is ok because locks allow re-entrancy.
87- }
91+ //This has to come first because it creates the module state if not present.
92+ _state . AddModuleStateIfNotPresent ( module ) ;
93+
94+ _state . SaveContentHash ( module ) ;
95+ _state . AddParseTree ( module , results . CodePaneParseTree ) ;
96+ _state . AddParseTree ( module , results . AttributesParseTree , CodeKind . AttributesCode ) ;
97+ _state . SetModuleComments ( module , results . Comments ) ;
98+ _state . SetModuleAnnotations ( module , results . Annotations ) ;
99+ _state . SetModuleAttributes ( module , results . Attributes ) ;
100+ _state . SetMembersAllowingAttributes ( module , results . MembersAllowingAttributes ) ;
101+ _state . SetCodePaneTokenStream ( module , results . CodePaneTokenStream ) ;
102+ _state . SetAttributesTokenStream ( module , results . AttributesTokenStream ) ;
103+
104+ // This really needs to go last
105+ //It does not reevaluate the overall parer state to avoid concurrent evaluation of all module states and for performance reasons.
106+ //The evaluation has to be triggered manually in the calling procedure.
107+ StateManager . SetModuleState ( module , ParserState . Parsed , token , false ) ; //Note that this is ok because locks allow re-entrancy.
88108 }
89109 }
90110}
0 commit comments