1717using Rubberduck . UI . Command . MenuItems ;
1818using Infralution . Localization . Wpf ;
1919using Rubberduck . Common . Dispatch ;
20+ using Rubberduck . VBEditor . Extensions ;
2021
2122namespace Rubberduck
2223{
@@ -39,10 +40,10 @@ public class App : IDisposable
3940 private readonly IConnectionPoint _projectsEventsConnectionPoint ;
4041 private readonly int _projectsEventsCookie ;
4142
42- private readonly IDictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > _componentsEventsConnectionPoints =
43- new Dictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > ( ) ;
44- private readonly IDictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > _referencesEventsConnectionPoints =
45- new Dictionary < VBProjectsEventsSink , Tuple < IConnectionPoint , int > > ( ) ;
43+ private readonly IDictionary < string , Tuple < IConnectionPoint , int > > _componentsEventsConnectionPoints =
44+ new Dictionary < string , Tuple < IConnectionPoint , int > > ( ) ;
45+ private readonly IDictionary < string , Tuple < IConnectionPoint , int > > _referencesEventsConnectionPoints =
46+ new Dictionary < string , Tuple < IConnectionPoint , int > > ( ) ;
4647
4748 public App ( VBE vbe , IMessageBox messageBox ,
4849 IRubberduckParser parser ,
@@ -127,11 +128,6 @@ public void Startup()
127128 {
128129 CleanReloadConfig ( ) ;
129130
130- foreach ( var project in _vbe . VBProjects . Cast < VBProject > ( ) )
131- {
132- _parser . State . AddProject ( project ) ;
133- }
134-
135131 _appMenus . Initialize ( ) ;
136132 _appMenus . Localize ( ) ;
137133
@@ -150,40 +146,51 @@ public void Startup()
150146 #region sink handlers. todo: move to another class
151147 async void sink_ProjectRemoved ( object sender , DispatcherEventArgs < VBProject > e )
152148 {
153- var sink = ( VBProjectsEventsSink ) sender ;
154- _componentsEventSinks . Remove ( sink ) ;
155- _referencesEventsSinks . Remove ( sink ) ;
149+ if ( e . Item . Protection == vbext_ProjectProtection . vbext_pp_locked )
150+ {
151+ Debug . WriteLine ( string . Format ( "Locked project '{0}' was removed." , e . Item . Name ) ) ;
152+ return ;
153+ }
154+
155+ var projectId = e . Item . HelpFile ;
156+ _componentsEventsSinks . Remove ( projectId ) ;
157+ _referencesEventsSinks . Remove ( projectId ) ;
156158 _parser . State . RemoveProject ( e . Item ) ;
157159
158160 Debug . WriteLine ( string . Format ( "Project '{0}' was removed." , e . Item . Name ) ) ;
159161 Tuple < IConnectionPoint , int > componentsTuple ;
160- if ( _componentsEventsConnectionPoints . TryGetValue ( sink , out componentsTuple ) )
162+ if ( _componentsEventsConnectionPoints . TryGetValue ( projectId , out componentsTuple ) )
161163 {
162164 componentsTuple . Item1 . Unadvise ( componentsTuple . Item2 ) ;
163- _componentsEventsConnectionPoints . Remove ( sink ) ;
165+ _componentsEventsConnectionPoints . Remove ( projectId ) ;
164166 }
165167
166168 Tuple < IConnectionPoint , int > referencesTuple ;
167- if ( _referencesEventsConnectionPoints . TryGetValue ( sink , out referencesTuple ) )
169+ if ( _referencesEventsConnectionPoints . TryGetValue ( projectId , out referencesTuple ) )
168170 {
169171 referencesTuple . Item1 . Unadvise ( referencesTuple . Item2 ) ;
170- _referencesEventsConnectionPoints . Remove ( sink ) ;
172+ _referencesEventsConnectionPoints . Remove ( projectId ) ;
171173 }
172-
173- _parser . State . ClearDeclarations ( e . Item ) ;
174174 }
175175
176- private readonly IDictionary < VBProjectsEventsSink , VBComponentsEventsSink > _componentsEventSinks =
177- new Dictionary < VBProjectsEventsSink , VBComponentsEventsSink > ( ) ;
176+ private readonly IDictionary < string , VBComponentsEventsSink > _componentsEventsSinks =
177+ new Dictionary < string , VBComponentsEventsSink > ( ) ;
178178
179- private readonly IDictionary < VBProjectsEventsSink , ReferencesEventsSink > _referencesEventsSinks =
180- new Dictionary < VBProjectsEventsSink , ReferencesEventsSink > ( ) ;
179+ private readonly IDictionary < string , ReferencesEventsSink > _referencesEventsSinks =
180+ new Dictionary < string , ReferencesEventsSink > ( ) ;
181181
182182 async void sink_ProjectAdded ( object sender , DispatcherEventArgs < VBProject > e )
183183 {
184- var sink = ( VBProjectsEventsSink ) sender ;
185- RegisterComponentsEventSink ( e , sink ) ;
186- _parser . State . AddProject ( e . Item ) ;
184+ Debug . WriteLine ( string . Format ( "Project '{0}' was added." , e . Item . Name ) ) ;
185+ if ( e . Item . Protection == vbext_ProjectProtection . vbext_pp_locked )
186+ {
187+ Debug . WriteLine ( "Project is protected and will not be added to parser state." ) ;
188+ return ;
189+ }
190+
191+ _parser . State . AddProject ( e . Item ) ; // note side-effect: assigns ProjectId/HelpFile
192+ var projectId = e . Item . HelpFile ;
193+ RegisterComponentsEventSink ( e . Item . VBComponents , projectId ) ;
187194
188195 if ( ! _parser . State . AllDeclarations . Any ( ) )
189196 {
@@ -193,13 +200,19 @@ async void sink_ProjectAdded(object sender, DispatcherEventArgs<VBProject> e)
193200 return ;
194201 }
195202
196- Debug . WriteLine ( string . Format ( "Project '{0}' was added." , e . Item . Name ) ) ;
197203 _parser . State . OnParseRequested ( sender ) ;
198204 }
199205
200- private void RegisterComponentsEventSink ( DispatcherEventArgs < VBProject > e , VBProjectsEventsSink sink )
206+ private void RegisterComponentsEventSink ( VBComponents components , string projectId )
201207 {
202- var connectionPointContainer = ( IConnectionPointContainer ) e . Item . VBComponents ;
208+ if ( _componentsEventsSinks . ContainsKey ( projectId ) )
209+ {
210+ // already registered - this is caused by the initial load+rename of a project in the VBE
211+ Debug . WriteLine ( "Components sink already registered." ) ;
212+ return ;
213+ }
214+
215+ var connectionPointContainer = ( IConnectionPointContainer ) components ;
203216 var interfaceId = typeof ( _dispVBComponentsEvents ) . GUID ;
204217
205218 IConnectionPoint connectionPoint ;
@@ -212,12 +225,13 @@ private void RegisterComponentsEventSink(DispatcherEventArgs<VBProject> e, VBPro
212225 componentsSink . ComponentRemoved += sink_ComponentRemoved ;
213226 componentsSink . ComponentRenamed += sink_ComponentRenamed ;
214227 componentsSink . ComponentSelected += sink_ComponentSelected ;
215- _componentsEventSinks . Add ( sink , componentsSink ) ;
228+ _componentsEventsSinks . Add ( projectId , componentsSink ) ;
216229
217230 int cookie ;
218231 connectionPoint . Advise ( componentsSink , out cookie ) ;
219232
220- _componentsEventsConnectionPoints . Add ( sink , Tuple . Create ( connectionPoint , cookie ) ) ;
233+ _componentsEventsConnectionPoints . Add ( projectId , Tuple . Create ( connectionPoint , cookie ) ) ;
234+ Debug . WriteLine ( "Components sink registered and advising." ) ;
221235 }
222236
223237 async void sink_ComponentSelected ( object sender , DispatcherEventArgs < VBComponent > e )
@@ -251,7 +265,7 @@ async void sink_ComponentRemoved(object sender, DispatcherEventArgs<VBComponent>
251265 }
252266
253267 Debug . WriteLine ( string . Format ( "Component '{0}' was removed." , e . Item . Name ) ) ;
254- _parser . State . ClearDeclarations ( e . Item ) ;
268+ _parser . State . ClearStateCache ( e . Item ) ;
255269 }
256270
257271 async void sink_ComponentReloaded ( object sender , DispatcherEventArgs < VBComponent > e )
@@ -364,7 +378,10 @@ public void Dispose()
364378 {
365379 item . Value . Item1 . Unadvise ( item . Value . Item2 ) ;
366380 }
367-
381+ foreach ( var item in _referencesEventsConnectionPoints )
382+ {
383+ item . Value . Item1 . Unadvise ( item . Value . Item2 ) ;
384+ }
368385 _hooks . Dispose ( ) ;
369386 }
370387 }
0 commit comments