diff --git a/RetailCoder.VBE/Common/Dispatch/DispatcherEventArgs.cs b/RetailCoder.VBE/Common/Dispatch/DispatcherEventArgs.cs index 6091125dfc..ba4ca0daa7 100644 --- a/RetailCoder.VBE/Common/Dispatch/DispatcherEventArgs.cs +++ b/RetailCoder.VBE/Common/Dispatch/DispatcherEventArgs.cs @@ -1,9 +1,8 @@ using System; -using Rubberduck.Parsing; namespace Rubberduck.Common.Dispatch { - public class DispatcherEventArgs : EventArgs, IDispatcherEventArgs + public class DispatcherEventArgs : EventArgs where T : class { private readonly T _item; diff --git a/RetailCoder.VBE/Common/Dispatch/DispatcherRenamedEventArgs.cs b/RetailCoder.VBE/Common/Dispatch/DispatcherRenamedEventArgs.cs index d84ac94b64..c69774882a 100644 --- a/RetailCoder.VBE/Common/Dispatch/DispatcherRenamedEventArgs.cs +++ b/RetailCoder.VBE/Common/Dispatch/DispatcherRenamedEventArgs.cs @@ -1,8 +1,6 @@ -using Rubberduck.Parsing; - -namespace Rubberduck.Common.Dispatch +namespace Rubberduck.Common.Dispatch { - public class DispatcherRenamedEventArgs : DispatcherEventArgs, IDispatcherRenamedEventArgs + public class DispatcherRenamedEventArgs : DispatcherEventArgs where T : class { private readonly string _oldName; diff --git a/RetailCoder.VBE/Extension.cs b/RetailCoder.VBE/Extension.cs index f3db33a08f..a57ba82a93 100644 --- a/RetailCoder.VBE/Extension.cs +++ b/RetailCoder.VBE/Extension.cs @@ -11,6 +11,7 @@ using System.Runtime.InteropServices; using System.Windows.Forms; using Ninject.Extensions.Interception; +using NLog; namespace Rubberduck { @@ -26,6 +27,7 @@ public class _Extension : IDTExtensibility2 private IKernel _kernel; private App _app; + private readonly Logger _logger = LogManager.GetCurrentClassLogger(); public void OnAddInsUpdate(ref Array custom) { @@ -50,6 +52,7 @@ public void OnConnection(object Application, ext_ConnectMode ConnectMode, object } catch (Exception exception) { + _logger.Fatal(exception); System.Windows.Forms.MessageBox.Show(exception.ToString(), RubberduckUI.RubberduckLoadFailure, MessageBoxButtons.OK, MessageBoxIcon.Error); } } diff --git a/RetailCoder.VBE/Rubberduck.csproj b/RetailCoder.VBE/Rubberduck.csproj index 0046866c26..7dfbbe5ef7 100644 --- a/RetailCoder.VBE/Rubberduck.csproj +++ b/RetailCoder.VBE/Rubberduck.csproj @@ -256,7 +256,6 @@ - False diff --git a/RetailCoder.VBE/Sinks.cs b/RetailCoder.VBE/Sinks.cs index 315a3e8e78..3e5e78dc23 100644 --- a/RetailCoder.VBE/Sinks.cs +++ b/RetailCoder.VBE/Sinks.cs @@ -1,12 +1,67 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices.ComTypes; +using System.Threading.Tasks; using Microsoft.Vbe.Interop; using Rubberduck.Common.Dispatch; using Rubberduck.Parsing; +using Rubberduck.VBEditor.Extensions; namespace Rubberduck { + public class ProjectEventArgs : EventArgs, IProjectEventArgs + { + public ProjectEventArgs(string projectId) + { + _projectId = projectId; + } + + private readonly string _projectId; + public string ProjectId { get { return _projectId; } } + } + + public class ProjectRenamedEventArgs : ProjectEventArgs, IProjectRenamedEventArgs + { + public ProjectRenamedEventArgs(string projectId, string oldName) : base(projectId) + { + _oldName = oldName; + } + + private readonly string _oldName; + public string OldName { get { return _oldName; } } + } + + public class ComponentEventArgs : EventArgs, IComponentEventArgs + { + public ComponentEventArgs(string projectId, string componentName, vbext_ComponentType type) + { + _projectId = projectId; + _componentName = componentName; + _type = type; + } + + private readonly string _projectId; + public string ProjectId { get { return _projectId; } } + + private readonly string _componentName; + public string ComponentName { get { return _componentName; } } + + private readonly vbext_ComponentType _type; + public vbext_ComponentType Type { get { return _type; } } + } + + public class ComponentRenamedEventArgs : ComponentEventArgs, IComponentRenamedEventArgs + { + public ComponentRenamedEventArgs(string projectId, string componentName, vbext_ComponentType type, string oldName) + : base(projectId, componentName, type) + { + _oldName = oldName; + } + + private readonly string _oldName; + public string OldName { get { return _oldName; } } + } + public class Sinks : ISinks, IDisposable { private VBProjectsEventsSink _sink; @@ -18,11 +73,6 @@ public class Sinks : ISinks, IDisposable private readonly IDictionary> _componentsEventsConnectionPoints = new Dictionary>(); - private readonly IDictionary _referencesEventsSinks = - new Dictionary(); - private readonly IDictionary> _referencesEventsConnectionPoints = - new Dictionary>(); - public bool IsEnabled { get; set; } public Sinks(VBE vbe) @@ -43,59 +93,78 @@ public Sinks(VBE vbe) #region ProjectEvents - public event EventHandler> ProjectActivated; - public event EventHandler> ProjectAdded; - public event EventHandler> ProjectRemoved; - public event EventHandler> ProjectRenamed; + public event EventHandler ProjectActivated; + public event EventHandler ProjectAdded; + public event EventHandler ProjectRemoved; + public event EventHandler ProjectRenamed; private void _sink_ProjectActivated(object sender, DispatcherEventArgs e) { if (!IsEnabled) { return; } + var projectId = e.Item.HelpFile; - var handler = ProjectActivated; - if (handler != null) + Task.Run(() => { - handler(sender, e); - } + var handler = ProjectActivated; + if (handler != null) + { + handler(sender, new ProjectEventArgs(projectId)); + } + }); } private void _sink_ProjectAdded(object sender, DispatcherEventArgs e) { if (!IsEnabled) { return; } - var handler = ProjectAdded; - if (handler != null) - { - handler(sender, e); - } + e.Item.AssignProjectId(); + var projectId = e.Item.HelpFile; - RegisterComponentsEventSink(e.Item.VBComponents, e.Item.HelpFile); - //RegisterReferencesEventSink(e.Item.References, e.Item.HelpFile); + Task.Run(() => + { + var handler = ProjectAdded; + if (handler != null) + { + handler(sender, new ProjectEventArgs(projectId)); + } + + RegisterComponentsEventSink(e.Item.VBComponents, e.Item.HelpFile); + }); } private void _sink_ProjectRemoved(object sender, DispatcherEventArgs e) { if (!IsEnabled) { return; } - var handler = ProjectRemoved; - if (handler != null) - { - handler(sender, e); - } + var projectId = e.Item.HelpFile; - UnregisterComponentsEventSink(e.Item.HelpFile); - //UnregisterReferencesEventSink(e.Item.HelpFile); + Task.Run(() => + { + var handler = ProjectRemoved; + if (handler != null) + { + handler(sender, new ProjectEventArgs(projectId)); + } + + UnregisterComponentsEventSink(e.Item.HelpFile); + }); } private void _sink_ProjectRenamed(object sender, DispatcherRenamedEventArgs e) { if (!IsEnabled) { return; } - var handler = ProjectRenamed; - if (handler != null) + var projectId = e.Item.HelpFile; + var oldName = e.OldName; + + Task.Run(() => { - handler(sender, e); - } + var handler = ProjectRenamed; + if (handler != null) + { + handler(sender, new ProjectRenamedEventArgs(projectId, oldName)); + } + }); } #endregion @@ -148,21 +217,24 @@ private void UnregisterComponentsEventSink(string projectId) _componentsEventsConnectionPoints.Remove(projectId); } - public event EventHandler> ComponentActivated; - public event EventHandler> ComponentAdded; - public event EventHandler> ComponentReloaded; - public event EventHandler> ComponentRemoved; - public event EventHandler> ComponentRenamed; - public event EventHandler> ComponentSelected; + public event EventHandler ComponentActivated; + public event EventHandler ComponentAdded; + public event EventHandler ComponentReloaded; + public event EventHandler ComponentRemoved; + public event EventHandler ComponentRenamed; + public event EventHandler ComponentSelected; private void ComponentsSink_ComponentActivated(object sender, DispatcherEventArgs e) { if (!IsEnabled) { return; } + var projectId = e.Item.Collection.Parent.HelpFile; + var componentName = e.Item.Name; + var handler = ComponentActivated; if (handler != null) { - handler(sender, e); + handler(sender, new ComponentEventArgs(projectId, componentName, e.Item.Type)); } } @@ -170,10 +242,13 @@ private void ComponentsSink_ComponentAdded(object sender, DispatcherEventArgs> ReferenceAdded; - //public event EventHandler> ReferenceRemoved; - - //private void ReferencesSink_ReferenceAdded(object sender, DispatcherEventArgs e) - //{ - // if (!IsEnabled) { return; } - - // var handler = ReferenceAdded; - // if (handler != null) - // { - // handler(sender, e); - // } - //} - - //private void ReferencesSink_ReferenceRemoved(object sender, DispatcherEventArgs e) - //{ - // if (!IsEnabled) { return; } - - // var handler = ReferenceRemoved; - // if (handler != null) - // { - // handler(sender, e); - // } - //} - //#endregion - public void Dispose() { if (_sink != null) @@ -315,21 +336,10 @@ public void Dispose() item.Value.ComponentSelected -= ComponentsSink_ComponentSelected; } - /*foreach (var item in _referencesEventsSinks) - { - item.Value.ReferenceAdded -= ReferencesSink_ReferenceAdded; - item.Value.ReferenceRemoved -= ReferencesSink_ReferenceRemoved; - }*/ - foreach (var item in _componentsEventsConnectionPoints) { item.Value.Item1.Unadvise(item.Value.Item2); } - - foreach (var item in _referencesEventsConnectionPoints) - { - item.Value.Item1.Unadvise(item.Value.Item2); - } } } } \ No newline at end of file diff --git a/RetailCoder.VBE/UI/RubberduckUI.de.resx b/RetailCoder.VBE/UI/RubberduckUI.de.resx index 27210a323c..c0f2878211 100644 --- a/RetailCoder.VBE/UI/RubberduckUI.de.resx +++ b/RetailCoder.VBE/UI/RubberduckUI.de.resx @@ -1,4 +1,4 @@ - + - + @@ -705,9 +705,6 @@ Warnung: Alle eigenen Einstellungen gehen dabei verloren. Die Originaldatei wird '.gitignore' Datei - - Neues Repo auf Basis dieses Projektes erstellen - Ausstehende Änderungen aktualisieren @@ -1099,7 +1096,7 @@ Warnung: Alle eigenen Einstellungen gehen dabei verloren. Die Originaldatei wird Spätes Binden - Tolereante Forderung + Tolerante Forderung Strikte Forderung @@ -1276,9 +1273,6 @@ Fugue Icons von Yusuke Kamiyamane Allen Sternguckern, Likern & Followern, für das warme Kribbeln … und jedem der dies leist. - - Repository löschen - Zweigname: @@ -1354,9 +1348,6 @@ Allen Sternguckern, Likern & Followern, für das warme Kribbeln Fehler beim Auflösen - - Löse auf ... - Blogs: @@ -1499,7 +1490,7 @@ Allen Sternguckern, Likern & Followern, für das warme Kribbeln Ordner-Trennzeichen: - Slash (/) + Schrägstrich (/) Fehlende Zugangsdaten @@ -1516,9 +1507,6 @@ Allen Sternguckern, Likern & Followern, für das warme Kribbeln Commit Status. - - Nach Auswahl - Nach Typ @@ -1556,10 +1544,10 @@ Allen Sternguckern, Likern & Followern, für das warme Kribbeln Parserfehler - Minimum Log Level + Minimale Logging-Empfindlichkeit - Debug + Debugging Fehler @@ -1568,13 +1556,13 @@ Allen Sternguckern, Likern & Followern, für das warme Kribbeln Fatal - Info + Informationen Kein Logging - Trace + Spuren Warnung @@ -1583,24 +1571,132 @@ Allen Sternguckern, Likern & Followern, für das warme Kribbeln Logging-Ordner anzeigen - + ..\Resources\information.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a In Zwischenablage kopieren - + ..\Resources\cross-circle.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a Veröffentliche Repository - - Veröffentliche Repository auf Github - Kein geöffnetes Repository verfügbar, um es auf den Remote-Pfad zu veröffentlichen Eine Quelldatei wurde außerhalb des VBA-Editors geändert. Soll Rubberduck diese nachladen? - \ No newline at end of file + + Neues Repository initialisieren + + + Fehler beim öffnen der Eingabeaufforderung + + + Unverändert + + + Fehlt + + + Im Arbeitsverzeichnis umbenannt + + + Veröffentlicht ein existierendes Repository zu einem entfernten Repository. Das offene Projekt muss dazu mit einem Repository verbunden sein. + + + Standard Repository-Pfad + + + Bitte setzen Sie die Logging-Empfindlichkeit auf Fatal oder niedriger und erstellen Sie ein Ticket auf unserer GitHub-Seite mit dem Inhalt Ihrer Logdatei in C:\Users\{username}\AppData\Roaming\Rubberduck\Logs. + + + Unlesbar + + + Im Index umbenannt + + + Neues Repository mit dem geöffneten Projekt erstellen. + + + Vorgemerkt + + + Nicht verfolgt + + + Speicherort der Eingabeaufforderung (cmd.exe / powershell.exe) + + + Klont das entfernte Repository von der angegebenen URL. Dazu muss ein leeres Projekt in der VBE geöffnet sein. + + + Klone entferntes Repository + + + Projekteigenschaften öffnen + + + Kein aktives VBProject + + + Bitte öffnen oder aktivieren Sie ein Projekt und versuchen Sie es erneut. + + + Existierendes Repository öffnen. + + + Existierendes Repository Veröffentlichen + + + Ignoriert + + + Ein unbekannter Fehler ist aufgetreten. + + + Eingabeaufforderung öffnen + + + Nach Deklarationsreihenfolge + + + Gelöscht + + + Löse Referenzen auf... + + + Typ geändert + + + Eingabeaufforderung + + + Repository von der Festplatte öffnen. Dazu muss ein leeres Projekt in der VBE geöffnet sein. + + + Nicht Vorhanden + + + Geändert + + + Verwalten + + + Änderung der Vormerkung + + + Löse Deklarationen auf... + + + Hinzugefügt + + + In Rubberduck ist ein Fehler aufgetreten. Bitte speichern Sie Ihre Arbeit und starten Sie das Hostprogramm neu. Laden Sie dann Ihre Logdatei zu unserer GitHub-Seite hoch. + + diff --git a/RetailCoder.VBE/UI/SourceControl/SourceControlView.xaml b/RetailCoder.VBE/UI/SourceControl/SourceControlView.xaml index 3a596f7a81..ce26a7f3f6 100644 --- a/RetailCoder.VBE/UI/SourceControl/SourceControlView.xaml +++ b/RetailCoder.VBE/UI/SourceControl/SourceControlView.xaml @@ -1,4 +1,4 @@ - @@ -289,7 +288,7 @@ - + @@ -307,7 +306,7 @@ - + @@ -380,7 +379,7 @@ - + @@ -395,7 +394,7 @@ - + diff --git a/RetailCoder.VBE/UI/SourceControl/SourceControlViewViewModel.cs b/RetailCoder.VBE/UI/SourceControl/SourceControlViewViewModel.cs index 0fdb9b808b..61d139d009 100644 --- a/RetailCoder.VBE/UI/SourceControl/SourceControlViewViewModel.cs +++ b/RetailCoder.VBE/UI/SourceControl/SourceControlViewViewModel.cs @@ -115,50 +115,50 @@ public void SetTab(SourceControlTab tab) SelectedItem = TabItems.First(t => t.ViewModel.Tab == tab); } - private void ComponentAdded(object sender, IDispatcherEventArgs e) + private void ComponentAdded(object sender, IComponentEventArgs e) { if (Provider == null || !Provider.HandleVbeSinkEvents) { return; } - if (e.Item.Collection.Parent.HelpFile != Provider.CurrentRepository.Id) + if (e.ProjectId != Provider.CurrentRepository.Id) { return; } - Logger.Trace("Component {0} added", e.Item.Name); - var fileStatus = Provider.Status().SingleOrDefault(stat => stat.FilePath.Split('.')[0] == e.Item.Name); + Logger.Trace("Component {0} added", e.ComponentName); + var fileStatus = Provider.Status().SingleOrDefault(stat => stat.FilePath.Split('.')[0] == e.ComponentName); if (fileStatus != null) { Provider.AddFile(fileStatus.FilePath); } } - private void ComponentRemoved(object sender, IDispatcherEventArgs e) + private void ComponentRemoved(object sender, IComponentEventArgs e) { if (Provider == null || !Provider.HandleVbeSinkEvents) { return; } - if (e.Item.Collection.Parent.HelpFile != Provider.CurrentRepository.Id) + if (e.ProjectId != Provider.CurrentRepository.Id) { return; } - Logger.Trace("Component {0] removed", e.Item.Name); - var fileStatus = Provider.Status().SingleOrDefault(stat => stat.FilePath.Split('.')[0] == e.Item.Name); + Logger.Trace("Component {0] removed", e.ComponentName); + var fileStatus = Provider.Status().SingleOrDefault(stat => stat.FilePath.Split('.')[0] == e.ComponentName); if (fileStatus != null) { Provider.RemoveFile(fileStatus.FilePath, true); } } - private void ComponentRenamed(object sender, IDispatcherRenamedEventArgs e) + private void ComponentRenamed(object sender, IComponentRenamedEventArgs e) { if (Provider == null || !Provider.HandleVbeSinkEvents) { return; } - if (e.Item.Collection.Parent.HelpFile != Provider.CurrentRepository.Id) + if (e.ProjectId != Provider.CurrentRepository.Id) { return; } - Logger.Trace("Component {0} renamed to {1}", e.OldName, e.Item.Name); + Logger.Trace("Component {0} renamed to {1}", e.OldName, e.ComponentName); var fileStatus = Provider.LastKnownStatus().SingleOrDefault(stat => stat.FilePath.Split('.')[0] == e.OldName); if (fileStatus != null) { @@ -168,11 +168,11 @@ private void ComponentRenamed(object sender, IDispatcherRenamedEventArgs - where T : class + public interface IProjectEventArgs { - T Item { get; } + string ProjectId { get; } } - public interface IDispatcherRenamedEventArgs : IDispatcherEventArgs - where T : class + public interface IProjectRenamedEventArgs : IProjectEventArgs + { + string OldName { get; } + } + + public interface IComponentEventArgs + { + string ProjectId { get; } + string ComponentName { get; } + vbext_ComponentType Type { get; } + } + + public interface IComponentRenamedEventArgs : IComponentEventArgs { string OldName { get; } } @@ -19,17 +29,17 @@ public interface ISinks { bool IsEnabled { get; set; } - event EventHandler> ProjectActivated; - event EventHandler> ProjectAdded; - event EventHandler> ProjectRemoved; - event EventHandler> ProjectRenamed; - - event EventHandler> ComponentActivated; - event EventHandler> ComponentAdded; - event EventHandler> ComponentReloaded; - event EventHandler> ComponentRemoved; - event EventHandler> ComponentRenamed; - event EventHandler> ComponentSelected; + event EventHandler ProjectActivated; + event EventHandler ProjectAdded; + event EventHandler ProjectRemoved; + event EventHandler ProjectRenamed; + + event EventHandler ComponentActivated; + event EventHandler ComponentAdded; + event EventHandler ComponentReloaded; + event EventHandler ComponentRemoved; + event EventHandler ComponentRenamed; + event EventHandler ComponentSelected; //event EventHandler> ReferenceAdded; //event EventHandler> ReferenceRemoved; diff --git a/Rubberduck.Parsing/VBA/RubberduckParser.cs b/Rubberduck.Parsing/VBA/RubberduckParser.cs index 5d349f41b1..a911561776 100644 --- a/Rubberduck.Parsing/VBA/RubberduckParser.cs +++ b/Rubberduck.Parsing/VBA/RubberduckParser.cs @@ -106,7 +106,7 @@ public void Parse() { foreach (var project in _vbe.VBProjects.UnprotectedProjects()) { - State.AddProject(project); + State.AddProject(project.HelpFile); } } @@ -188,7 +188,7 @@ private void ParseAll() { foreach (var project in _vbe.VBProjects.UnprotectedProjects()) { - State.AddProject(project); + State.AddProject(project.HelpFile); } } diff --git a/Rubberduck.Parsing/VBA/RubberduckParserState.cs b/Rubberduck.Parsing/VBA/RubberduckParserState.cs index 7215d263ce..89a15bba8a 100644 --- a/Rubberduck.Parsing/VBA/RubberduckParserState.cs +++ b/Rubberduck.Parsing/VBA/RubberduckParserState.cs @@ -90,38 +90,27 @@ public RubberduckParserState(VBE vbe, ISinks sinks) sinks.ComponentRenamed += Sinks_ComponentRenamed; } - private void Sinks_ProjectAdded(object sender, IDispatcherEventArgs e) + private void Sinks_ProjectAdded(object sender, IProjectEventArgs e) { if (!_vbe.IsInDesignMode()) { return; } - Logger.Debug("Project '{0}' was added.", e.Item.Name); - if (e.Item.Protection == vbext_ProjectProtection.vbext_pp_locked) - { - Logger.Debug("Project is protected and will not be added to parser state."); - return; - } + Logger.Debug("Project '{0}' was added.", e.ProjectId); - AddProject(e.Item); // note side-effect: assigns ProjectId/HelpFile + AddProject(e.ProjectId); // note side-effect: assigns ProjectId/HelpFile OnParseRequested(sender); } - private void Sinks_ProjectRemoved(object sender, IDispatcherEventArgs e) + private void Sinks_ProjectRemoved(object sender, IProjectEventArgs e) { if (!_vbe.IsInDesignMode()) { return; } - - if (e.Item.Protection == vbext_ProjectProtection.vbext_pp_locked) - { - return; - } - var projectId = e.Item.HelpFile; - Debug.Assert(projectId != null); + Debug.Assert(e.ProjectId != null); - RemoveProject(e.Item); + RemoveProject(e.ProjectId); OnParseRequested(sender); } - private void Sinks_ProjectRenamed(object sender, IDispatcherRenamedEventArgs e) + private void Sinks_ProjectRenamed(object sender, IProjectRenamedEventArgs e) { if (!_vbe.IsInDesignMode()) { return; } @@ -130,15 +119,15 @@ private void Sinks_ProjectRenamed(object sender, IDispatcherRenamedEventArgs e) + private void Sinks_ComponentAdded(object sender, IComponentEventArgs e) { if (!_vbe.IsInDesignMode()) { return; } @@ -147,11 +136,11 @@ private void Sinks_ComponentAdded(object sender, IDispatcherEventArgs e) + private void Sinks_ComponentRemoved(object sender, IComponentEventArgs e) { if (!_vbe.IsInDesignMode()) { return; } @@ -160,11 +149,11 @@ private void Sinks_ComponentRemoved(object sender, IDispatcherEventArgs e) + private void Sinks_ComponentRenamed(object sender, IComponentRenamedEventArgs e) { if (!_vbe.IsInDesignMode()) { return; } @@ -173,9 +162,40 @@ private void Sinks_ComponentRenamed(object sender, IDispatcherRenamedEventArgs(); + foreach (VBProject p in _vbe.VBProjects) { - // adding protected project to parser state is asking for COMExceptions.. - return; - } + if (p.HelpFile != null && _projects.Keys.Contains(p.HelpFile)) + { + continue; + } - //assign a hashcode if no helpfile is present - if (string.IsNullOrEmpty(project.HelpFile)) - { - project.HelpFile = project.GetHashCode().ToString(); + projects.Add(p); } - //loop until the helpfile is unique for this host session - while (!IsProjectIdUnique(project.HelpFile)) + if (projects.Count == 0) { - project.HelpFile = (project.GetHashCode() ^ project.HelpFile.GetHashCode()).ToString(); + Logger.Debug("Project was not found and will not be added to parser state."); + return; } - var projectId = project.HelpFile; - if (!_projects.ContainsKey(projectId)) + foreach (var project in projects) { - _projects.Add(projectId, project); - } + if (project.Protection == vbext_ProjectProtection.vbext_pp_locked) + { + // adding protected project to parser state is asking for COMExceptions.. + Logger.Debug("Project is protected and will not be added to parser state."); + return; + } - foreach (VBComponent component in project.VBComponents) - { - _moduleStates.TryAdd(new QualifiedModuleName(component), new ModuleState(ParserState.Pending)); - } - } + if (string.IsNullOrEmpty(project.HelpFile)) + { + // assigns the help file and returns the value to reduce COM calls + projectId = project.AssignProjectId(); + } - private bool IsProjectIdUnique(string id) - { - foreach (var project in _projects) - { - if (project.Key == id) + if (!_projects.ContainsKey(projectId)) { - return false; + _projects.Add(projectId, project); } - } - return true; + foreach (VBComponent component in project.VBComponents) + { + _moduleStates.TryAdd(new QualifiedModuleName(component), new ModuleState(ParserState.Pending)); + } + } } - public void RemoveProject(string projectId) + private void RemoveProject(string projectId) { VBProject project = null; foreach (var p in Projects) @@ -257,12 +278,6 @@ public void RemoveProject(string projectId) } } - public void RemoveProject(VBProject project) - { - RemoveProject(project.HelpFile); - ClearStateCache(project); - } - public List Projects { get @@ -666,7 +681,7 @@ public void AddDeclaration(Declaration declaration) } } - public void ClearStateCache(VBProject project, bool notifyStateChanged = false) + private void ClearStateCache(VBProject project, bool notifyStateChanged = false) { try { @@ -817,13 +832,12 @@ public bool ClearStateCache(QualifiedModuleName component, bool notifyStateChang return success; } - public bool RemoveRenamedComponent(VBComponent component, string oldComponentName) + private bool RemoveRenamedComponent(string projectId, string oldComponentName) { - var match = new QualifiedModuleName(component, oldComponentName); var keys = new List(); foreach (var key in _moduleStates.Keys) { - if (key.ComponentName == oldComponentName && key.ProjectId == match.ProjectId) + if (key.ComponentName == oldComponentName && key.ProjectId == projectId) { keys.Add(key); } @@ -837,9 +851,6 @@ public bool RemoveRenamedComponent(VBComponent component, string oldComponentNam OnStateChanged(ParserState.Ready); // trigger find all references &c. updates } - _projects.Remove(match.ProjectId); - _projects.Add(match.ProjectId, component.Collection.Parent); - return success; } diff --git a/Rubberduck.VBEEditor/Extensions/VbProjectExtensions.cs b/Rubberduck.VBEEditor/Extensions/VbProjectExtensions.cs index 29ecec15dc..8ac4e716cf 100644 --- a/Rubberduck.VBEEditor/Extensions/VbProjectExtensions.cs +++ b/Rubberduck.VBEEditor/Extensions/VbProjectExtensions.cs @@ -7,6 +7,38 @@ namespace Rubberduck.VBEditor.Extensions { public static class ProjectExtensions { + public static string AssignProjectId(this VBProject project) + { + //assign a hashcode if no helpfile is present + if (string.IsNullOrEmpty(project.HelpFile)) + { + project.HelpFile = project.GetHashCode().ToString(); + } + + //loop until the helpfile is unique for this host session + while (!IsProjectIdUnique(project.HelpFile, project.VBE)) + { + project.HelpFile = (project.GetHashCode() ^ project.HelpFile.GetHashCode()).ToString(); + } + + return project.HelpFile; + } + + private static bool IsProjectIdUnique(string id, VBE vbe) + { + var projectsWithId = 0; + + foreach (VBProject project in vbe.VBProjects) + { + if (project.HelpFile == id) + { + projectsWithId++; + } + } + + return projectsWithId == 1; + } + public static IEnumerable UnprotectedProjects(this VBProjects projects) { return projects.Cast().Where(project => project.Protection == vbext_ProjectProtection.vbext_pp_none); diff --git a/Rubberduck.VBEEditor/QualifiedModuleName.cs b/Rubberduck.VBEEditor/QualifiedModuleName.cs index 14247ba752..004e63bf16 100644 --- a/Rubberduck.VBEEditor/QualifiedModuleName.cs +++ b/Rubberduck.VBEEditor/QualifiedModuleName.cs @@ -181,16 +181,6 @@ public QualifiedModuleName(VBComponent component, string oldComponentName) _projectId = GetProjectId(_project); _contentHashCode = 0; - if (component == null) - { - return; - } - - var module = component.CodeModule; - _contentHashCode = module.CountOfLines > 0 - // ReSharper disable once UseIndexedProperty - ? module.get_Lines(1, module.CountOfLines).GetHashCode() - : 0; } ///