diff --git a/README.md b/README.md index 8388b1a8bd..eb27668a22 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,27 @@ -![banner](https://user-images.githubusercontent.com/5751684/113501222-8edfe880-94f1-11eb-99a9-64583e413ef3.png) + -[**Installing**](https://github.com/rubberduck-vba/Rubberduck/wiki/Installing) • [Contributing](https://github.com/rubberduck-vba/Rubberduck/blob/next/CONTRIBUTING.md) • [Attributions](https://github.com/rubberduck-vba/Rubberduck/blob/next/docs/Attributions.md) • [Blog](https://rubberduckvba.blog) • [Wiki](https://github.com/rubberduck-vba/Rubberduck/wiki) • [rubberduckvba.com](https://rubberduckvba.com) +## Links -## Build Status +- [**Installing**](https://github.com/rubberduck-vba/Rubberduck/wiki/Installing) +- [Contributing](https://github.com/rubberduck-vba/Rubberduck/blob/next/CONTRIBUTING.md) +- [Attributions](https://github.com/rubberduck-vba/Rubberduck/blob/next/docs/Attributions.md) +- [Wiki](https://github.com/rubberduck-vba/Rubberduck/wiki) +- [Website](https://rubberduckvba.com) +- [Blog](https://rubberduckvba.blog) +- [Shop](https://ko-fi.com/rubberduckvba/shop) -|Branch | Build Status | Release notes & Download Links | Donate | -|------------|--------------|-|:---:| -| **main** | ![main branch build status][mainBuildStatus] | [latest release](https://github.com/rubberduck-vba/Rubberduck/releases/latest) | Donate via PayPal| -| **next** | ![next branch build status][nextBuildStatus] | [pre-releases](https://github.com/rubberduck-vba/Rubberduck/releases) |

via PayPal

Pays for website and blog hosting fees. Donations in excess of our needs are going to Multiple Sclerosis Society of Canada. | +Support us on ko-fi.com -[nextBuildStatus]:https://ci.appveyor.com/api/projects/status/we3pdnkeebo4nlck/branch/next?svg=true -[mainBuildStatus]:https://ci.appveyor.com/api/projects/status/we3pdnkeebo4nlck/branch/main?svg=true +## Releases + +- The [latest release](https://github.com/rubberduck-vba/Rubberduck/releases/latest) +- See [all releases](https://github.com/rubberduck-vba/Rubberduck/releases) including pre-release tags --- ## [License (GPLv3)](https://github.com/rubberduck-vba/Rubberduck/blob/next/LICENSE) -Copyright © 2014-2021 Rubberduck project contributors. +Copyright © 2014-2023 Rubberduck project contributors. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @@ -24,16 +29,6 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY --- -## [JetBrains](https://www.jetbrains.com) | [ReSharper](https://www.jetbrains.com/resharper/) - -[![JetBrains ReSharper logo](https://cloud.githubusercontent.com/assets/5751684/20271309/616bb740-aa58-11e6-91c9-65287b740985.png)](https://www.jetbrains.com/resharper/) - -Since the project's early days, JetBrains' Open-Source team has been supporting Rubberduck with free OSS licenses for all core contributors - and we deeply thank them for that. ReSharper has been not only a tool we couldn't do without; it's been an inspiration, the ultimate level of polished perfection to strive for in our own IDE add-in project. So just like you're missing out if you write VBA and you're not using Rubberduck, you're missing out if you write C# and aren't using ReSharper. - -Note: Rubberduck is not a JetBrains product. JetBrains does not contribute and is not affiliated to the Rubberduck project in any way. - ---- - ## What is Rubberduck? The Visual Basic Editor (VBE) has stood still for over 20 years, and there is no chance a first-party update to the legacy IDE ever brings it up to speed with modern-day tooling. Rubberduck aims to bring the VBE into this century by doing exactly that. @@ -42,11 +37,11 @@ Read more about contributing here: [![contribute!](https://user-images.githubusercontent.com/5751684/113513709-071dcc80-9539-11eb-833d-d21532065306.png)](https://github.com/rubberduck-vba/Rubberduck/blob/next/CONTRIBUTING.md) -The add-in has *many* features - below is a quick overview. +The add-in has *many* features - below is a quick overview. See https://rubberduckvba.com/features for more details. ### Enhanced Navigation -The Rubberduck *command bar* displays docstring for the current member +The Rubberduck *command bar* displays docstring for the current member. ![command bar](https://user-images.githubusercontent.com/5751684/113501975-25fb6f00-94f7-11eb-9189-fcf2a0dd98da.png) @@ -56,9 +51,9 @@ All references to any identifier, whether defined in your project or any of its ### Static Code Analysis, Refactorings -Rubberduck analyses your code in various configurable ways and can help avoiding beginner mistakes, keeping a consistent programming style, and finding all sorts of potential bugs and problems. Many code inspections were implemented as a result of frequently-asked [VBA questions on Stack Overflow](https://stackoverflow.com/questions/tagged/vba), and in many occasions an automatic quick-fix is available. +Rubberduck analyses your code in various configurable ways and can help avoid beginner mistakes, keep a consistent programming style, and find all sorts of potential bugs and problems. Many code inspections were implemented due to frequently-asked [VBA questions on Stack Overflow](https://stackoverflow.com/questions/tagged/vba), and on many occasions, an automatic quick-fix is available. -Rename variables to meaningful identifiers without worrying about breaking something. Promote local variables to parameters, extract interfaces and methods out of a selection, encapsulate fields into properties; reorder and/or delete parameters, and automatically update all callers. +Rename variables to meaningful identifiers without worrying about breaking something. Promote local variables to parameters, extract interfaces and methods from a selection, encapsulate fields into properties, reorder and/or delete parameters, and automatically update all callers. ### Unit Testing @@ -76,7 +71,7 @@ Special comments that become a game changer with Rubberduck processing them: org ### More? -Of course there's more! There's tooling to help synchronizing the project with files in a folder (for source/version control), some auto-completion features like self-closing parentheses and quotes; there's a regular expression assistant, a replacement for the VBE's *add/remove references* dialog, and so many other things to discover, and yet even more to implement. +Of course there's more! There's tooling to help synchronizing the project with files in a folder (useful for source/version control!), some auto-completion features like self-closing parentheses and quotes; there's a regular expression assistant, a replacement for the VBE's *add/remove references* dialog, and so many other things to discover, and yet even more to implement. --- @@ -89,6 +84,28 @@ Rubberduck isn't a lightweight add-in and consumes a large amount of memory. So - **Review inspection settings**: there are *many* inspections, and some of them may produce *a lot* of results if they're directly targeting something that's part of your coding style. Spawning tens of thousands of inspection results can significantly degrade performance. - **Avoid late binding**: Rubberduck cannot resolve identifier references and thus cannot understand the code as well if even the VBA compiler is deferring all validations to run-time. Declare and return explicit data types, and cast from `Object` and `Variant` to a more specific type whenever possible. -Join us on our [Discord server](https://discord.gg/EmbYjbPr) for support, questions, contributions, or just to come and say hi! +Join us on our [Discord server](https://discord.gg/MYX9RECenJ) for support, questions, contributions, or just to come and say hi! For more information please see [Getting Started](https://github.com/rubberduck-vba/Rubberduck/blob/next/docs/GettingStarted.md) in the project's wiki, and follow the project's blog for project updates and advanced VBA OOP reading material. + +--- + +## Roadmap + +After over two years without an "official" new release, Rubberduck version jumped from 2.5.2 to 2.5.9, adding minor but interesting features to an already impressive array. + +### The road ahead + +Rubberduck 2.x is now planned to end at 2.5.9.x, perhaps with a number of small revisions and bug fixes, but nothing major should be expected, as the developers' attention is shifting to the 3.0 project: + +- Parsing and understanding VBA code is moving to a language (LSP) server +- We're making a new editor _inside_ (for now) the Visual Basic Editor that will be the LSP client +- Baseline server-side feature set for 3.0 is everything 2.5.9 does +- Baseline client-side feature set for 3.0 is the 2.5.x UI (perhaps tweaked a bit/lot) hosted in the Rubberduck Editor + +Fully controlling the editor opens Rubberduck to everything we ever dreamed of: + +- In-editor syntax and static code analysis reporting and quick-fixing +- Full editor theming, custom syntax highlighting + +See the [Rubberduck3](https://github.com/rubberduck-vba/Rubberduck3) repository for more information. diff --git a/Rubberduck.CodeAnalysis/CodeAnalysisUI.Designer.cs b/Rubberduck.CodeAnalysis/CodeAnalysisUI.Designer.cs new file mode 100644 index 0000000000..4d3597979d --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodeAnalysisUI.Designer.cs @@ -0,0 +1,497 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Rubberduck.CodeAnalysis { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class CodeAnalysisUI { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal CodeAnalysisUI() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Rubberduck.CodeAnalysis.CodeAnalysisUI", typeof(CodeAnalysisUI).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Issue. + /// + public static string CodeInspectionResults_Issue { + get { + return ResourceManager.GetString("CodeInspectionResults_Issue", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Location. + /// + public static string CodeInspectionResults_Location { + get { + return ResourceManager.GetString("CodeInspectionResults_Location", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type. + /// + public static string CodeInspectionResults_Type { + get { + return ResourceManager.GetString("CodeInspectionResults_Type", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Code Inspections. + /// + public static string CodeInspections { + get { + return ResourceManager.GetString("CodeInspections", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Inspecting.... + /// + public static string CodeInspections_Inspecting { + get { + return ResourceManager.GetString("CodeInspections_Inspecting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rubberduck Code Inspections - {0} + ///{1} issues found.. + /// + public static string CodeInspections_NumberOfIssuesFound_Plural { + get { + return ResourceManager.GetString("CodeInspections_NumberOfIssuesFound_Plural", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Rubberduck Code Inspections - {0} + ///{1} issue found.. + /// + public static string CodeInspections_NumberOfIssuesFound_Singular { + get { + return ResourceManager.GetString("CodeInspections_NumberOfIssuesFound_Singular", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Description:. + /// + public static string CodeInspectionSettingsPage_FilterByDescription { + get { + return ResourceManager.GetString("CodeInspectionSettingsPage_FilterByDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Severity:. + /// + public static string CodeInspectionSettingsPage_FilterBySeverity { + get { + return ResourceManager.GetString("CodeInspectionSettingsPage_FilterBySeverity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Inspection Severities. + /// + public static string CodeInspectionSettingsPage_InspectionSeveritySettingsLabel { + get { + return ResourceManager.GetString("CodeInspectionSettingsPage_InspectionSeveritySettingsLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Miscellaneous. + /// + public static string CodeInspectionSettingsPage_Misc { + get { + return ResourceManager.GetString("CodeInspectionSettingsPage_Misc", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Run inspections automatically on successful parse. + /// + public static string CodeInspectionSettingsPage_Misc_RunInspectionsOnSuccessfulParse { + get { + return ResourceManager.GetString("CodeInspectionSettingsPage_Misc_RunInspectionsOnSuccessfulParse", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to These identifiers will be ignored by the 'Use meaningful names' inspection.. + /// + public static string CodeInspectionSettingsPage_WhitelistedIdentifiersDescription { + get { + return ResourceManager.GetString("CodeInspectionSettingsPage_WhitelistedIdentifiersDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Allowed Identifiers. + /// + public static string CodeInspectionSettingsPage_WhitelistedIdentifiersLabel { + get { + return ResourceManager.GetString("CodeInspectionSettingsPage_WhitelistedIdentifiersLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cyclomatic Complexity. + /// + public static string CodeMetrics_Complexity { + get { + return ResourceManager.GetString("CodeMetrics_Complexity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Lines. + /// + public static string CodeMetrics_Lines { + get { + return ResourceManager.GetString("CodeMetrics_Lines", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Maximum Nesting. + /// + public static string CodeMetrics_Nesting { + get { + return ResourceManager.GetString("CodeMetrics_Nesting", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Code Metrics. + /// + public static string CodeMetricsDockablePresenter_Caption { + get { + return ResourceManager.GetString("CodeMetricsDockablePresenter_Caption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The following project(s) cannot be compiled, which will most likely result in parser errors. Continue anyway? {0}. + /// + public static string Command_Reparse_CannotCompile { + get { + return ResourceManager.GetString("Command_Reparse_CannotCompile", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unable to compile for parsing.. + /// + public static string Command_Reparse_CannotCompile_Caption { + get { + return ResourceManager.GetString("Command_Reparse_CannotCompile_Caption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The VBE setting "Compile On Demand" is currently enabled. This is not recommended as this may hide compilation errors and cause problems with parsing. Do you want to parse anyway?. + /// + public static string Command_Reparse_CompileOnDemandEnabled { + get { + return ResourceManager.GetString("Command_Reparse_CompileOnDemandEnabled", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Compile On Demand Setting. + /// + public static string Command_Reparse_CompileOnDemandEnabled_Caption { + get { + return ResourceManager.GetString("Command_Reparse_CompileOnDemandEnabled_Caption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to runtime expression. + /// + public static string DeclarationType_BracketedExpression { + get { + return ResourceManager.GetString("DeclarationType_BracketedExpression", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to class. + /// + public static string DeclarationType_ClassModule { + get { + return ResourceManager.GetString("DeclarationType_ClassModule", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to constant. + /// + public static string DeclarationType_Constant { + get { + return ResourceManager.GetString("DeclarationType_Constant", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to control. + /// + public static string DeclarationType_Control { + get { + return ResourceManager.GetString("DeclarationType_Control", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to enum. + /// + public static string DeclarationType_Enumeration { + get { + return ResourceManager.GetString("DeclarationType_Enumeration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to enum member. + /// + public static string DeclarationType_EnumerationMember { + get { + return ResourceManager.GetString("DeclarationType_EnumerationMember", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to event. + /// + public static string DeclarationType_Event { + get { + return ResourceManager.GetString("DeclarationType_Event", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to function. + /// + public static string DeclarationType_Function { + get { + return ResourceManager.GetString("DeclarationType_Function", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to library function. + /// + public static string DeclarationType_LibraryFunction { + get { + return ResourceManager.GetString("DeclarationType_LibraryFunction", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to library procedure. + /// + public static string DeclarationType_LibraryProcedure { + get { + return ResourceManager.GetString("DeclarationType_LibraryProcedure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to line label. + /// + public static string DeclarationType_LineLabel { + get { + return ResourceManager.GetString("DeclarationType_LineLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to parameter. + /// + public static string DeclarationType_Parameter { + get { + return ResourceManager.GetString("DeclarationType_Parameter", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to module. + /// + public static string DeclarationType_ProceduralModule { + get { + return ResourceManager.GetString("DeclarationType_ProceduralModule", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to procedure. + /// + public static string DeclarationType_Procedure { + get { + return ResourceManager.GetString("DeclarationType_Procedure", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to project. + /// + public static string DeclarationType_Project { + get { + return ResourceManager.GetString("DeclarationType_Project", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to property get accessor. + /// + public static string DeclarationType_PropertyGet { + get { + return ResourceManager.GetString("DeclarationType_PropertyGet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to property let accessor. + /// + public static string DeclarationType_PropertyLet { + get { + return ResourceManager.GetString("DeclarationType_PropertyLet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to property set accessor. + /// + public static string DeclarationType_PropertySet { + get { + return ResourceManager.GetString("DeclarationType_PropertySet", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to user-defined type. + /// + public static string DeclarationType_UserDefinedType { + get { + return ResourceManager.GetString("DeclarationType_UserDefinedType", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to user-defined type member. + /// + public static string DeclarationType_UserDefinedTypeMember { + get { + return ResourceManager.GetString("DeclarationType_UserDefinedTypeMember", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to variable. + /// + public static string DeclarationType_Variable { + get { + return ResourceManager.GetString("DeclarationType_Variable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You've earned the "Continuator" badge!. + /// + public static string EasterEgg_Continuator { + get { + return ResourceManager.GetString("EasterEgg_Continuator", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Ignore. + /// + public static string EmptyLineHandling_Ignore { + get { + return ResourceManager.GetString("EmptyLineHandling_Ignore", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Indent. + /// + public static string EmptyLineHandling_Indent { + get { + return ResourceManager.GetString("EmptyLineHandling_Indent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Remove. + /// + public static string EmptyLineHandling_Remove { + get { + return ResourceManager.GetString("EmptyLineHandling_Remove", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Filter. + /// + public static string GroupingGrid_Filter { + get { + return ResourceManager.GetString("GroupingGrid_Filter", resourceCulture); + } + } + } +} diff --git a/Rubberduck.CodeAnalysis/CodeAnalysisUI.cs.resx b/Rubberduck.CodeAnalysis/CodeAnalysisUI.cs.resx new file mode 100644 index 0000000000..566914eb1b --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodeAnalysisUI.cs.resx @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Typ + + + Problém + + + Lokace + + + Rubberduck Inspekce Kódu - {0} +{1} problém nalezen. + + + Kontroluji... + + + Rubberduck Inspekce Kódu - {0} +Nalezeno {1} problémů. + + + Závažnosti Inspekce + + + Dovolené Identifikátory + + + Různé + + + Spustit automaticky inspekce po úspěšném parsování + + + Tyto identifikátory budou ignorovány inspekcí 'Použij smysluplné názvy'. + + + Řádky + + + Cyklomatická Komplexita + + + Maximální Vnoření + + + Metrika Kódu + + + Inspekce kódu + + + VBE nastavení "Zkompilovat Na Žádost" je aktuálně povoleno. Toto není doporučeno a může vyústit v kompilační chyby a způsobit problémy při parsování. Chcete i přesto spustit parser? + + + Nastavení Zkompilování Na Žádost + + + Není možno zkompilovat pro parsování. + + + Následující projekt(y) nemohou být zkompilovány, což je s největší pravděpodobností kvůli parsovacím chybám. I přesto pokračovat? {0} + + + runtime expression + + + třída + + + konstanta + + + VBDesigner-Objekt + + + enum + + + enum člen + + + událost + + + funkce + + + funkce knihovny + + + procedura knihovny + + + označení řádku + + + parametr + + + modul + + + procedura + + + projekt + + + Get accessor vlastnosti + + + Let accessor vlastnosti + + + Set accessor vlastnosti + + + uživatelsky-definovaný typ + + + uživatelsky-definovaný člen + + + proměnná + + + Získali jste odznak "Continuator"! + + + Odsadit + + + Odstranit + + + Ignorovat + + + Filtr + + + Popis: + + + Závažnost: + + \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/CodeAnalysisUI.de.resx b/Rubberduck.CodeAnalysis/CodeAnalysisUI.de.resx new file mode 100644 index 0000000000..4610b4d620 --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodeAnalysisUI.de.resx @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Typ + + + Problem + + + Ort + + + Rubberduck Code Untersuchung - {0} +{1} Problem gefunden. + + + Inspiziere... + + + Rubberduck Code Untersuchung - {0} +{1} Probleme gefunden. + + + Inspektionsschwere + + + Explizit erlaubte Namen + + + Verschiedenes + + + Inspektionen nach erfolgreichem Parsen automatisch starten + + + Diese Namen werden von der Inspektion "Nutze aussagekräftige Namen" ignoriert. + + + Codezeilen + + + Zyklomatische Komplexität + + + Maximale Einrückung + + + Codemetrikergebnisse + + + Code Untersuchung + + + Die VBE-Einstellung "Bei Bedarf Kompilieren" ist aktuell eingeschalten. Dies ist nicht empfohlen, da Kompilierungsfehler und Probleme beim Parsen versteckt werden können. Trotzdem Parsen? + + + Einstellung "Bei Bedarf Kompilieren" + + + Konnte nicht vor dem Parsen kompilieren. + + + Folgende(s) Projekt(e) können nicht kompiliert werden. Dies führt höchstwahrscheinlich zu Parserfehlern. Trotzdem fortfahren? {0} + + + Laufzeitausdruck + + + Klasse + + + Konstante + + + VBDesigner-Objekt + + + Enum + + + Enum-Element (Konstante) + + + Ereignis + + + Funktion + + + Bibliotheks-Funktion + + + Bibliotheksprozedur + + + Sprungmarke + + + Parameter + + + Modul + + + Prozedur + + + Projekt + + + Get-Eigenschaftsprozedur + + + Let-Eigenschaftsprozedur + + + Set-Eigenschaftsprozedur + + + Nutzerdefinierter Typ + + + Element eines nutzerdefinierten Typs + + + Variable + + + Sie haben das Abzeichen "Continuator" erhalten! + + + Einrücken + + + Entfernen + + + Ignorieren + + + Filter + + + Beschreibung: + + + Schweregrad: + + \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/CodeAnalysisUI.es.resx b/Rubberduck.CodeAnalysis/CodeAnalysisUI.es.resx new file mode 100644 index 0000000000..3e7f048462 --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodeAnalysisUI.es.resx @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Tipo + + + Problema + + + Ubicación + + + Inspecciones del código de Rubberduck - {0} +{1} problema encontrado. + + + Inspeccionando... + + + Inspecciones del código de Rubberduck - {0} +{1} problemas encontrados. + + + Severidad de la inspección + + + Identificadores en lista blanca + + + Misceláneas + + + Ejecutar inspecciones automáticamente en el análisis exitoso + + + Estos identificadores serán ignorados por la inspección 'Usar nombres significativos'. + + + Líneas + + + Complejidad ciclomática + + + Anidamiento maximo + + + Métricas de Código + + + Inspecciones de código + + + El VBEsetting "Compile On Demand" está habilitado actualmente. No se recomienda, ya que puede ocultar errores de compilación y causar problemas con el análisis. ¿Quieres analizar de todos modos? + + + Ajuste "Compilar A Demanda" + + + No se puede compilar para analizar. + + + Los siguientes proyectos no pueden compilarse, lo que probablemente resultará en errores del analizador. ¿Continua de todas maneras? {0} + + + expresión en tiempo de ejecución + + + clase + + + constante + + + control + + + enumerar + + + enumerar miembro + + + evento + + + función + + + biblioteca de funciones + + + biblioteca de procedimientos + + + etiqueta de línea + + + parámetro + + + módulo + + + procedimiento + + + proyecto + + + propiedad Get + + + propiedad Let + + + propiedad Set + + + tipo definido por el usuario + + + miembro de tipo definido por el usuario + + + variable + + + ¡Has ganado la insignia de "Continuador"! + + + Indentar + + + Eliminar + + + Ignorar + + + Filtro + + + Descripción: + + + Severidad: + + \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/CodeAnalysisUI.fr.resx b/Rubberduck.CodeAnalysis/CodeAnalysisUI.fr.resx new file mode 100644 index 0000000000..d647d3adef --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodeAnalysisUI.fr.resx @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Type + + + Problème + + + Emplacement + + + Inspections Rubberduck - {0} +{1} problème trouvé. + + + Inspection... + + + Inspections Rubberduck - {0} +{1} problèmes trouvés. + + + Niveau de sévérité + + + Identifiants permis + + + Autres options + + + Exécuter les inspections automatiquement + + + L'inspection des noms ignorera ces identifiants. + + + Lignes + + + Complexité Cyclomatique + + + Imbrication + + + Statistiques + + + Inspections + + + L'option VBE "Compile on demand" est présentement activée. Cette configuration n'est pas recommandée, puisqu'elle peut masquer des erreurs de compilation in interférer avec l'analyse. Poursuivre l'analyse? + + + Paramètre "Compile on demand" + + + La compilation a échoué. + + + Les projets suivants ne peuvent être compilés, ce qui causera probablement des erreurs d'analyse. Continuer? {0} + + + expression résolue à l'exécution + + + la classe + + + la constante + + + le contrôle + + + l'énumération + + + le membre de l'énumération + + + l'événement + + + la fonction + + + la fonction externe + + + la procédure externe + + + l'étiquette de ligne + + + le paramètre + + + le module + + + la procédure + + + le projet + + + l'accesseur property get + + + l'accesseur property let + + + l'accesseur property set + + + le type définit par l'utilisateur + + + le membre d'un type définit par l'utilisateur + + + la variable + + + Vous obtenez le badge "Continuator"! + + + Indenter + + + Supprimer + + + Ignorer + + + Filtrer + + + Description: + + + Sévérité: + + \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/CodeAnalysisUI.it.resx b/Rubberduck.CodeAnalysis/CodeAnalysisUI.it.resx new file mode 100644 index 0000000000..44148d372f --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodeAnalysisUI.it.resx @@ -0,0 +1,266 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Complessità Ciclomatica + + + Righe + + + Annidamenti Massimi + + + Tipo + + + Posizione + + + Problema + + + Impostazione Compila su Richiesta + + + L'impostazione "Compila su richiesta" di VBE è attualmente abilitata. Questo non è raccomandato perché può nascondere errori di compilazione e causare problemi con l'analisi. Vuoi analizzare comunque? + + + Impossibile compilare per l'analisi. + + + Il/i seguente/i progetto/i non può/possono essere compilato/i, con probabile errore dell'analisi. Continuare comunque? {0} + + + Filtra + + + Rimuovi + + + Indenta + + + Ignora + + + Hai guadagnato il badge di "Continuatore"! + + + variabile + + + membro di tipo definito dall'utente + + + tipo definito dall'utente + + + property set accessor + + + property let accessor + + + property get accessor + + + progetto + + + procedura + + + modulo + + + parametro + + + riga di etichetta + + + libreria di procedura + + + libreria di funzione + + + funzione + + + evento + + + membro di enum + + + enum + + + controllo + + + costante + + + classe + + + espressione a runtime + + + Statistiche + + + Rubberduck Ispezioni del Codice - {0} +{1} problema trovato. + + + Rubberduck Ispezioni del Codice - {0} +{1} problemi trovati. + + + Ispezione... + + + Ispezioni del Codice + + + Gravità: + + + Descrizione: + + + Gravità dell'ispezione + + + Esegui le ispezioni automaticamente ad analisi superata + + + Varie + + + Identificatori Consentiti + + + Questi identificatori saranno ignorati dall'ispezione 'Usa nomi significativi'. + + \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/CodeAnalysisUI.resx b/Rubberduck.CodeAnalysis/CodeAnalysisUI.resx new file mode 100644 index 0000000000..33bba664e2 --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodeAnalysisUI.resx @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Type + + + Issue + + + Location + + + Rubberduck Code Inspections - {0} +{1} issue found. + {0}=timestamp; {1}=number + + + Inspecting... + + + Rubberduck Code Inspections - {0} +{1} issues found. + {0}=timestamp; {1}=number + + + Inspection Severities + + + Allowed Identifiers + + + Miscellaneous + + + Run inspections automatically on successful parse + + + These identifiers will be ignored by the 'Use meaningful names' inspection. + + + Lines + + + Cyclomatic Complexity + + + Maximum Nesting + + + Code Metrics + + + Code Inspections + + + The VBE setting "Compile On Demand" is currently enabled. This is not recommended as this may hide compilation errors and cause problems with parsing. Do you want to parse anyway? + + + Compile On Demand Setting + + + Unable to compile for parsing. + + + The following project(s) cannot be compiled, which will most likely result in parser errors. Continue anyway? {0} + + + runtime expression + + + class + + + constant + + + control + + + enum + + + enum member + + + event + + + function + + + library function + + + library procedure + + + line label + + + parameter + + + module + + + procedure + + + project + + + property get accessor + + + property let accessor + + + property set accessor + + + user-defined type + + + user-defined type member + + + variable + + + You've earned the "Continuator" badge! + + + Indent + + + Remove + + + Ignore + + + Filter + + + Description: + + + Severity: + + \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/Inspections/Abstract/IdentifierReferenceInspectionFromDeclarationsBase.cs b/Rubberduck.CodeAnalysis/Inspections/Abstract/IdentifierReferenceInspectionFromDeclarationsBase.cs index 1d0fb5e9ea..438f148063 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Abstract/IdentifierReferenceInspectionFromDeclarationsBase.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Abstract/IdentifierReferenceInspectionFromDeclarationsBase.cs @@ -21,74 +21,6 @@ protected IdentifierReferenceInspectionFromDeclarationsBase(IDeclarationFinderPr protected virtual ICollection DisabledQuickFixes(IdentifierReference reference) => new List(); - /// - /// Gets the possible that qualifies an identifier reference in a member access expression. - /// - protected IEnumerable GetQualifierCandidates(IdentifierReference reference, DeclarationFinder finder) - { - if (reference.Context.TryGetAncestor(out var memberAccess)) - { - var parentModule = Declaration.GetModuleParent(reference.ParentScoping); - var qualifyingExpression = memberAccess.lExpression(); - if (qualifyingExpression is VBAParser.SimpleNameExprContext simpleName) - { - if (simpleName.GetText().Equals(Tokens.Me, System.StringComparison.InvariantCultureIgnoreCase)) - { - // qualifier is 'Me' - return new[] { parentModule }; - } - - // todo get the actual qualifying declaration? - return finder.MatchName(simpleName.GetText()) - .Where(candidate => !candidate.IdentifierName.Equals(reference.Declaration.IdentifierName, System.StringComparison.InvariantCultureIgnoreCase)); - } - - if (qualifyingExpression.ChildCount == 1 && qualifyingExpression.GetText().Equals(Tokens.Me, System.StringComparison.InvariantCultureIgnoreCase)) - { - // qualifier is 'Me' - return new[] { parentModule }; - } - } - - if (reference.Context.TryGetAncestor(out var dot)) - { - // qualifier is a With block - var withBlock = dot.GetAncestor(); - return finder.ContainedIdentifierReferences(new QualifiedSelection(reference.QualifiedModuleName, withBlock.GetSelection())) - .Select(r => r.Declaration).Distinct() - .Where(candidate => !candidate.Equals(reference.Declaration)); - } - - if (reference.Context.TryGetAncestor(out var callStmt)) - { - if (reference.Context.TryGetAncestor(out var lExpression)) - { - // reference is in lexpression of a call statement - - if (lExpression is VBAParser.MemberAccessExprContext member) - { - if (member.lExpression() is VBAParser.SimpleNameExprContext name) - { - if (reference.IdentifierName.Equals(name.identifier().GetText(), System.StringComparison.InvariantCultureIgnoreCase)) - { - // unqualified - return Enumerable.Empty(); - } - - return finder.MatchName(name.identifier().GetText()) - .Where(candidate => !candidate.Equals(reference.Declaration)); - } - - // todo get the actual qualifying declaration? - return finder.MatchName(member.lExpression().children.First().GetText()) - .Where(candidate => !candidate.Equals(reference.Declaration)); - } - } - } - - return Enumerable.Empty(); - } - protected override IEnumerable DoGetInspectionResults(DeclarationFinder finder) { var objectionableReferences = ObjectionableReferences(finder); diff --git a/Rubberduck.CodeAnalysis/Inspections/Abstract/ImplicitWorkbookReferenceInspectionBase.cs b/Rubberduck.CodeAnalysis/Inspections/Abstract/ImplicitWorkbookReferenceInspectionBase.cs index 93e3726393..23d0295d00 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Abstract/ImplicitWorkbookReferenceInspectionBase.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Abstract/ImplicitWorkbookReferenceInspectionBase.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; @@ -22,40 +23,27 @@ internal ImplicitWorkbookReferenceInspectionBase(IDeclarationFinderProvider decl "_Global", "_Application", "Global", "Application", "_Workbook", "Workbook" }; - private IReadOnlyList _relevantClasses; - private IReadOnlyList _relevantProperties; - - protected Declaration Excel { get; private set; } + protected Declaration Excel(DeclarationFinder finder) + { + return finder.BuiltInDeclarations(DeclarationType.Project) + .FirstOrDefault(project => project.IdentifierName.Equals("Excel", StringComparison.InvariantCultureIgnoreCase)); + } protected override IEnumerable ObjectionableDeclarations(DeclarationFinder finder) { - if (Excel == null) - { - if (!finder.TryFindProjectDeclaration("Excel", out var excel)) - { - return Enumerable.Empty(); - } - Excel = excel; - } - - if (_relevantClasses == null) - { - _relevantClasses = InterestingClasses - .Select(className => finder.FindClassModule(className, Excel, true)) - .OfType() - .ToList(); - } - - if (_relevantProperties == null) - { - _relevantProperties = _relevantClasses - .SelectMany(classDeclaration => classDeclaration.Members) - .OfType() - .Where(member => InterestingMembers.Contains(member.IdentifierName)) - .ToList(); - } - - return _relevantProperties; + var excel = Excel(finder); + var relevantClasses = InterestingClasses + .Select(className => finder.FindClassModule(className, excel, true)) + .OfType() + .ToList(); + + var relevantProperties = relevantClasses + .SelectMany(classDeclaration => classDeclaration.Members) + .OfType() + .Where(member => InterestingMembers.Contains(member.IdentifierName)) + .ToList(); + + return relevantProperties; } } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionBase.cs b/Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionBase.cs index 23b94c9a92..4128e920b7 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionBase.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionBase.cs @@ -55,7 +55,7 @@ protected InspectionBase(IDeclarationFinderProvider declarationFinderProvider) /// Gets a localized string representing the type of inspection. /// /// - public virtual string InspectionTypeName => Resources.Inspections.InspectionsUI.ResourceManager.GetString($"CodeInspectionSettings_{InspectionType.ToString()}", CultureInfo.CurrentUICulture); + public virtual string InspectionTypeName => Resources.Inspections.InspectionsUI.ResourceManager.GetString($"CodeInspectionSettings_{InspectionType}", CultureInfo.CurrentUICulture); /// /// Gets a string representing the text that must be present in an @@ -83,8 +83,14 @@ public IEnumerable GetInspectionResults(CancellationToken tok .Where(ir => !ir.IsIgnoringInspectionResult(finder)) .ToList(); stopwatch.Stop(); - Logger.Trace("Intercepted invocation of '{0}.{1}' returned {2} objects.", GetType().Name, nameof(DoGetInspectionResults), result.Count); - Logger.Trace("Intercepted invocation of '{0}.{1}' ran for {2}ms", GetType().Name, nameof(DoGetInspectionResults), stopwatch.ElapsedMilliseconds); + if (result.Count > 0) + { + Logger.Trace("'Returned {2} results, completed in {3}ms.", result.Count, stopwatch.ElapsedMilliseconds); + } + else + { + Logger.Trace("Completed in {2}ms", stopwatch.ElapsedMilliseconds); + } return result; } @@ -103,8 +109,14 @@ public IEnumerable GetInspectionResults(QualifiedModuleName m .Where(ir => !ir.IsIgnoringInspectionResult(finder)) .ToList(); stopwatch.Stop(); - Logger.Trace("Intercepted invocation of '{0}.{1}' returned {2} objects.", GetType().Name, nameof(DoGetInspectionResults), result.Count); - Logger.Trace("Intercepted invocation of '{0}.{1}' ran for {2}ms", GetType().Name, nameof(DoGetInspectionResults), stopwatch.ElapsedMilliseconds); + if (result.Count > 0) + { + Logger.Trace("'Returned {2} results, completed in {3}ms.", result.Count, stopwatch.ElapsedMilliseconds); + } + else + { + Logger.Trace("Completed in {2}ms", stopwatch.ElapsedMilliseconds); + } return result; } diff --git a/Rubberduck.CodeAnalysis/Inspections/CodeInspectionType.cs b/Rubberduck.CodeAnalysis/Inspections/CodeInspectionType.cs index c5965218ad..c495bb7ada 100644 --- a/Rubberduck.CodeAnalysis/Inspections/CodeInspectionType.cs +++ b/Rubberduck.CodeAnalysis/Inspections/CodeInspectionType.cs @@ -4,8 +4,9 @@ public enum CodeInspectionType { RubberduckOpportunities, LanguageOpportunities, - MaintainabilityAndReadabilityIssues, + NamingAndConventionsIssues, CodeQualityIssues, Performance, + Uncategorized, } } diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs index 7e9c75ec09..e487e4a47d 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs @@ -83,8 +83,7 @@ protected override IEnumerable ReferencesInModule(Qualified protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) { - return !(IsAssignmentOfNothing(reference) - || IsPotentiallyUsedViaJump(reference, finder)); + return !(IsAssignmentOfNothing(reference) || IsPotentiallyUsedViaJump(reference, finder)); } protected override string ResultDescription(IdentifierReference reference) @@ -115,8 +114,11 @@ private static IEnumerable FindUnusedAssignmentReferences(D ? FindUnusedAssignmentNodes(tree, localVariable, allAssignmentsAndReferences) : allAssignmentsAndReferences.OfType(); - return unusedAssignmentNodes.Where(n => !IsDescendentOfNeverFlagNode(n)) - .Select(n => n.Reference); + var results = unusedAssignmentNodes + .Where(n => !IsDescendentOfNeverFlagNode(n)) + .Select(n => n.Reference); + + return results; } private static IEnumerable FindUnusedAssignmentNodes(INode node, Declaration localVariable, IEnumerable allAssignmentsAndReferences) @@ -136,7 +138,7 @@ private static IEnumerable FindUnusedAssignmentNodes(INode node, ? assignmentExprNodes.TakeWhile(n => n != assignmentExprNodesWithReference.LastOrDefault()) ?.LastOrDefault() ?.Nodes(new[] { typeof(AssignmentNode) }) - : allAssignmentsAndReferences.TakeWhile(n => n != refNode) + : allAssignmentsAndReferences.TakeWhile(n => n != refNode && !IsDescendentOfNeverFlagNode(n)) .OfType(); if (assignmentsPrecedingReference?.Any() ?? false) @@ -148,7 +150,7 @@ private static IEnumerable FindUnusedAssignmentNodes(INode node, return allAssignmentsAndReferences.OfType().Except(usedAssignments); } - private static bool IsDescendentOfNeverFlagNode(AssignmentNode assignment) + private static bool IsDescendentOfNeverFlagNode(INode assignment) { return assignment.TryGetAncestorNode(out _) || assignment.TryGetAncestorNode(out _); diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ConstantNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ConstantNotUsedInspection.cs index b2fe9b7db9..2c8508de95 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ConstantNotUsedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ConstantNotUsedInspection.cs @@ -45,7 +45,24 @@ public ConstantNotUsedInspection(IDeclarationFinderProvider declarationFinderPro protected override bool IsResultDeclaration(Declaration declaration, DeclarationFinder finder) { return declaration?.Context != null - && !declaration.References.Any(); + && !declaration.References.Any() + && !IsPublicInExposedClass(declaration); + } + + private static bool IsPublicInExposedClass(Declaration procedure) + { + if (!(procedure.Accessibility == Accessibility.Public + || procedure.Accessibility == Accessibility.Global)) + { + return false; + } + + if (!(Declaration.GetModuleParent(procedure) is ClassModuleDeclaration classParent)) + { + return false; + } + + return classParent.IsExposed; } protected override string ResultDescription(Declaration declaration) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyMethodInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyMethodInspection.cs index 4d8f0d4bbe..baaf3d6688 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyMethodInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyMethodInspection.cs @@ -33,7 +33,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete /// ]]> /// /// - internal class EmptyMethodInspection : DeclarationInspectionBase + internal sealed class EmptyMethodInspection : DeclarationInspectionBase { public EmptyMethodInspection(IDeclarationFinderProvider declarationFinderProvider) : base(declarationFinderProvider, DeclarationType.Member) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyModuleInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyModuleInspection.cs index 1350acff4b..fc99597114 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyModuleInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyModuleInspection.cs @@ -84,7 +84,7 @@ public override bool VisitModuleDeclarations(VBAParser.ModuleDeclarationsContext public override bool VisitModuleDeclarationsElement(VBAParser.ModuleDeclarationsElementContext context) { return context.moduleVariableStmt() == null - && context.constStmt() == null + && context.moduleConstStmt() == null && context.enumerationStmt() == null && context.udtDeclaration() == null && context.eventStmt() == null diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyStringLiteralInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyStringLiteralInspection.cs index 9b2364a56a..98868b1c06 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyStringLiteralInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/EmptyStringLiteralInspection.cs @@ -9,10 +9,15 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete /// /// Flags uses of an empty string literal (""). /// + /// + /// Treating an empty string literal as equal to the 'vbNullString' constant + /// requires using the PermissiveAssertClass. The default AssertClass is more strict about data types, and tells them apart. + /// /// /// Standard library constant 'vbNullString' is more explicit about its intent, and should be preferred to a string literal. /// While the memory gain is meaningless, an empty string literal still takes up 2 bytes of memory, - /// but 'vbNullString' is a null string pointer, and doesn't. + /// but 'vbNullString' is a null string pointer, and doesn't. In VB6 and VBA this makes little to no difference however, + /// but in earlier versions each instance of an empty string literal in source code resulted in the allocation of these 2 bytes every time. /// /// /// diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueAlwaysDiscardedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueAlwaysDiscardedInspection.cs index 31a5b60608..46fc854b83 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueAlwaysDiscardedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueAlwaysDiscardedInspection.cs @@ -141,14 +141,23 @@ private static bool IsCalledAsProcedure(ParserRuleContext context) } //Member accesses are parsed right-to-left, e.g. 'foo.Bar' is the parent of 'foo'. - //Thus, having a member access parent means that the return value is used somehow. - var ownFunctionCallExpression = context.Parent is VBAParser.MemberAccessExprContext methodCall - ? methodCall - : context; - var memberAccessParent = ownFunctionCallExpression.GetAncestor(); + //Thus, having a member access parent and being contained in its lExpression on the left of the dot + //or having a further member access parent means that the return value is used somehow. + var memberAccessParent = context.GetAncestor(); if (memberAccessParent != null) { - return false; + //This case is necessary for member accesses in particular on simple name expressions since the context is the simpleNameExpression there and not the identifier. + if (memberAccessParent.lExpression().Contains(context)) + { + return false; + } + + //This case is necessary if the context is itself the unrestricted identifier in a member access. + var furtherMemberAccessParent = memberAccessParent.GetAncestor(); + if (furtherMemberAccessParent != null) + { + return false; + } } //If we are in an output list, the value is used somewhere in defining the argument. diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueDiscardedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueDiscardedInspection.cs index 1815ba5db4..2ac32ca6b4 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueDiscardedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueDiscardedInspection.cs @@ -77,14 +77,23 @@ private static bool IsCalledAsProcedure(ParserRuleContext context) } //Member accesses are parsed right-to-left, e.g. 'foo.Bar' is the parent of 'foo'. - //Thus, having a member access parent means that the return value is used somehow. - var ownFunctionCallExpression = context.Parent is VBAParser.MemberAccessExprContext methodCall - ? methodCall - : context; - var memberAccessParent = ownFunctionCallExpression.GetAncestor(); + //Thus, having a member access parent and being contained in its lExpression on the left of the dot + //or having a further member access parent means that the return value is used somehow. + var memberAccessParent = context.GetAncestor(); if (memberAccessParent != null) { - return false; + //This case is necessary for member accesses in particular on simple name expressions since the context is the simpleNameExpression there and not the identifier. + if (memberAccessParent.lExpression().Contains(context)) + { + return false; + } + + //This case is necessary if the context is itself the unrestricted identifier in a member access. + var furtherMemberAccessParent = memberAccessParent.GetAncestor(); + if (furtherMemberAccessParent != null) + { + return false; + } } //If we are in an output list, the value is used somewhere in defining the argument. diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/IIfSideEffectInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/IIfSideEffectInspection.cs new file mode 100644 index 0000000000..8c0908c631 --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/IIfSideEffectInspection.cs @@ -0,0 +1,265 @@ +using Antlr4.Runtime; +using Rubberduck.CodeAnalysis.Inspections.Abstract; +using Rubberduck.Parsing; +using Rubberduck.Parsing.Grammar; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.DeclarationCaching; +using Rubberduck.Resources.Inspections; +using Rubberduck.VBEditor; +using System.Collections.Generic; +using System.Linq; + +namespace Rubberduck.CodeAnalysis.Inspections.Concrete +{ + /// + /// Identifies Functions or Properties referenced by the TruePart(second argument) + /// or FalsePart(third argument) of the IIf built-in function. + /// + /// + /// All arguments of any function/procedure call are always evaluated before the function is invoked so that + /// their respective values can be passed as parameters. Even so, the IIf Function's behavior is sometimes mis-interpreted + /// to expect that ONLY the 'TruePart' or ONLY the 'FalsePart' expression will be evaluated based on the result of the + /// first argument expression. Consequently, the IIf Function can be a source of unanticipated side-effects and errors + /// if the user does not account for the fact that both the TruePart and FalsePart arguments are always evaluated. + /// + /// + /// + /// 0, GetQuotient(dividend, divisor), DivideByZeroAttempted()) + ///End Sub + /// + ///Private Function GetQuotient(ByVal dividend As Long, ByVal divisor As Long) As Double + /// ValidDivision = CDbl(dividend / divisor) + ///End Function + /// + ///Private Function DivideByZeroAttempted() As Double + /// DivideByZeroAttempted = 0# + /// + /// divideByZeroAttempts = divideByZeroAttempts + 1 + /// + /// Err.Raise vbObjectError + 1051, "MyModule", "Divide by Zero attempted" + ///End Function + /// ]]> + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + + internal sealed class IIfSideEffectInspection : IdentifierReferenceInspectionBase + { + private readonly IDeclarationFinderProvider _declarationFinderProvider; + + private static Dictionary _nonSideEffectingLibraryFunctionIdentifiers = CreateLibraryFunctionIdentifiersToIgnore(); + + public IIfSideEffectInspection(IDeclarationFinderProvider declarationFinderProvider) + : base(declarationFinderProvider) + { + _declarationFinderProvider = declarationFinderProvider; + } + + //Override DoGetInspectionResults to improve efficiency. Collates all IIf function TruePart and FalsePart + //ArgumentContexts once per module rather than once for every IdentifierReference (of all DeclarationTypes) + //contained in a module. + protected override IEnumerable DoGetInspectionResults(QualifiedModuleName module, DeclarationFinder finder) + { + var iifReferences = _declarationFinderProvider.DeclarationFinder.BuiltInDeclarations(DeclarationType.Function) + .SingleOrDefault(d => string.Compare( d.IdentifierName, "IIf", System.StringComparison.InvariantCultureIgnoreCase) == 0) + .References.Where(rf => rf.QualifiedModuleName == module); + + if (!iifReferences.Any()) + { + return new List(); + } + + var iifTruePartAndFalsePartArgumentContexts = ExtractTruePartFalsePartArgumentContexts(iifReferences); + + var objectionableReferences = ReferencesInModule(module, finder) + .Where(reference => reference.Declaration.DeclarationType.HasFlag(DeclarationType.Function) + && !_nonSideEffectingLibraryFunctionIdentifiers.ContainsKey(reference.IdentifierName.ToUpperInvariant()) + && reference.Context.TryGetAncestor(out _) + && iifTruePartAndFalsePartArgumentContexts.Any(ac => ac.Contains(reference.Context))); + + return objectionableReferences + .Select(reference => InspectionResult(reference, finder)) + .ToList(); + } + + //Not used. This inspection overrides DoGetInspectionResults and aggregates results there. + protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) + { + throw new System.NotImplementedException(); + } + + private static IEnumerable ExtractTruePartFalsePartArgumentContexts(IEnumerable iifReferences) + { + (int PositionIndex, string Identifier) truePartParam = (1, "TruePart"); + (int PositionIndex, string Identifier) falsePartParam = (2, "FalsePart"); + + var results = new List(); + + foreach (var iifReference in iifReferences) + { + var argumentContexts = (iifReference.Context.Parent as ParserRuleContext) + .GetChild() + .children.OfType() + .ToList(); + + results.Add(ExtractArgumentContext(argumentContexts, truePartParam)); + results.Add(ExtractArgumentContext(argumentContexts, falsePartParam)); + } + + return results; + } + + private static VBAParser.ArgumentContext ExtractArgumentContext(IEnumerable argumentContexts, (int PositionIndex, string Identifier) partParam) + { + var namedArgumentContexts = argumentContexts.Where(ctxt => ctxt.namedArgument() != null) + .Select(ctxt => ctxt.namedArgument()); + + if (namedArgumentContexts.Any()) + { + var unrestrictedIDContextsByName = namedArgumentContexts + .SelectMany(ctxt => ctxt.children.OfType()) + //'ToUpperInvariant' in case the user has (at some point) entered a declaration that re-cased any IIf parameter names + .ToDictionary(ch => ch.GetText().ToUpperInvariant()); + + if (unrestrictedIDContextsByName.TryGetValue(partParam.Identifier.ToUpperInvariant(), out var expressionUnrestrictedIDContext)) + { + return expressionUnrestrictedIDContext.Parent.Parent as VBAParser.ArgumentContext; + } + } + + return argumentContexts.ElementAt(partParam.PositionIndex); + } + + protected override string ResultDescription(IdentifierReference reference) + { + return string.Format(InspectionResults.IIfSideEffectInspection, reference.IdentifierName); + } + + /// + /// Loads VBA Standard library functions that are not be side-effecting or highly unlikely to raise errors + /// + /// + private static Dictionary CreateLibraryFunctionIdentifiersToIgnore() + { + return LoadLibraryFunctionIdentifiersToIgnore( new Dictionary(), + //MS-VBAL 6.1.2.3 Conversion Module + /*Excluded for potential of raising errors: + * "CBool", "CByte", "CCur", "CDate", "CVDate", "CDbl", "CDec", "CInt", "CLng", "CLngLng", "ClngPtr", + * "CSng", "CStr", "CVar", "CVErr", "Error","Error$", "Fix", "Hex", "Hex$", "Int", "Oct", "Oct$", "Str", + * "Str$", "Val" + */ + + //MS-VBAL 6.1.2.4 DateTime Module + /*Excluded for potential of raising errors: + * "DateAdd", "DateDiff", "DatePart", "DateSerial", "DateValue", "Day", "Hour", "Minute", "Month", "Second", + * "TimeSerial","TimeValue", "Weekday", "Year" + */ + "Calendar", "Date", "Date$", "Now", "Time", "Time$", "Timer", + //MS-VBAL 6.1.2.5 File System + /*Excluded for potential of raising errors: + * "CurDir", "CurDir$", "Dir", "EOF", "FileAttr", "FileDateTime", "FileLen", "FreeFile", "Loc", "LOF", "Seek" + */ + + //MS-VBAL 6.1.2.6 Financial - all excluded + /*Excluded for potential of raising errors: + * "DDB", "FV", "IPmt", "IRR", "MIRR", "NPer", "NPV", "Pmt", "PPmt", "PV", "Rate", "SLN", "SYD" + */ + + //MS-VBAL 6.1.2.7 Information + "IMEStatus", "IsArray", "IsDate", "IsEmpty", "IsError", "IsMissing", "IsNull", "IsNumeric", "IsObject", + "QBColor", "RGB", "TypeName", "VarType", + + //MS-VBAL 6.1.2.8 Interaction + /* Excluded as Potentially side-effecting: + * "CallByName", "Choose", "Command", "Command$", "CreateObject", + * GetObject", "DoEvents", "InputBox", "MsgBox", "Shell", "Switch", "GetAllSettings", "GetAttr", "GetSetting", + * "Partition" + */ + "Environ", "Environ$", "IIf", + + //MS-VBAL 6.1.2.10 Math + /*Excluded for potential of raising errors: + * "Abs", "Atn", "Cos", "Exp", "Log", "Round", "Sgn", "Sin", "Sqr", "Tan" + */ + "Rnd", + + //MS-VBAL 6.1.2.11 Strings + /* Excluded for potential of raising errors: + * "Format", "Format$", "FormatDateTime", "FormatNumber", "FormatPercent", "InStr", "InStrB", "InStrRev", + * "Join", "Left", "LeftB", "Left$", "LeftB$", "Mid", "MidB", "Mid$", "MidB$", "Replace", "Right", "RightB", + * "Right$", "RightB$", "Asc", "AscW", "AscB", "Chr", "Chr$", "ChB", "ChB$", "ChrW", "ChrW$", "Filter", + * "MonthName", "WeekdayName", "Space", "Space$", "Split","StrConv", "String", "String$" + */ + "LCase", "LCase$", "Len", "LenB", "Trim", "LTrim", "RTrim", "Trim$", "LTrim$", "RTrim$", "StrComp", + "StrReverse", "UCase", "UCase$" + ); + } + + private static Dictionary LoadLibraryFunctionIdentifiersToIgnore(Dictionary idMap, params string[] identifiers) + { + foreach (var identifier in identifiers) + { + idMap.Add(identifier.ToUpperInvariant(), identifier); + } + return idMap; + } + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplementedInterfaceMemberInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplementedInterfaceMemberInspection.cs index c76f098853..0ceadcaaf0 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplementedInterfaceMemberInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplementedInterfaceMemberInspection.cs @@ -73,7 +73,7 @@ private static bool IsInterfaceDeclaration(Declaration declaration) protected override string ResultDescription(Declaration declaration) { var qualifiedName = declaration.QualifiedModuleName.ToString(); - var declarationType = Resources.RubberduckUI.ResourceManager + var declarationType = CodeAnalysisUI.ResourceManager .GetString("DeclarationType_" + declaration.DeclarationType) .Capitalize(); var identifierName = declaration.IdentifierName; diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitActiveWorkbookReferenceInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitActiveWorkbookReferenceInspection.cs index a1c6da7c55..61279d1e08 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitActiveWorkbookReferenceInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitActiveWorkbookReferenceInspection.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Linq; using Rubberduck.CodeAnalysis.Inspections.Abstract; using Rubberduck.CodeAnalysis.Inspections.Attributes; @@ -45,46 +44,37 @@ internal sealed class ImplicitActiveWorkbookReferenceInspection : ImplicitWorkbo public ImplicitActiveWorkbookReferenceInspection(IDeclarationFinderProvider declarationFinderProvider) : base(declarationFinderProvider) { } - private IReadOnlyList _applicationCandidates; - protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) { - var qualifiers = base.GetQualifierCandidates(reference, finder); - var isQualified = qualifiers.Any(); - var document = Declaration.GetModuleParent(reference.ParentNonScoping) as DocumentModuleDeclaration; - - var isHostWorkbook = (document?.SupertypeNames.Contains("Workbook") ?? false) - && (document?.ProjectId?.Equals(reference.QualifiedModuleName.ProjectId) ?? false); - + var isQualified = reference.QualifyingReference != null; if (!isQualified) { + var document = Declaration.GetModuleParent(reference.ParentNonScoping) as DocumentModuleDeclaration; + + var isHostWorkbook = (document?.SupertypeNames.Contains("Workbook") ?? false) + && (document?.ProjectId?.Equals(reference.QualifiedModuleName.ProjectId) ?? false); + // unqualified calls aren't referring to ActiveWorkbook only inside a Workbook module: return !isHostWorkbook; } - else + + if (reference.QualifyingReference.Declaration == null) { - if (_applicationCandidates == null) - { - var applicationClass = finder.FindClassModule("Application", base.Excel, includeBuiltIn: true); - // note: underscored declarations would be for unqualified calls - var workbookClass = finder.FindClassModule("Workbook", base.Excel, includeBuiltIn: true); - var worksheetClass = finder.FindClassModule("Worksheet", base.Excel, includeBuiltIn: true); - var hostBook = finder.UserDeclarations(DeclarationType.Document) - .Cast() - .SingleOrDefault(doc => doc.ProjectId.Equals(reference.QualifiedModuleName.ProjectId) - && doc.SupertypeNames.Contains("Workbook")); + //This should really only happen on unbound member calls and then the current reference would also be unbound. + //So, if we end up here, we have no idea and bail out. + return false; + } - _applicationCandidates = finder.MatchName("Application") - .Where(m => m.Equals(applicationClass) - || (m.ParentDeclaration.Equals(workbookClass) && m.DeclarationType.HasFlag(DeclarationType.PropertyGet)) - || (m.ParentDeclaration.Equals(worksheetClass) && m.DeclarationType.HasFlag(DeclarationType.PropertyGet)) - || (m.ParentDeclaration.Equals(hostBook) && m.DeclarationType.HasFlag(DeclarationType.PropertyGet))) - .ToList(); - } + var excelProjectId = Excel(finder).ProjectId; + var applicationCandidates = finder.MatchName("Application") + .Where(m => m.ProjectId.Equals(excelProjectId) + && ( m.DeclarationType == DeclarationType.PropertyGet + || m.DeclarationType == DeclarationType.ClassModule)); - // qualified calls are referring to ActiveWorkbook if qualifier is the Application object: - return _applicationCandidates.Any(candidate => qualifiers.Any(q => q.Equals(candidate))); - } + var qualifyingDeclaration = reference.QualifyingReference.Declaration; + + // qualified calls are referring to ActiveWorkbook if qualifier is the Application object: + return applicationCandidates.Any(candidate => qualifyingDeclaration.Equals(candidate)); } protected override string ResultDescription(IdentifierReference reference) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitByRefModifierInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitByRefModifierInspection.cs index 72a01905bb..9c968f697a 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitByRefModifierInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitByRefModifierInspection.cs @@ -12,7 +12,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete /// /// /// VBA parameters are implicitly ByRef, which differs from modern VB (VB.NET) and most other programming languages which are implicitly ByVal. - /// So, explicitly identifing VBA parameter mechanisms (the ByRef and ByVal modifiers) can help surface potentially unexpected language results. + /// So, explicitly identifying VBA parameter mechanisms (the ByRef and ByVal modifiers) can help surface potentially unexpected language results. /// The inspection does not flag an implicit parameter mechanism for the last parameter of Property mutators (Let or Set). /// VBA applies a ByVal parameter mechanism to the last parameter in the absence (or presence!) of a modifier. /// Exception: UserDefinedType parameters must always be passed as ByRef. diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorkbookReferenceInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorkbookReferenceInspection.cs index d66560d6ca..0c705b86de 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorkbookReferenceInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorkbookReferenceInspection.cs @@ -1,10 +1,7 @@ using System.Collections.Generic; using System.Linq; -using Antlr4.Runtime; using Rubberduck.CodeAnalysis.Inspections.Abstract; using Rubberduck.CodeAnalysis.Inspections.Attributes; -using Rubberduck.Parsing; -using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Parsing.VBA.DeclarationCaching; @@ -61,10 +58,9 @@ protected override IEnumerable ObjectionableDeclarations(Declaratio protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) { - var qualifiers = base.GetQualifierCandidates(reference, finder); return Declaration.GetModuleParent(reference.ParentScoping) is DocumentModuleDeclaration document - && document.SupertypeNames.Contains("Workbook") - && !qualifiers.Any(); + && document.SupertypeNames.Contains("Workbook") + && reference.QualifyingReference == null; } protected override string ResultDescription(IdentifierReference reference) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorksheetReferenceInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorksheetReferenceInspection.cs index d7e3e47a69..0ce1d79361 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorksheetReferenceInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ImplicitContainingWorksheetReferenceInspection.cs @@ -1,7 +1,6 @@ using System.Linq; using Rubberduck.CodeAnalysis.Inspections.Abstract; using Rubberduck.CodeAnalysis.Inspections.Attributes; -using Rubberduck.Parsing; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Parsing.VBA.DeclarationCaching; @@ -48,7 +47,7 @@ protected override bool IsResultReference(IdentifierReference reference, Declara { return Declaration.GetModuleParent(reference.ParentNonScoping) is DocumentModuleDeclaration document && document.SupertypeNames.Contains("Worksheet") - && !(reference.Context.Parent is Parsing.Grammar.VBAParser.MemberAccessExprContext); // if it's qualified, it's not an implicit reference + && reference.QualifyingReference == null; // if it's qualified, it's not an implicit reference } protected override string ResultDescription(IdentifierReference reference) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/MultilineParameterInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/MultilineParameterInspection.cs index 9b21dfa2c1..dd384592e3 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/MultilineParameterInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/MultilineParameterInspection.cs @@ -3,7 +3,6 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.VBA; -using Rubberduck.Resources; namespace Rubberduck.CodeAnalysis.Inspections.Concrete { @@ -48,7 +47,7 @@ protected override string ResultDescription(QualifiedContext 3 - ? RubberduckUI.EasterEgg_Continuator + ? CodeAnalysisUI.EasterEgg_Continuator : Resources.Inspections.InspectionResults.MultilineParameterInspection, parameterText); } diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/MultipleDeclarationsInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/MultipleDeclarationsInspection.cs index 4a19e88138..ca975181e1 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/MultipleDeclarationsInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/MultipleDeclarationsInspection.cs @@ -9,23 +9,32 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete { /// - /// Flags declaration statements spanning multiple physical lines of code. + /// Flags declaration statements declaring multiple variables. /// /// - /// Declaration statements should generally declare a single variable. + /// Declaration statements should generally declare a single variable. + /// Although this inspection does not take variable types into account, it is a common mistake to only declare an explicit type on the last variable in a list. /// /// /// /// + /// + /// + /// + /// + /// /// /// /// /// /// /// /// diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/NonReturningFunctionInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/NonReturningFunctionInspection.cs index 22e82c57c4..e496396a09 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/NonReturningFunctionInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/NonReturningFunctionInspection.cs @@ -1,4 +1,5 @@ using System.Linq; +using Antlr4.Runtime.Tree; using Rubberduck.CodeAnalysis.Inspections.Abstract; using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; @@ -122,31 +123,58 @@ protected override string ResultDescription(Declaration declaration) private class FunctionReturnValueAssignmentLocator : VBAParserBaseVisitor { private readonly string _name; - private bool _result; + private bool _inFunctionReturnWithExpression; public FunctionReturnValueAssignmentLocator(string name) { _name = name; + _inFunctionReturnWithExpression = false; } - public override bool VisitBlock(VBAParser.BlockContext context) + protected override bool DefaultResult => false; + + protected override bool ShouldVisitNextChild(IRuleNode node, bool currentResult) + { + return !currentResult; + } + + //This is actually the default implementation, but for explicities sake stated here. + protected override bool AggregateResult(bool aggregate, bool nextResult) + { + return nextResult; + } + + public override bool VisitWithStmt(VBAParser.WithStmtContext context) { - base.VisitBlock(context); - return _result; + var oldInFunctionReturnWithExpression = _inFunctionReturnWithExpression; + _inFunctionReturnWithExpression = context.expression().GetText() == _name; + var result = base.VisitWithStmt(context); + _inFunctionReturnWithExpression = oldInFunctionReturnWithExpression; + return result; } public override bool VisitLetStmt(VBAParser.LetStmtContext context) { - var leftmost = context.lExpression().GetChild(0).GetText(); - _result = _result || leftmost == _name; - return _result; + var LHS = context.lExpression(); + if (_inFunctionReturnWithExpression + && LHS is VBAParser.WithMemberAccessExprContext) + { + return true; + } + var leftmost = LHS.GetChild(0).GetText(); + return leftmost == _name; } public override bool VisitSetStmt(VBAParser.SetStmtContext context) { - var leftmost = context.lExpression().GetChild(0).GetText(); - _result = _result || leftmost == _name; - return _result; + var LHS = context.lExpression(); + if (_inFunctionReturnWithExpression + && LHS is VBAParser.WithMemberAccessExprContext) + { + return true; + } + var leftmost = LHS.GetChild(0).GetText(); + return leftmost == _name; } } } diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureCanBeWrittenAsFunctionInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureCanBeWrittenAsFunctionInspection.cs index fcb4f63c7b..24ebd6735d 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureCanBeWrittenAsFunctionInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureCanBeWrittenAsFunctionInspection.cs @@ -13,8 +13,8 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete /// Warns about 'Sub' procedures that could be refactored into a 'Function'. /// /// - /// Idiomatic VB code uses 'Function' procedures to return a single value. If the procedure isn't side-effecting, consider writing is as a - /// 'Function' rather than a 'Sub' the returns a result through a 'ByRef' parameter. + /// Idiomatic VB code uses 'Function' procedures to return a single value. If the procedure isn't side-effecting, consider writing it as a + /// 'Function' rather than a 'Sub' that returns a result through a 'ByRef' parameter. /// /// /// diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs index f21fb6f60d..14a795906c 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs @@ -19,9 +19,9 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete /// Shape object in the host document: in such cases the inspection result should be ignored. /// /// - /// Not all unused procedures can/should be removed: ignore any inspection results for - /// event handler procedures and interface members that Rubberduck isn't recognizing as such, or annotate them with @EntryPoint. + /// Not all unused procedures can/should be removed: ignore any inspection results for event handler procedures or annotate them with @EntryPoint. /// Members that are annotated with @EntryPoint (or @ExcelHotkey) are not flagged by this inspection, regardless of the presence or absence of user code references. + /// Moreover, unused public members of exposed class modules will not be reported. /// /// /// @@ -144,12 +144,28 @@ protected override bool IsResultDeclaration(Declaration declaration, Declaration && !finder.FindEventHandlers().Contains(declaration) && !IsClassLifeCycleHandler(declaration) && !(declaration is ModuleBodyElementDeclaration member - && (member.IsInterfaceMember - || member.IsInterfaceImplementation)) + && member.IsInterfaceImplementation) && !declaration.Annotations .Any(pta => pta.Annotation is ITestAnnotation) && !IsDocumentEventHandler(declaration) - && !IsEntryPoint(declaration); + && !IsEntryPoint(declaration) + && !IsPublicInExposedClass(declaration); + } + + private static bool IsPublicInExposedClass(Declaration procedure) + { + if(!(procedure.Accessibility == Accessibility.Public + || procedure.Accessibility == Accessibility.Global)) + { + return false; + } + + if(!(Declaration.GetModuleParent(procedure) is ClassModuleDeclaration classParent)) + { + return false; + } + + return classParent.IsExposed; } private static bool IsEntryPoint(Declaration procedure) => diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicControlFieldAccessInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicControlFieldAccessInspection.cs new file mode 100644 index 0000000000..9f2f983c32 --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicControlFieldAccessInspection.cs @@ -0,0 +1,162 @@ +using Rubberduck.CodeAnalysis.Inspections.Abstract; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.DeclarationCaching; +using Rubberduck.Resources.Inspections; + +namespace Rubberduck.CodeAnalysis.Inspections.Concrete +{ + /// + /// Flags MSForms controls being accessed from outside the UserForm that contains them. + /// + /// + /// MSForms exposes UserForm controls as public fields; accessing these fields outside the UserForm class breaks encapsulation and couples + /// the application logic with specific form controls rather than the data they hold. + /// For a more object-oriented approach and code that can be unit-tested, consider encapsulating the desired values into their own 'model' class, + /// making event handlers in the form manipulate these 'model' properties, then have the code that displayed the form query this encapsulated state as needed. + /// + /// + /// + /// vbNullString Then + /// MsgBox .FileNameBox.Text + /// End If + /// End With + /// End Sub + /// ]]> + /// + /// + /// + /// + /// vbNullString Then + /// MsgBox .FileName + /// End If + /// End With + /// End Sub + /// ]]> + /// + /// + /// pros: simple to implement, silences the inspection! + /// ' > cons: view vs model responsibilities are fuzzy, intellisense get bloated, business logic is still coupled with the UI. + /// Option Explicit + /// + /// Public Property Get ExportPath() As String + /// ExportPath = ExportPathBox.Text + /// End Property + /// + /// Public Property Get FileName() As String + /// FileName = FileNameBox.Text + /// End Property + /// ]]> + /// + /// + /// + /// + /// vbNullString Then + /// MsgBox Model.FileName + /// End If + /// End With + /// End Sub + /// ]]> + /// + /// + /// + /// + /// + /// pros: easily extended, cleanly separates data from presentation concerns; application logic can be tested independently of the form. + /// ' > cons: Model-View-Presenter architecture requires more modules and can feel/be "overkill" for simpler scenarios. + /// Option Explicit + /// Private Type TView + /// Model As TestModel + /// End Type + /// Private This As TView + /// + /// '@Description "Gets or sets Model object for this instance." + /// Public Property Get Model() As TestModel + /// Set Model = This.Model + /// End Property + /// + /// Public Property Set Model(ByVal RHS As TestModel) + /// Set This.Model = RHS + /// End Property + /// + /// Private Sub ExportPathBox_Change() + /// ' the export path has changed; update the model accordingly + /// Model.ExportPath = ExportPathBox.Text + /// End Sub + /// + /// Private Sub FileNameBox_Change() + /// ' the file name has changed; update the model accordingly + /// Model.FileName = FileNameBox.Text + /// End Sub + /// + /// '... + /// ]]> + /// + /// + internal sealed class PublicControlFieldAccessInspection : IdentifierReferenceInspectionBase + { + public PublicControlFieldAccessInspection(IDeclarationFinderProvider declarationFinderProvider) + : base(declarationFinderProvider) + { + } + + protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) + { + return reference.Declaration.DeclarationType == DeclarationType.Control && + !reference.ParentScoping.ParentDeclaration.Equals(reference.Declaration.ParentDeclaration); + } + + protected override string ResultDescription(IdentifierReference reference) + { + return string.Format(InspectionResults.PublicControlFieldAccessInspection, reference.Declaration.ParentDeclaration.IdentifierName, reference.IdentifierName); + } + } +} \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicEnumerationDeclaredInWorksheetInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicEnumerationDeclaredInWorksheetInspection.cs new file mode 100644 index 0000000000..ac5bbe60e4 --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicEnumerationDeclaredInWorksheetInspection.cs @@ -0,0 +1,83 @@ +using Rubberduck.CodeAnalysis.Inspections.Abstract; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.DeclarationCaching; +using Rubberduck.Resources.Inspections; +using Rubberduck.VBEditor.SafeComWrappers; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Rubberduck.CodeAnalysis.Inspections.Concrete +{ + /// + /// Identifies public enumerations declared within worksheet modules. + /// + /// + /// Copying a worksheet which contains a public Enum declaration will also create a copy of the Enum declaration. + /// The copied Enum declaration will result in an 'Ambiguous name detected' compiler error. + /// Declaring Enumerations in Standard or Class modules avoids unintentional duplication of an Enum declaration. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + internal sealed class PublicEnumerationDeclaredInWorksheetInspection : DeclarationInspectionBase + { + private readonly string[] _worksheetSuperTypeNames = new string[] { "Worksheet", "_Worksheet" }; + + public PublicEnumerationDeclaredInWorksheetInspection(IDeclarationFinderProvider declarationFinderProvider) + : base(declarationFinderProvider, DeclarationType.Enumeration) + {} + + protected override bool IsResultDeclaration(Declaration enumeration, DeclarationFinder finder) + { + if (enumeration.Accessibility != Accessibility.Private + && enumeration.QualifiedModuleName.ComponentType == ComponentType.Document) + { + if (enumeration.ParentDeclaration is ClassModuleDeclaration classModuleDeclaration) + { + return RetrieveSuperTypeNames(classModuleDeclaration).Intersect(_worksheetSuperTypeNames).Any(); + } + } + + return false; + } + + protected override string ResultDescription(Declaration declaration) + { + return string.Format(InspectionResults.PublicEnumerationDeclaredInWorksheetInspection, + declaration.IdentifierName); + } + + /// + /// Supports property injection for testing. + /// + /// + /// MockParser does not populate SuperTypes/SuperTypeNames. RetrieveSuperTypeNames Func allows injection + /// of ClassModuleDeclaration.SuperTypeNames property results. + /// + public Func> RetrieveSuperTypeNames { set; private get; } = GetSuperTypeNames; + + private static IEnumerable GetSuperTypeNames(ClassModuleDeclaration classModule) + { + return classModule.SupertypeNames; + } + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicImplementationShouldBePrivateInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicImplementationShouldBePrivateInspection.cs new file mode 100644 index 0000000000..69e5166b39 --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/PublicImplementationShouldBePrivateInspection.cs @@ -0,0 +1,155 @@ +using Rubberduck.CodeAnalysis.CodeMetrics; +using Rubberduck.CodeAnalysis.Inspections.Abstract; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.DeclarationCaching; +using Rubberduck.Refactorings.Common; +using Rubberduck.Resources.Inspections; +using Rubberduck.VBEditor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rubberduck.CodeAnalysis.Inspections.Concrete +{ + /// + /// Flags Interface implementation members and EventHandlers with Public scope. + /// + /// + /// The default (Public) interface of a class module should not expose the implementation of other interfaces or event handler procedures. + /// If the implementation of an interface member or event handler is useful for a class to expose, it should do so using + /// a dedicated Public member rather than changing the interface member or event handler scope from 'Private' to 'Public'. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + + internal sealed class PublicImplementationShouldBePrivateInspection : DeclarationInspectionBase + { + public PublicImplementationShouldBePrivateInspection(IDeclarationFinderProvider declarationFinderProvider) + : base(declarationFinderProvider, DeclarationType.Member) + {} + + //Overriding DoGetInspectionResults in order to dereference the DeclarationFinder FindXXX declaration + //lists only once per inspections pass. + protected override IEnumerable DoGetInspectionResults(DeclarationFinder finder) + { + var publicMembers = finder.UserDeclarations(DeclarationType.Member) + .Where(d => !d.HasPrivateAccessibility() + && IsLikeAnImplementerOrHandlerName(d.IdentifierName)); + + if (!publicMembers.Any()) + { + return Enumerable.Empty(); + } + + var publicImplementersAndHandlers = finder.FindAllInterfaceImplementingMembers() + .Where(d => !d.HasPrivateAccessibility()) + .Concat(finder.FindEventHandlers() + .Where(d => !d.HasPrivateAccessibility())); + + var publicDocumentEvents = FindDocumentEventHandlers(publicMembers); + + return publicMembers.Intersect(publicImplementersAndHandlers) + .Concat(publicDocumentEvents) + .Select(InspectionResult) + .ToList(); + } + + private static IEnumerable FindDocumentEventHandlers(IEnumerable publicMembers) + { + //Excel and Word + var docEventPrefixes = new List() + { + "Workbook", + "Worksheet", + "Document" + }; + + //FindDocumentEventHandlers can be a source of False Positives if a Document's code + //contains Public procedure Identifiers (with a single underscore). + return publicMembers.Where(d => d.ParentDeclaration.DeclarationType.HasFlag(DeclarationType.Document) + && d.DeclarationType.Equals(DeclarationType.Procedure) + && docEventPrefixes.Any(dep => IsLikeADocumentEventHandlerName(d.IdentifierName, dep))); + } + + protected override string ResultDescription(Declaration declaration) + { + return string.Format(Resources.Inspections.InspectionResults.PublicImplementationShouldBePrivateInspection, + declaration.IdentifierName); + } + + private static bool IsLikeAnImplementerOrHandlerName(string identifier) + { + var splitup = identifier.Split('_'); + return splitup.Length == 2 && splitup[1].Length > 0; + } + + private static bool IsLikeADocumentEventHandlerName(string procedureName, string docEventHandlerPrefix) + { + var splitup = procedureName.Split('_'); + + return splitup.Length == 2 + && splitup[0].Equals(docEventHandlerPrefix, StringComparison.InvariantCultureIgnoreCase) + && splitup[1].Length > 2 //Excel and Word document events all have at least 3 characters + && !splitup[1].Any(c => char.IsDigit(c)); //Excel and Word document event names do not contain numbers + } + + //The 'DoGetInspectionResults' override excludes IsResultDeclaration from the execution path + protected override bool IsResultDeclaration(Declaration declaration, DeclarationFinder finder) + { + throw new NotImplementedException(); + } + + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ReadOnlyPropertyAssignmentInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ReadOnlyPropertyAssignmentInspection.cs new file mode 100644 index 0000000000..65ad96bb73 --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ReadOnlyPropertyAssignmentInspection.cs @@ -0,0 +1,135 @@ +using Rubberduck.CodeAnalysis.Inspections.Abstract; +using Rubberduck.Parsing; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.DeclarationCaching; +using Rubberduck.Resources.Inspections; +using System.Linq; + +namespace Rubberduck.CodeAnalysis.Inspections.Concrete +{ + /// + /// Identifies Property assigment references where Set or Let Property Members do not exist. + /// + /// + /// In general, the VBE editor catches this type of error and will not compile. However, there are + /// a few scenarios where the error is overlooked by the compiler and an error is generated at runtime. + /// To avoid the runtime error scenarios, the inspection flags all assignment references of a read-only property. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + internal sealed class ReadOnlyPropertyAssignmentInspection : IdentifierReferenceInspectionBase + { + public ReadOnlyPropertyAssignmentInspection(IDeclarationFinderProvider declarationFinderProvider) + : base(declarationFinderProvider) + { } + + protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) + { + if (!reference.Declaration.DeclarationType.HasFlag(DeclarationType.Property)) + { + return false; + } + + //Ignore assignment expressions found within Property Get declaration contexts + if (!IsReadOnlyPropertyReference(reference, finder) + || reference.Declaration.Context.Contains(reference.Context)) + { + return false; + } + + return reference.IsAssignment; + } + + private bool IsReadOnlyPropertyReference(IdentifierReference reference, DeclarationFinder finder) + { + var propertyDeclarations = finder.MatchName(reference.Declaration.IdentifierName) + .Where(d => d.DeclarationType.HasFlag(DeclarationType.Property) + && d.QualifiedModuleName == reference.QualifiedModuleName); + + return propertyDeclarations.Count() == 1 + && propertyDeclarations.First().DeclarationType.HasFlag(DeclarationType.PropertyGet); + } + + protected override string ResultDescription(IdentifierReference reference) + { + var identifierName = reference.IdentifierName; + return string.Format( + InspectionResults.ReadOnlyPropertyAssignmentInspection, identifierName); + } + } +} \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/SheetAccessedUsingStringInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/SheetAccessedUsingStringInspection.cs index e4db4f955b..a1e98f2cfa 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/SheetAccessedUsingStringInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/SheetAccessedUsingStringInspection.cs @@ -229,9 +229,6 @@ private static string ComponentPropertyValue(IVBComponent component, string prop return null; } - protected override string ResultDescription(IdentifierReference reference, string codeName) - { - return InspectionResults.SheetAccessedUsingStringInspection; - } + protected override string ResultDescription(IdentifierReference reference, string codeName) => InspectionResults.SheetAccessedUsingStringInspection; } } diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/SuspiciousPredeclaredInstanceAccessInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/SuspiciousPredeclaredInstanceAccessInspection.cs new file mode 100644 index 0000000000..4d02e070bd --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/SuspiciousPredeclaredInstanceAccessInspection.cs @@ -0,0 +1,99 @@ +using Rubberduck.CodeAnalysis.Inspections.Abstract; +using Rubberduck.Parsing; +using Rubberduck.Parsing.Grammar; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.DeclarationCaching; +using Rubberduck.Resources.Inspections; +using Tokens = Rubberduck.Resources.Tokens; + +namespace Rubberduck.CodeAnalysis.Inspections.Concrete +{ + /// + /// This inspection warns about references to the default instance of a class, inside that class. + /// + /// + /// While a stateful default instance might be intentional, when it isn't it's easily a source of bugs. + /// Use the Me qualifier to explicitly refer to the current instance and eliminate any ambiguity. + /// Global state accidentally stored in a class' default instance is not shared by all other instances of that class. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + internal sealed class SuspiciousPredeclaredInstanceAccessInspection : IdentifierReferenceInspectionBase + { + public SuspiciousPredeclaredInstanceAccessInspection(IDeclarationFinderProvider declarationFinderProvider) + : base(declarationFinderProvider) + { + } + + protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) + { + return + reference.Declaration is ClassModuleDeclaration module && + module.HasPredeclaredId && + reference.ParentScoping.ParentDeclaration.Equals(module) && + reference.Context.TryGetAncestor(out var expression) && + reference.IdentifierName != Tokens.Me && expression.lExpression()?.GetText() == reference.IdentifierName; + } + + protected override string ResultDescription(IdentifierReference reference) + { + reference.Context.TryGetAncestor(out var expression); + return string.Format(InspectionResults.SuspiciousPredeclaredInstanceAccessInspection, reference.IdentifierName, expression.GetText()); + } + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/KeywordsUsedAsMemberInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/KeywordsUsedAsMemberInspection.cs index 6a5a946820..b80fb257e8 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/KeywordsUsedAsMemberInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/KeywordsUsedAsMemberInspection.cs @@ -19,7 +19,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete.ThunderCode /// While perfectly legal as Type or Enum member names, these identifiers should be avoided: /// they need to be square-bracketed everywhere they are used. /// - internal class KeywordsUsedAsMemberInspection : DeclarationInspectionBase + internal sealed class KeywordsUsedAsMemberInspection : DeclarationInspectionBase { public KeywordsUsedAsMemberInspection(IDeclarationFinderProvider declarationFinderProvider) : base(declarationFinderProvider, DeclarationType.EnumerationMember, DeclarationType.UserDefinedTypeMember) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/NonBreakingSpaceIdentifierInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/NonBreakingSpaceIdentifierInspection.cs index aa9e8bf798..4987df727c 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/NonBreakingSpaceIdentifierInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ThunderCode/NonBreakingSpaceIdentifierInspection.cs @@ -14,7 +14,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete.ThunderCode /// code our friend Andrew Jackson would have written to confuse Rubberduck's parser and/or resolver. /// This inspection may accidentally reveal non-breaking spaces in code copied and pasted from a website. /// - internal class NonBreakingSpaceIdentifierInspection : DeclarationInspectionBase + internal sealed class NonBreakingSpaceIdentifierInspection : DeclarationInspectionBase { private const string Nbsp = "\u00A0"; diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/UDTMemberNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/UDTMemberNotUsedInspection.cs new file mode 100644 index 0000000000..9857359cdd --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/UDTMemberNotUsedInspection.cs @@ -0,0 +1,83 @@ +using Rubberduck.CodeAnalysis.Inspections.Abstract; +using Rubberduck.CodeAnalysis.Inspections.Extensions; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.DeclarationCaching; +using Rubberduck.Resources.Inspections; +using System.Linq; + +namespace Rubberduck.CodeAnalysis.Inspections.Concrete +{ + /// + /// Warns about User Defined Type (UDT) members that are never referenced. + /// + /// + /// Declarations that are never used should be removed. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + internal sealed class UDTMemberNotUsedInspection : DeclarationInspectionBase + { + public UDTMemberNotUsedInspection(IDeclarationFinderProvider declarationFinderProvider) + : base(declarationFinderProvider, DeclarationType.UserDefinedTypeMember) + {} + + protected override bool IsResultDeclaration(Declaration declaration, DeclarationFinder finder) + { + return declaration.DeclarationType.Equals(DeclarationType.UserDefinedTypeMember) + && !declaration.References.Any(); + } + + protected override string ResultDescription(Declaration declaration) + { + var declarationType = declaration.DeclarationType.ToLocalizedString(); + var declarationName = declaration.IdentifierName; + return string.Format( + InspectionResults.IdentifierNotUsedInspection, + declarationType, + declarationName); + } + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs index b3280565a6..a6cae19f80 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Antlr4.Runtime.Misc; using Rubberduck.CodeAnalysis.Inspections.Abstract; using Rubberduck.InternalApi.Extensions; using Rubberduck.Parsing; @@ -81,7 +82,8 @@ protected override IEnumerable ObjectionableReferences(Decl .ToHashSet(); return base.ObjectionableReferences(finder) - .Where(reference => !excludedReferenceSelections.Contains(reference.QualifiedSelection)); + .Where(reference => !excludedReferenceSelections.Contains(reference.QualifiedSelection) + && !IsRedimedVariantArrayReference(reference)); } private IEnumerable DeclarationsWithExcludedArgumentUsage(DeclarationFinder finder) @@ -204,5 +206,85 @@ private static bool IsArrayReDim(IdentifierReference reference) return reDimVariableStmt is VBAParser.RedimVariableDeclarationContext; } + + // This function works under the assumption that there are no assignments to the referenced variable. + private bool IsRedimedVariantArrayReference(IdentifierReference reference) + { + if (reference.Declaration.AsTypeName != "Variant") + { + return false; + } + + if(!reference.Context.TryGetAncestor(out var containingMember)) + { + return false; + } + + var referenceSelection = reference.Selection; + var referencedDeclarationName = reference.Declaration.IdentifierName; + var reDimLocator = new PriorReDimLocator(referencedDeclarationName, referenceSelection); + + return reDimLocator.Visit(containingMember); + } + + /// + /// A visitor that visits a member's body and returns true if any ReDim statement for the variable called name is present before the selection. + /// + private class PriorReDimLocator : VBAParserBaseVisitor + { + private readonly string _name; + private readonly Selection _selection; + + public PriorReDimLocator(string name, Selection selection) + { + _name = name; + _selection = selection; + } + + protected override bool DefaultResult => false; + + protected override bool ShouldVisitNextChild(Antlr4.Runtime.Tree.IRuleNode node, bool currentResult) + { + return !currentResult; + } + + //This is actually the default implementation, but for explicities sake stated here. + protected override bool AggregateResult(bool aggregate, bool nextResult) + { + return nextResult; + } + + public override bool VisitRedimVariableDeclaration([NotNull] VBAParser.RedimVariableDeclarationContext context) + { + var reDimedVariableName = RedimedVariableName(context); + if (reDimedVariableName != _name) + { + return false; + } + + var reDimSelection = context.GetSelection(); + + return reDimSelection <= _selection; + } + + private string RedimedVariableName([NotNull] VBAParser.RedimVariableDeclarationContext context) + { + if (!(context.expression() is VBAParser.LExprContext reDimmedVariablelExpr)) + { + //This is not syntactically correct VBA. + return null; + } + + switch (reDimmedVariablelExpr.lExpression()) + { + case VBAParser.IndexExprContext indexExpr: + return indexExpr.lExpression().GetText(); + case VBAParser.WhitespaceIndexExprContext whiteSpaceIndexExpr: + return whiteSpaceIndexExpr.lExpression().GetText(); + default: //This should not be possible in syntactically correct VBA. + return null; + } + } + } } } diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotAssignedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotAssignedInspection.cs index d964a9e55e..a24942a16a 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotAssignedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotAssignedInspection.cs @@ -51,7 +51,26 @@ protected override bool IsResultDeclaration(Declaration declaration, Declaration && !declaration.IsWithEvents && !declaration.IsSelfAssigned && !HasUdtType(declaration, finder) // UDT variables don't need to be assigned - && !declaration.References.Any(reference => reference.IsAssignment || IsAssignedByRefArgument(reference.ParentScoping, reference, finder)); + && !declaration.References.Any(reference => reference.IsAssignment + || reference.IsReDim //Ignores Variants used as arrays without assignment of an existing one. + || IsAssignedByRefArgument(reference.ParentScoping, reference, finder)) + && !IsPublicInExposedClass(declaration); + } + + private static bool IsPublicInExposedClass(Declaration procedure) + { + if (!(procedure.Accessibility == Accessibility.Public + || procedure.Accessibility == Accessibility.Global)) + { + return false; + } + + if (!(Declaration.GetModuleParent(procedure) is ClassModuleDeclaration classParent)) + { + return false; + } + + return classParent.IsExposed; } private static bool HasUdtType(Declaration declaration, DeclarationFinder finder) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotUsedInspection.cs index c3e8783c37..03827a1836 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotUsedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotUsedInspection.cs @@ -54,9 +54,27 @@ public VariableNotUsedInspection(IDeclarationFinderProvider declarationFinderPro protected override bool IsResultDeclaration(Declaration declaration, DeclarationFinder finder) { // exclude undeclared, see #5439 - return !declaration.IsWithEvents && !declaration.IsUndeclared + return !declaration.IsWithEvents + && !declaration.IsUndeclared && declaration.References.All(reference => reference.IsAssignment) - && !declaration.References.Any(IsForLoopAssignment); + && !declaration.References.Any(IsForLoopAssignment) + && !IsPublicInExposedClass(declaration); + } + + private static bool IsPublicInExposedClass(Declaration procedure) + { + if (!(procedure.Accessibility == Accessibility.Public + || procedure.Accessibility == Accessibility.Global)) + { + return false; + } + + if (!(Declaration.GetModuleParent(procedure) is ClassModuleDeclaration classParent)) + { + return false; + } + + return classParent.IsExposed; } private bool IsForLoopAssignment(IdentifierReference reference) diff --git a/Rubberduck.CodeAnalysis/Inspections/Extensions/DeclarationTypeExtensions.cs b/Rubberduck.CodeAnalysis/Inspections/Extensions/DeclarationTypeExtensions.cs index c1d3914a53..30c83a769f 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Extensions/DeclarationTypeExtensions.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Extensions/DeclarationTypeExtensions.cs @@ -1,6 +1,5 @@ using System.Globalization; using Rubberduck.Parsing.Symbols; -using Rubberduck.Resources; namespace Rubberduck.CodeAnalysis.Inspections.Extensions { @@ -9,7 +8,7 @@ public static class DeclarationTypeExtensions //ToDo: Move this to resources. (This will require moving resource lookups to Core.) public static string ToLocalizedString(this DeclarationType type) { - return RubberduckUI.ResourceManager.GetString("DeclarationType_" + type, CultureInfo.CurrentUICulture); + return CodeAnalysisUI.ResourceManager.GetString("DeclarationType_" + type, CultureInfo.CurrentUICulture); } } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/Inspections/Logistics/Inspector.cs b/Rubberduck.CodeAnalysis/Inspections/Logistics/Inspector.cs index 03cf73cf2a..fbee1bdac3 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Logistics/Inspector.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Logistics/Inspector.cs @@ -63,7 +63,7 @@ public async Task> FindIssuesAsync(RubberduckPars } token.ThrowIfCancellationRequested(); - state.OnStatusMessageUpdate(RubberduckUI.CodeInspections_Inspecting); + state.OnStatusMessageUpdate(CodeAnalysisUI.CodeInspections_Inspecting); var allIssues = new ConcurrentBag(); token.ThrowIfCancellationRequested(); diff --git a/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.Designer.cs b/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.Designer.cs index c7d0c0aed7..8a159534e8 100644 --- a/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.Designer.cs +++ b/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.Designer.cs @@ -1,10 +1,10 @@ //------------------------------------------------------------------------------ // -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 +// Este código fue generado por una herramienta. +// Versión de runtime:4.0.30319.42000 // -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. +// Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si +// se vuelve a generar el código. // //------------------------------------------------------------------------------ @@ -12,7 +12,7 @@ namespace Rubberduck.CodeAnalysis.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] public sealed partial class CodeInspectionDefaults : global::System.Configuration.ApplicationSettingsBase { private static CodeInspectionDefaults defaultInstance = ((CodeInspectionDefaults)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new CodeInspectionDefaults()))); @@ -28,131 +28,126 @@ public static CodeInspectionDefaults Default { [global::System.Configuration.DefaultSettingValueAttribute("\r\n\r\n \r\n \r\n \r\n \r\n <" + - "CodeInspection Name=\"UnhandledOnErrorResumeNextInspection\" Severity=\"Warning\" In" + - "spectionType=\"CodeQualityIssues\" />\r\n \r\n <" + - "CodeInspection Name=\"ImplicitByRefModifierInspection\" Severity=\"Hint\" Inspection" + - "Type=\"CodeQualityIssues\" />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n " + - " \r\n \r\n \r\n \r\n " + - " \r\n \r\n " + - " \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n" + - " \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n " + + " \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n " + - "\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <" + - "CodeInspection Name=\"IsMissingWithNonArgumentParameterInspection\" Severity=\"Warn" + - "ing\" InspectionType=\"CodeQualityIssues\" />\r\n \r\n" + - " \r\n \r\n \r\n \r\n true\r\n")] + "Inspection Name=\"ApplicationWorksheetFunctionInspection\" Severity=\"Suggestion\" I" + + "nspectionType=\"CodeQualityIssues\" />\r\n \r\n " + + "\r\n \r\n \r\n \r\n \r\n " + + " \r\n " + + "\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <" + + "CodeInspection Name=\"SelfAssignedDeclarationInspection\" Severity=\"Suggestion\" In" + + "spectionType=\"CodeQualityIssues\" />\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n <" + + "CodeInspection Name=\"AssignmentNotUsedInspection\" Severity=\"Suggestion\" Inspecti" + + "onType=\"CodeQualityIssues\" />\r\n " + + "\r\n \r\n \r\n " + + " \r\n \r\n \r\n \r\n true\r\n")] public global::Rubberduck.CodeAnalysis.Settings.CodeInspectionSettings CodeInspectionSettings { get { return ((global::Rubberduck.CodeAnalysis.Settings.CodeInspectionSettings)(this["CodeInspectionSettings"])); diff --git a/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.settings b/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.settings index d0b41da20e..2112d95f10 100644 --- a/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.settings +++ b/Rubberduck.CodeAnalysis/Properties/CodeInspectionDefaults.settings @@ -6,68 +6,64 @@ <?xml version="1.0" encoding="utf-16"?> <CodeInspectionSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <CodeInspections> - <CodeInspection Name="BooleanAssignedInIfElseInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="BooleanAssignedInIfElseInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="ObsoleteErrorSyntaxInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="StopKeywordInspection" Severity="Suggestion" InspectionType="CodeQualityIssues" /> <CodeInspection Name="UnhandledOnErrorResumeNextInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="EmptyStringLiteralInspection" Severity="Warning" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ImplicitByRefModifierInspection" Severity="Hint" InspectionType="CodeQualityIssues" /> <CodeInspection Name="FunctionReturnValueNotUsedInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> - <CodeInspection Name="IllegalAnnotationInspection" Severity="Error" InspectionType="RubberduckOpportunities" /> <CodeInspection Name="RedundantByRefModifierInspection" Severity="DoNotShow" InspectionType="CodeQualityIssues" /> <CodeInspection Name="MissingAttributeInspection" Severity="Warning" InspectionType="RubberduckOpportunities" /> - <CodeInspection Name="AttributeValueOutOfSyncInspection" Severity="Warning" InspectionType="RubberduckOpportunities" /> + <CodeInspection Name="AttributeOutOfSyncInspection" Severity="Warning" InspectionType="RubberduckOpportunities" /> <CodeInspection Name="MissingAnnotationArgumentInspection" Severity="Error" InspectionType="CodeQualityIssues" /> - <CodeInspection Name="MissingMemberAnnotationInspection" Severity="Error" InspectionType="RubberduckOpportunities" /> <CodeInspection Name="ModuleScopeDimKeywordInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="MultilineParameterInspection" Severity="Suggestion" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="MultipleDeclarationsInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="MultilineParameterInspection" Severity="Suggestion" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="MultipleDeclarationsInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="ObsoleteCallStatementInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ObsoleteCommentSyntaxInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ObsoleteLetStatementInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="OptionBaseInspection" Severity="Hint" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="OptionBaseInspection" Severity="Hint" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="RedundantOptionInspection" Severity="Hint" InspectionType="LanguageOpportunities" /> <CodeInspection Name="OptionExplicitInspection" Severity="Error" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ProcedureCanBeWrittenAsFunctionInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ApplicationWorksheetFunctionInspection" Severity="Suggestion" InspectionType="CodeQualityIssues" /> <CodeInspection Name="AssignedByValParameterInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> - <CodeInspection Name="EmptyModuleInspection" Severity="Hint" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="EmptyModuleInspection" Severity="Hint" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="LineLabelNotUsedInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="IntegerDataTypeInspection" Severity="Hint" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ShadowedDeclarationInspection" Severity="DoNotShow" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ConstantNotUsedInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> - <CodeInspection Name="DefaultProjectNameInspection" Severity="Suggestion" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EmptyCaseBlockInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EmptyDoWhileBlockInspection" Severity="Suggestion" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EmptyElseBlockInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EmptyForEachBlockInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EmptyForLoopBlockInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EmptyIfBlockInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EmptyWhileWendBlockInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> - <CodeInspection Name="EncapsulatePublicFieldInspection" Severity="Suggestion" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="DefaultProjectNameInspection" Severity="Suggestion" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EmptyCaseBlockInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EmptyDoWhileBlockInspection" Severity="Suggestion" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EmptyElseBlockInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EmptyForEachBlockInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EmptyForLoopBlockInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EmptyIfBlockInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EmptyWhileWendBlockInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> + <CodeInspection Name="EncapsulatePublicFieldInspection" Severity="Suggestion" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="HostSpecificExpressionInspection" Severity="Warning" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="HungarianNotationInspection" Severity="Suggestion" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="HungarianNotationInspection" Severity="Suggestion" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="ImplicitActiveSheetReferenceInspection" Severity="Warning" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="ImplicitContainingSheetReferenceInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ImplicitActiveWorkbookReferenceInspection" Severity="Warning" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="ImplicitContainingWorkbookReferenceInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ImplicitDefaultMemberAssignmentInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ImplicitPublicMemberInspection" Severity="Hint" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ImplicitVariantReturnTypeInspection" Severity="Hint" InspectionType="LanguageOpportunities" /> <CodeInspection Name="MemberNotOnInterfaceInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> - <CodeInspection Name="MoveFieldCloserToUsageInspection" Severity="Hint" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="MoveFieldCloserToUsageInspection" Severity="Hint" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="NonReturningFunctionInspection" Severity="Error" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ObjectVariableNotSetInspection" Severity="Error" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ObsoleteGlobalInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> <CodeInspection Name="ObsoleteTypeHintInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="ParameterCanBeByValInspection" Severity="Suggestion" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="ParameterCanBeByValInspection" Severity="Suggestion" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="ParameterNotUsedInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ProcedureNotUsedInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="SelfAssignedDeclarationInspection" Severity="Suggestion" InspectionType="CodeQualityIssues" /> <CodeInspection Name="UnassignedVariableUsageInspection" Severity="Error" InspectionType="CodeQualityIssues" /> <CodeInspection Name="UndeclaredVariableInspection" Severity="Error" InspectionType="CodeQualityIssues" /> <CodeInspection Name="UntypedFunctionUsageInspection" Severity="Hint" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="UseMeaningfulNameInspection" Severity="Suggestion" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="UseMeaningfulNameInspection" Severity="Suggestion" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="VariableNotAssignedInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="VariableNotUsedInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="VariableTypeNotDeclaredInspection" Severity="Warning" InspectionType="LanguageOpportunities" /> @@ -76,7 +72,7 @@ <CodeInspection Name="StepIsNotSpecifiedInspection" Severity="DoNotShow" InspectionType="LanguageOpportunities" /> <CodeInspection Name="StepOneIsRedundantInspection" Severity="Hint" InspectionType="LanguageOpportunities" /> <CodeInspection Name="SheetAccessedUsingStringInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> - <CodeInspection Name="ObsoleteMemberUsageInspection" Severity="Warning" InspectionType="MaintainabilityAndReadabilityIssues" /> + <CodeInspection Name="ObsoleteMemberUsageInspection" Severity="Warning" InspectionType="NamingAndConventionsIssues" /> <CodeInspection Name="ObsoleteCallingConventionInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="DuplicatedAnnotationInspection" Severity="Error" InspectionType="RubberduckOpportunities" /> <CodeInspection Name="ModuleWithoutFolderInspection" Severity="Suggestion" InspectionType="RubberduckOpportunities" /> @@ -86,6 +82,9 @@ <CodeInspection Name="AssignmentNotUsedInspection" Severity="Suggestion" InspectionType="CodeQualityIssues" /> <CodeInspection Name="UnderscoreInPublicClassModuleMemberInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ExcelUdfNameIsValidCellReferenceInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> + <CodeInspection Name="EmptyMethodInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> + <CodeInspection Name="ImplementedInterfaceMemberInspection" Severity="Suggestion" InspectionType="CodeQualityIssues" /> + <CodeInspection Name="PublicControlFieldAccessInspection" Severity="Hint" InspectionType="LanguageOpportunities" /> </CodeInspections> <WhitelistedIdentifiers /> <RunInspectionsOnSuccessfulParse>true</RunInspectionsOnSuccessfulParse> diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Abstract/QuickFixBase.cs b/Rubberduck.CodeAnalysis/QuickFixes/Abstract/QuickFixBase.cs index 10545fb184..851cc390bc 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Abstract/QuickFixBase.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Abstract/QuickFixBase.cs @@ -55,6 +55,22 @@ public void RemoveInspections(params Type[] inspections) public virtual CodeKind TargetCodeKind => CodeKind.CodePaneCode; public abstract void Fix(IInspectionResult result, IRewriteSession rewriteSession); + + /// + /// FixMany defers the enumeration of inspection results to the QuickFix + /// + /// + /// The default implementation enumerates the results collection calling Fix() for each result. + /// Override this funcion when a QuickFix needs operate on results as a group (e.g., RemoveUnusedDeclarationQuickFix) + /// + public virtual void Fix(IReadOnlyCollection results, IRewriteSession rewriteSession) + { + foreach (var result in results) + { + Fix(result, rewriteSession); + } + } + public abstract string Description(IInspectionResult result); public abstract bool CanFixMultiple { get; } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AccessSheetUsingCodeNameQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AccessSheetUsingCodeNameQuickFix.cs index 921ef72e68..e7c737e8c5 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AccessSheetUsingCodeNameQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AccessSheetUsingCodeNameQuickFix.cs @@ -106,10 +106,7 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio } } - public override string Description(IInspectionResult result) - { - return Resources.Inspections.QuickFixes.AccessSheetUsingCodeNameQuickFix; - } + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AccessSheetUsingCodeNameQuickFix; public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddMissingAttributeQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddMissingAttributeQuickFix.cs index 577d51751e..2307dc13a2 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddMissingAttributeQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddMissingAttributeQuickFix.cs @@ -73,10 +73,10 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio _attributesUpdater.AddAttribute(rewriteSession, declaration, attributeName, annotation.AttributeValues(annotationInstance)); } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AddMissingAttributeQuickFix; - public override CodeKind TargetCodeKind => CodeKind.AttributesCode; + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AddMissingAttributeQuickFix; + public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; public override bool CanFixInModule => true; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddStepOneQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddStepOneQuickFix.cs index 0d78b6c091..82195421b0 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddStepOneQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AddStepOneQuickFix.cs @@ -42,17 +42,6 @@ public AddStepOneQuickFix() : base(typeof(StepIsNotSpecifiedInspection)) {} - public override bool CanFixMultiple => true; - public override bool CanFixInProcedure => true; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; - public override bool CanFixAll => true; - - public override string Description(IInspectionResult result) - { - return Resources.Inspections.QuickFixes.AddStepOneQuickFix; - } - public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); @@ -76,5 +65,13 @@ private static int GetToExpressionEnd(ForNextStmtContext context) throw new InvalidOperationException(); } + + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AddStepOneQuickFix; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => true; + public override bool CanFixInModule => true; + public override bool CanFixInProject => true; + public override bool CanFixAll => true; } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AdjustAttributeValuesQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AdjustAttributeValuesQuickFix.cs index 2b90493cd7..57c400af68 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AdjustAttributeValuesQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AdjustAttributeValuesQuickFix.cs @@ -85,10 +85,10 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio _attributesUpdater.UpdateAttribute(rewriteSession, declaration, attributeName, attributeValuesFromAnnotation, oldValues: attributeValues); } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AdjustAttributeValuesQuickFix; - public override CodeKind TargetCodeKind => CodeKind.AttributesCode; + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AdjustAttributeValuesQuickFix; + public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; public override bool CanFixInModule => true; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AnnotateEntryPointQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AnnotateEntryPointQuickFix.cs index c2c35f98b2..d04711e8bc 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AnnotateEntryPointQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AnnotateEntryPointQuickFix.cs @@ -44,12 +44,6 @@ public AnnotateEntryPointQuickFix(IAnnotationUpdater annotationUpdater, Rubberdu _annotationUpdater = annotationUpdater; } - public override bool CanFixMultiple => true; - public override bool CanFixInProcedure => true; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; - public override bool CanFixAll => true; - public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var module = result.QualifiedSelection.QualifiedName; @@ -65,5 +59,11 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio } public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AnnotateEntryPointQuickFix; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => true; + public override bool CanFixInModule => true; + public override bool CanFixInProject => true; + public override bool CanFixAll => true; } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AssignedByValParameterMakeLocalCopyQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AssignedByValParameterMakeLocalCopyQuickFix.cs index 2881f1e43b..a247c06b31 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AssignedByValParameterMakeLocalCopyQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/AssignedByValParameterMakeLocalCopyQuickFix.cs @@ -77,14 +77,6 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio InsertLocalVariableDeclarationAndAssignment(rewriter, result.Target, localIdentifier); } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AssignedByValParameterMakeLocalCopyQuickFix; - - public override bool CanFixMultiple => false; - public override bool CanFixInProcedure => false; - public override bool CanFixInModule => false; - public override bool CanFixInProject => false; - public override bool CanFixAll => false; - private string PromptForLocalVariableName(Declaration target) { IAssignedByValParameterQuickFixDialog view = null; @@ -165,5 +157,14 @@ private void InsertLocalVariableDeclarationAndAssignment(IModuleRewriter rewrite rewriter.Remove(endOfStmtCtxt); rewriter.InsertAfter(insertCtxt.Stop.TokenIndex, $"{endOfStmtCtxtComment}{endOfStmtCtxtEndFormat}{localVariableDeclaration}" + $"{endOfStmtCtxtEndFormat}{localVariableAssignment}{endOfStmtCtxtEndFormat}"); } + + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.AssignedByValParameterMakeLocalCopyQuickFix; + + public override bool CanFixMultiple => false; + public override bool CanFixInProcedure => false; + public override bool CanFixInModule => false; + public override bool CanFixInProject => false; + public override bool CanFixAll => false; + } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeIntegerToLongQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeIntegerToLongQuickFix.cs index 254dd3953e..2c373249bc 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeIntegerToLongQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeIntegerToLongQuickFix.cs @@ -194,14 +194,6 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio } } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.IntegerDataTypeQuickFix; - - public override bool CanFixMultiple => true; - public override bool CanFixInProcedure => true; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; - public override bool CanFixAll => true; - private static int GetParameterIndex(VBAParser.ArgContext context) { return Array.IndexOf(((VBAParser.ArgListContext)context.Parent).arg().ToArray(), context); @@ -212,5 +204,13 @@ private static void ReplaceTypeHint(RuleContext context, IModuleRewriter rewrite var typeHintContext = ((ParserRuleContext)context).GetDescendent(); rewriter.Replace(typeHintContext, "&"); } + + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.IntegerDataTypeQuickFix; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => true; + public override bool CanFixInModule => true; + public override bool CanFixInProject => true; + public override bool CanFixAll => true; } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeProcedureToFunctionQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeProcedureToFunctionQuickFix.cs index 90847a1f75..d355ac16f2 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeProcedureToFunctionQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ChangeProcedureToFunctionQuickFix.cs @@ -66,8 +66,6 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio } } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ProcedureShouldBeFunctionInspectionQuickFix; - private void UpdateSignature(Declaration target, ParameterDeclaration arg, IRewriteSession rewriteSession) { var subStmt = (VBAParser.SubStmtContext) target.Context; @@ -107,6 +105,8 @@ private void UpdateCall(IdentifierReference reference, int argIndex, IRewriteSes rewriter.InsertAfter(argListContext.Stop.TokenIndex, ")"); } + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ProcedureShouldBeFunctionInspectionQuickFix; + public override bool CanFixMultiple => true; public override bool CanFixInProcedure => false; public override bool CanFixInModule => false; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ConvertToProcedureQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ConvertToProcedureQuickFix.cs index 542e5a259d..afad02d184 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ConvertToProcedureQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ConvertToProcedureQuickFix.cs @@ -17,7 +17,7 @@ namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete /// /// /// - /// + /// /// /// /// @@ -180,14 +180,6 @@ private static void ConvertExitPropertyStatements(VBAParser.PropertyGetStmtConte } } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ConvertFunctionToProcedureQuickFix; - - public override bool CanFixMultiple => true; - public override bool CanFixInProcedure => false; - public override bool CanFixInModule => true; - public override bool CanFixInProject => false; - public override bool CanFixAll => false; - private IEnumerable GetReturnStatements(Declaration declaration) { return declaration.References @@ -200,5 +192,13 @@ private bool IsReturnStatement(Declaration declaration, IdentifierReference assi { return assignment.ParentScoping.Equals(declaration) && assignment.Declaration.Equals(declaration); } + + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ConvertFunctionToProcedureQuickFix; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => false; + public override bool CanFixInModule => true; + public override bool CanFixInProject => false; + public override bool CanFixAll => false; } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/DeclareAsExplicitTypeQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/DeclareAsExplicitTypeQuickFix.cs index c425495742..cc93d95114 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/DeclareAsExplicitTypeQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/DeclareAsExplicitTypeQuickFix.cs @@ -84,18 +84,17 @@ public DeclareAsExplicitTypeQuickFix(ImplicitTypeToExplicitRefactoringAction ref _refactoring = refactoringAction; } - public override bool CanFixMultiple => true; - public override bool CanFixInProcedure => false; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; - public override bool CanFixAll => true; - public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { _refactoring.Refactor(new ImplicitTypeToExplicitModel(result.Target), rewriteSession); } - public override string Description(IInspectionResult result) - => Resources.Inspections.QuickFixes.DeclareAsExplicitTypeQuickFix; + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.DeclareAsExplicitTypeQuickFix; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => false; + public override bool CanFixInModule => true; + public override bool CanFixInProject => true; + public override bool CanFixAll => true; } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandBangNotationQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandBangNotationQuickFix.cs index 418ccbdedf..2e9098efb7 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandBangNotationQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandBangNotationQuickFix.cs @@ -47,6 +47,14 @@ namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete /// internal class ExpandBangNotationQuickFix : QuickFixBase { + private readonly string NonIdentifierCharacters = "[](){}\r\n\t.,'\"\\ |!@#$%^&*-+:=; "; + private readonly string AdditionalNonFirstIdentifierCharacters = "0123456789_"; + + private static readonly Dictionary DefaultMemberOverrides = new Dictionary + { + ["Excel.Range._Default"] = "Item" + }; + private readonly IDeclarationFinderProvider _declarationFinderProvider; public ExpandBangNotationQuickFix(IDeclarationFinderProvider declarationFinderProvider) @@ -121,24 +129,12 @@ private bool IsNotLegalIdentifierName(string declarationName) || AdditionalNonFirstIdentifierCharacters.Contains(declarationName[0]); ; } - public override string Description(IInspectionResult result) - { - return Resources.Inspections.QuickFixes.ExpandBangNotationQuickFix; - } + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ExpandBangNotationQuickFix; public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; public override bool CanFixInModule => true; public override bool CanFixInProject => true; public override bool CanFixAll => true; - - private readonly string NonIdentifierCharacters = "[](){}\r\n\t.,'\"\\ |!@#$%^&*-+:=; "; - private readonly string AdditionalNonFirstIdentifierCharacters = "0123456789_"; - - private static readonly Dictionary DefaultMemberOverrides = new Dictionary - { - ["Excel.Range._Default"] = "Item" - }; - } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandDefaultMemberQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandDefaultMemberQuickFix.cs index 07160ef591..c3683b3ed6 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandDefaultMemberQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ExpandDefaultMemberQuickFix.cs @@ -51,6 +51,19 @@ namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete /// internal class ExpandDefaultMemberQuickFix : QuickFixBase { + private string NonIdentifierCharacters = "[](){}\r\n\t.,'\"\\ |!@#$%^&*-+:=; "; + private string AdditionalNonFirstIdentifierCharacters = "0123456789_"; + + private static readonly Dictionary DefaultMemberBaseOverrides = new Dictionary + { + ["Excel.Range._Default"] = "Item" + }; + + private static readonly Dictionary> DefaultMemberArgumentNumberOverrides = new Dictionary> + { + ["Excel.Range._Default"] = new Dictionary { [0] = "Value" } + }; + private readonly IDeclarationFinderProvider _declarationFinderProvider; public ExpandDefaultMemberQuickFix(IDeclarationFinderProvider declarationFinderProvider) @@ -165,28 +178,12 @@ private static VBAParser.ArgumentListContext ArgumentList(IdentifierReference in } } - public override string Description(IInspectionResult result) - { - return Resources.Inspections.QuickFixes.ExpandDefaultMemberQuickFix; - } + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ExpandDefaultMemberQuickFix; public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; public override bool CanFixInModule => true; public override bool CanFixInProject => true; public override bool CanFixAll => true; - - private string NonIdentifierCharacters = "[](){}\r\n\t.,'\"\\ |!@#$%^&*-+:=; "; - private string AdditionalNonFirstIdentifierCharacters = "0123456789_"; - - private static readonly Dictionary DefaultMemberBaseOverrides = new Dictionary - { - ["Excel.Range._Default"] = "Item" - }; - - private static readonly Dictionary> DefaultMemberArgumentNumberOverrides = new Dictionary> - { - ["Excel.Range._Default"] = new Dictionary{[0] = "Value"} - }; } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreInModuleQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreInModuleQuickFix.cs index 41c4d015da..92f185f3ec 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreInModuleQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreInModuleQuickFix.cs @@ -52,12 +52,6 @@ public IgnoreInModuleQuickFix(IAnnotationUpdater annotationUpdater, RubberduckPa _annotationUpdater = annotationUpdater; } - public override bool CanFixMultiple => true; - public override bool CanFixInProcedure => false; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; - public override bool CanFixAll => true; - public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var module = result.QualifiedSelection.QualifiedName; @@ -101,5 +95,11 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio } public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.IgnoreInModuleQuickFix; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => false; + public override bool CanFixInModule => true; + public override bool CanFixInProject => true; + public override bool CanFixAll => true; } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreOnceQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreOnceQuickFix.cs index 5d93894dbc..057790dd5c 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreOnceQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/IgnoreOnceQuickFix.cs @@ -48,12 +48,6 @@ public IgnoreOnceQuickFix(IAnnotationUpdater annotationUpdater, RubberduckParser _annotationUpdater = annotationUpdater; } - public override bool CanFixMultiple => true; - public override bool CanFixInProcedure => true; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; - public override bool CanFixAll => true; - public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { if (result.Target?.DeclarationType.HasFlag(DeclarationType.Module) ?? false) @@ -109,5 +103,11 @@ private void FixModule(IInspectionResult result, IRewriteSession rewriteSession) } public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.IgnoreOnce; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => true; + public override bool CanFixInModule => true; + public override bool CanFixInProject => true; + public override bool CanFixAll => true; } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/PassParameterByValueQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/PassParameterByValueQuickFix.cs index 90e2ae795f..6323cadb32 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/PassParameterByValueQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/PassParameterByValueQuickFix.cs @@ -56,8 +56,6 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio } } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.PassParameterByValueQuickFix; - private void FixMethods(Declaration target, IRewriteSession rewriteSession) { var declarationParameters = @@ -111,6 +109,8 @@ private void FixMethod(VBAParser.ArgContext context, QualifiedSelection qualifie } } + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.PassParameterByValueQuickFix; + public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; public override bool CanFixInModule => true; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/QualifyWithMeQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/QualifyWithMeQuickFix.cs index 32734ccddb..be5b97cad9 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/QualifyWithMeQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/QualifyWithMeQuickFix.cs @@ -47,10 +47,7 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio rewriter.InsertBefore(context.Start.TokenIndex, $"{Tokens.Me}."); } - public override string Description(IInspectionResult result) - { - return Resources.Inspections.QuickFixes.QualifyWithMeQuickFix; - } + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.QualifyWithMeQuickFix; public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/MoveFieldCloserToUsageQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/MoveFieldCloserToUsageQuickFix.cs index 1b08d43003..2f24634f42 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/MoveFieldCloserToUsageQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/MoveFieldCloserToUsageQuickFix.cs @@ -50,7 +50,7 @@ protected override void Refactor(IInspectionResult result) public override string Description(IInspectionResult result) { - return string.Format(InspectionResults.MoveFieldCloserToUsageInspection, result.Target.IdentifierName); + return string.Format(Resources.Inspections.InspectionResults.MoveFieldCloserToUsageInspection, result.Target.IdentifierName); } } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/RenameDeclarationQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/RenameDeclarationQuickFix.cs index 5e8121cc39..6d94244f79 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/RenameDeclarationQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/Refactoring/RenameDeclarationQuickFix.cs @@ -2,6 +2,7 @@ using Rubberduck.CodeAnalysis.Inspections; using Rubberduck.CodeAnalysis.Inspections.Concrete; using Rubberduck.CodeAnalysis.QuickFixes.Abstract; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Rename; using Rubberduck.Resources; @@ -64,9 +65,8 @@ protected override void Refactor(IInspectionResult result) public override string Description(IInspectionResult result) { - return string.Format(RubberduckUI.Rename_DeclarationType, - RubberduckUI.ResourceManager.GetString("DeclarationType_" + result.Target.DeclarationType, - CultureInfo.CurrentUICulture)); + return string.Format(Resources.Inspections.QuickFixes.RenameDeclarationQuickFix, + RubberduckUI.ResourceManager.GetString("DeclarationType_" + result.Target.DeclarationType, CultureInfo.CurrentUICulture)); } } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveDuplicatedAnnotationQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveDuplicatedAnnotationQuickFix.cs index 46e8735952..4c89f5d0df 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveDuplicatedAnnotationQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveDuplicatedAnnotationQuickFix.cs @@ -63,8 +63,7 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio _annotationUpdater.RemoveAnnotations(rewriteSession, duplicateAnnotations); } - public override string Description(IInspectionResult result) => - Resources.Inspections.QuickFixes.RemoveDuplicatedAnnotationQuickFix; + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.RemoveDuplicatedAnnotationQuickFix; public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveOptionBaseStatementQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveRedundantOptionStatementQuickFix.cs similarity index 86% rename from Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveOptionBaseStatementQuickFix.cs rename to Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveRedundantOptionStatementQuickFix.cs index 2538a3669f..6fb2714570 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveOptionBaseStatementQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveRedundantOptionStatementQuickFix.cs @@ -35,9 +35,9 @@ namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete /// ]]> /// /// - internal sealed class RemoveOptionBaseStatementQuickFix : QuickFixBase + internal sealed class RemoveRedundantOptionStatementQuickFix : QuickFixBase { - public RemoveOptionBaseStatementQuickFix() + public RemoveRedundantOptionStatementQuickFix() : base(typeof(RedundantOptionInspection)) {} @@ -47,7 +47,10 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio rewriter.Remove(result.Context); } - public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.RemoveOptionBaseStatementQuickFix; + public override string Description(IInspectionResult result) + { + return string.Format(Resources.Inspections.QuickFixes.RemoveRedundantOptionStatementQuickFix, result.Context.GetText()); + } public override bool CanFixMultiple => true; public override bool CanFixInProcedure => false; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnassignedIdentifierQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnassignedIdentifierQuickFix.cs index 99332eca24..ac24979f85 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnassignedIdentifierQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnassignedIdentifierQuickFix.cs @@ -2,6 +2,10 @@ using Rubberduck.CodeAnalysis.Inspections.Concrete; using Rubberduck.CodeAnalysis.QuickFixes.Abstract; using Rubberduck.Parsing.Rewriter; +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.DeleteDeclarations; +using System.Collections.Generic; +using System.Linq; namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete { @@ -35,14 +39,25 @@ namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete /// internal sealed class RemoveUnassignedIdentifierQuickFix : QuickFixBase { - public RemoveUnassignedIdentifierQuickFix() + private readonly ICodeOnlyRefactoringAction _refactoring; + public RemoveUnassignedIdentifierQuickFix(DeleteDeclarationsRefactoringAction refactoringAction) : base(typeof(VariableNotAssignedInspection)) - {} + { + _refactoring = refactoringAction; + } public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); - rewriter.Remove(result.Target); + var model = new DeleteDeclarationsModel(result.Target); + + _refactoring.Refactor(model, rewriteSession); + } + + public override void Fix(IReadOnlyCollection results, IRewriteSession rewriteSession) + { + var model = new DeleteDeclarationsModel(results.Select(r => r.Target)); + + _refactoring.Refactor(model, rewriteSession); } public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.RemoveUnassignedIdentifierQuickFix; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnusedDeclarationQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnusedDeclarationQuickFix.cs index 2116c8d0ac..8bd00953db 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnusedDeclarationQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/RemoveUnusedDeclarationQuickFix.cs @@ -2,6 +2,12 @@ using Rubberduck.CodeAnalysis.Inspections.Concrete; using Rubberduck.CodeAnalysis.QuickFixes.Abstract; using Rubberduck.Parsing.Rewriter; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.Common; +using Rubberduck.Refactorings.DeleteDeclarations; +using System.Collections.Generic; +using System.Linq; namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete { @@ -31,7 +37,6 @@ namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete /// Option Explicit /// /// Public Sub DoSomething() - /// /// Debug.Print 42 /// End Sub /// ]]> @@ -39,17 +44,30 @@ namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete /// internal sealed class RemoveUnusedDeclarationQuickFix : QuickFixBase { - public RemoveUnusedDeclarationQuickFix() + private readonly ICodeOnlyRefactoringAction _refactoring; + + public RemoveUnusedDeclarationQuickFix(DeleteDeclarationsRefactoringAction refactoringAction) : base(typeof(ConstantNotUsedInspection), typeof(ProcedureNotUsedInspection), typeof(VariableNotUsedInspection), - typeof(LineLabelNotUsedInspection)) - {} + typeof(LineLabelNotUsedInspection), + typeof(UDTMemberNotUsedInspection)) + { + _refactoring = refactoringAction; + } public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); - rewriter.Remove(result.Target); + var model = new DeleteDeclarationsModel(result.Target); + + _refactoring.Refactor(model, rewriteSession); + } + + public override void Fix(IReadOnlyCollection results, IRewriteSession rewriteSession) + { + var model = new DeleteDeclarationsModel(results.Select(r => r.Target)); + + _refactoring.Refactor(model, rewriteSession); } public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.RemoveUnusedDeclarationQuickFix; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ReplaceQualifierWithMeQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ReplaceQualifierWithMeQuickFix.cs new file mode 100644 index 0000000000..eb1451a544 --- /dev/null +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/ReplaceQualifierWithMeQuickFix.cs @@ -0,0 +1,64 @@ +using Rubberduck.CodeAnalysis.Inspections; +using Rubberduck.CodeAnalysis.Inspections.Concrete; +using Rubberduck.CodeAnalysis.QuickFixes.Abstract; +using Rubberduck.Parsing.Rewriter; +using Rubberduck.Resources; + +namespace Rubberduck.CodeAnalysis.QuickFixes.Concrete +{ + /// + /// Replaces an explicit qualifier with 'Me'. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + internal class ReplaceQualifierWithMeQuickFix : QuickFixBase + { + public ReplaceQualifierWithMeQuickFix() + :base(typeof(SuspiciousPredeclaredInstanceAccessInspection)) + {} + + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) + { + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); + + var context = result.Context; + rewriter.Replace(context.Start, Tokens.Me); + } + + public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ReplaceQualifierWithMeQuickFix; + + public override bool CanFixMultiple => true; + public override bool CanFixInProcedure => true; + public override bool CanFixInModule => true; + public override bool CanFixInProject => true; + public override bool CanFixAll => true; + } +} diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/UntypedFunctionUsageQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/UntypedFunctionUsageQuickFix.cs index 5338f547e6..d886821071 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Concrete/UntypedFunctionUsageQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Concrete/UntypedFunctionUsageQuickFix.cs @@ -48,11 +48,6 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio rewriter.InsertAfter(result.Context.Stop.TokenIndex, "$"); } - public override string Description(IInspectionResult result) - { - return string.Format(Resources.Inspections.QuickFixes.UseTypedFunctionQuickFix, result.Context.GetText(), GetNewSignature(result.Context)); - } - private static string GetNewSignature(ParserRuleContext context) { Debug.Assert(context != null); @@ -64,6 +59,11 @@ private static string GetNewSignature(ParserRuleContext context) }); } + public override string Description(IInspectionResult result) + { + return string.Format(Resources.Inspections.QuickFixes.UseTypedFunctionQuickFix, result.Context.GetText(), GetNewSignature(result.Context)); + } + public override bool CanFixMultiple => true; public override bool CanFixInProcedure => true; public override bool CanFixInModule => true; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/IQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/IQuickFix.cs index f533cf473d..3de80809f8 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/IQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/IQuickFix.cs @@ -9,6 +9,7 @@ namespace Rubberduck.CodeAnalysis.QuickFixes public interface IQuickFix { void Fix(IInspectionResult result, IRewriteSession rewriteSession); + void Fix(IReadOnlyCollection results, IRewriteSession rewriteSession); string Description(IInspectionResult result); bool CanFixMultiple { get; } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/Logistics/QuickFixProvider.cs b/Rubberduck.CodeAnalysis/QuickFixes/Logistics/QuickFixProvider.cs index 308a1bbf9f..48835f7c3c 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/Logistics/QuickFixProvider.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/Logistics/QuickFixProvider.cs @@ -59,17 +59,17 @@ public bool CanFix(IQuickFix fix, IInspectionResult result) && !result.DisabledQuickFixes.Contains(fix.GetType().Name); } - public void Fix(IQuickFix fix, IInspectionResult result) + public void Fix(IQuickFix quickFix, IInspectionResult result) { - if (!CanFix(fix, result)) + if (!CanFix(quickFix, result)) { return; } - var rewriteSession = RewriteSession(fix.TargetCodeKind); + var rewriteSession = RewriteSession(quickFix.TargetCodeKind); try { - fix.Fix(result, rewriteSession); + quickFix.Fix(result, rewriteSession); } catch (RewriteFailedException) { @@ -78,24 +78,24 @@ public void Fix(IQuickFix fix, IInspectionResult result) Apply(rewriteSession); } - public void Fix(IQuickFix fix, IEnumerable resultsToFix) + public void Fix(IQuickFix quickFix, IEnumerable resultsToFix) { - var results = resultsToFix.ToList(); + var fixableResults = resultsToFix.Where(r => CanFix(quickFix, r)).ToList(); - if (!results.Any()) + if (!fixableResults.Any()) { return; } - var rewriteSession = RewriteSession(fix.TargetCodeKind); - foreach (var result in results) - { - if (!CanFix(fix, result)) - { - continue; - } + var rewriteSession = RewriteSession(quickFix.TargetCodeKind); - fix.Fix(result, rewriteSession); + try + { + quickFix.Fix(fixableResults, rewriteSession); + } + catch (RewriteFailedException) + { + _failureNotifier.NotifyQuickFixExecutionFailure(rewriteSession.Status); } Apply(rewriteSession); } diff --git a/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj b/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj index 1dcd7c7375..b39c0b1b32 100644 --- a/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj +++ b/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj @@ -3,7 +3,7 @@ Rubberduck.CodeAnalysis Assembly Containing the Code Analysis features exposed by Rubberduck - Copyright © 2017-2019 + Copyright © 2017-2023 Rubberduck.CodeAnalysis Rubberduck.CodeAnalysis Rubberduck.CodeAnalysis @@ -61,12 +61,24 @@ + + True + True + CodeAnalysisUI.resx + True True CodeInspectionDefaults.settings + True + + + PublicResXFileCodeGenerator + CodeAnalysisUI.Designer.cs + + PublicSettingsSingleFileGenerator diff --git a/Rubberduck.CodeAnalysis/app.config b/Rubberduck.CodeAnalysis/app.config index 688666fbff..56c52616a5 100644 --- a/Rubberduck.CodeAnalysis/app.config +++ b/Rubberduck.CodeAnalysis/app.config @@ -21,85 +21,163 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true diff --git a/Rubberduck.Core/AddRemoveReferences/ReferenceReconciler.cs b/Rubberduck.Core/AddRemoveReferences/ReferenceReconciler.cs index 9326b82e99..09919713ac 100644 --- a/Rubberduck.Core/AddRemoveReferences/ReferenceReconciler.cs +++ b/Rubberduck.Core/AddRemoveReferences/ReferenceReconciler.cs @@ -137,7 +137,7 @@ public ReferenceModel TryAddReference(IVBProject project, string path) } catch (COMException ex) { - _messageBox.NotifyWarn(ex.Message, RubberduckUI.References_AddFailedCaption); + _messageBox.NotifyWarn(ex.Message, AddRemoveReferencesUI.AddFailedCaption); } return null; } @@ -158,7 +158,7 @@ public ReferenceModel TryAddReference(IVBProject project, ReferenceModel referen } catch (COMException ex) { - _messageBox.NotifyWarn(ex.Message, RubberduckUI.References_AddFailedCaption); + _messageBox.NotifyWarn(ex.Message, AddRemoveReferencesUI.AddFailedCaption); } return null; } diff --git a/Rubberduck.Core/AddRemoveReferences/RegisteredLibraryInfo.cs b/Rubberduck.Core/AddRemoveReferences/RegisteredLibraryInfo.cs index 27b06df61a..7f638e4c22 100644 --- a/Rubberduck.Core/AddRemoveReferences/RegisteredLibraryInfo.cs +++ b/Rubberduck.Core/AddRemoveReferences/RegisteredLibraryInfo.cs @@ -3,6 +3,7 @@ using System.Globalization; using Path = System.IO.Path; using System.Runtime.InteropServices.ComTypes; +using Rubberduck.UI.AddRemoveReferences; namespace Rubberduck.AddRemoveReferences { @@ -24,7 +25,7 @@ public class RegisteredLibraryInfo { private static readonly Dictionary NativeLocaleNames = new Dictionary { - { 0, Resources.RubberduckUI.References_DefaultLocale } + { 0, AddRemoveReferencesUI.DefaultLocale } }; public RegisteredLibraryKey UniqueId { get; } @@ -54,8 +55,8 @@ public string LocaleName } catch { - NativeLocaleNames.Add(LocaleId, Resources.RubberduckUI.References_DefaultLocale); - return Resources.RubberduckUI.References_DefaultLocale; + NativeLocaleNames.Add(LocaleId, AddRemoveReferencesUI.DefaultLocale); + return AddRemoveReferencesUI.DefaultLocale; } } } diff --git a/Rubberduck.Core/App.cs b/Rubberduck.Core/App.cs index 11a37f3320..3b8c264949 100644 --- a/Rubberduck.Core/App.cs +++ b/Rubberduck.Core/App.cs @@ -17,6 +17,7 @@ using Application = System.Windows.Forms.Application; using Rubberduck.SettingsProvider; using System.IO.Abstractions; +using Microsoft.Win32; namespace Rubberduck { @@ -26,7 +27,7 @@ public sealed class App : IDisposable private readonly IConfigurationService _configService; private readonly IAppMenu _appMenus; private readonly IRubberduckHooks _hooks; - private readonly IVersionCheck _version; + private readonly IVersionCheckService _version; private readonly CommandBase _checkVersionCommand; private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); @@ -38,7 +39,7 @@ public App(IMessageBox messageBox, IConfigurationService configService, IAppMenu appMenus, IRubberduckHooks hooks, - IVersionCheck version, + IVersionCheckService version, CommandBase checkVersionCommand, IFileSystem filesystem) { @@ -231,11 +232,22 @@ public void LogRubberduckStart() { var version = _version.CurrentVersion; GlobalDiagnosticsContext.Set("RubberduckVersion", version.ToString()); + string osProductName = ""; + string osReleaseId = ""; + try + { + osProductName = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName", "").ToString(); + osReleaseId = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ReleaseId", "").ToString(); + } + catch + { + Logger.Debug("Failure to read OS version from registry. Logged version will be incomplete."); + } var headers = new List { $"\r\n\tRubberduck version {version} loading:", - $"\tOperating System: {Environment.OSVersion.VersionString} {(Environment.Is64BitOperatingSystem ? "x64" : "x86")}" + $"\tOperating System: {osProductName} {osReleaseId} {(Environment.Is64BitOperatingSystem ? "x64" : "x86")} ({Environment.OSVersion.VersionString})" }; try { diff --git a/Rubberduck.Core/Common/Hotkeys/HotkeyInfo.cs b/Rubberduck.Core/Common/Hotkeys/HotkeyInfo.cs index 05d2afa764..85c6e6cccc 100644 --- a/Rubberduck.Core/Common/Hotkeys/HotkeyInfo.cs +++ b/Rubberduck.Core/Common/Hotkeys/HotkeyInfo.cs @@ -1,7 +1,7 @@ using System; using System.Text; using System.Windows.Forms; -using Rubberduck.Resources; +using Rubberduck.UI.Settings; namespace Rubberduck.Common.Hotkeys { @@ -23,17 +23,17 @@ public override string ToString() var builder = new StringBuilder(); if (Keys.HasFlag(Keys.Alt)) { - builder.Append(RubberduckUI.GeneralSettings_HotkeyAlt); + builder.Append(GeneralSettingsUI.HotkeyAlt); builder.Append('+'); } if (Keys.HasFlag(Keys.Control)) { - builder.Append(RubberduckUI.GeneralSettings_HotkeyCtrl); + builder.Append(GeneralSettingsUI.HotkeyCtrl); builder.Append('+'); } if (Keys.HasFlag(Keys.Shift)) { - builder.Append(RubberduckUI.GeneralSettings_HotkeyShift); + builder.Append(GeneralSettingsUI.HotkeyShift); builder.Append('+'); } diff --git a/Rubberduck.Core/Common/RubberduckHooks.cs b/Rubberduck.Core/Common/RubberduckHooks.cs index c908de876a..69217aad61 100644 --- a/Rubberduck.Core/Common/RubberduckHooks.cs +++ b/Rubberduck.Core/Common/RubberduckHooks.cs @@ -121,13 +121,18 @@ public void Detach() private void hook_MessageReceived(object sender, HookEventArgs e) { - if (sender is IHotkey hotkey - && hotkey.Command.CanExecute(null)) + if (sender is IHotkey hotkey) { - hotkey.Command.Execute(null); - return; + if (hotkey.Command.CanExecute(null)) + { + hotkey.Command.Execute(null); + return; + } + else + { + Console.Beep(); + } } - OnMessageReceived(sender, e); } diff --git a/Rubberduck.Core/Formatters/ToDoItemFormatter.cs b/Rubberduck.Core/Formatters/ToDoItemFormatter.cs index 567016fab2..943b627554 100644 --- a/Rubberduck.Core/Formatters/ToDoItemFormatter.cs +++ b/Rubberduck.Core/Formatters/ToDoItemFormatter.cs @@ -1,6 +1,6 @@ using Rubberduck.ToDoItems; using Rubberduck.Common; -using Rubberduck.Resources; +using Rubberduck.Resources.ToDoExplorer; namespace Rubberduck.Formatters { @@ -22,7 +22,7 @@ public object[] ToArray() public string ToClipboardString() { var module = _toDoItem.Selection.QualifiedName; - return string.Format(RubberduckUI.ToDoExplorerToDoItemFormat, + return string.Format(ToDoExplorerUI.ToDoExplorerToDoItemFormat, _toDoItem.Type, _toDoItem.Description, module.ProjectName, diff --git a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerItemViewModelBase.cs b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerItemViewModelBase.cs index 286e2876e6..63132e2bd1 100644 --- a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerItemViewModelBase.cs +++ b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerItemViewModelBase.cs @@ -5,9 +5,9 @@ using System.Linq; using System.Windows; using NLog; +using Rubberduck.CodeAnalysis; using Rubberduck.Parsing; using Rubberduck.Parsing.Symbols; -using Rubberduck.Resources; using Rubberduck.UI; using Rubberduck.VBEditor; @@ -63,7 +63,7 @@ public virtual string PanelTitle } var nameWithDeclarationType = - $"{Declaration.IdentifierName} - ({RubberduckUI.ResourceManager.GetString("DeclarationType_" + Declaration.DeclarationType, CultureInfo.CurrentUICulture)})"; + $"{Declaration.IdentifierName} - ({CodeAnalysisUI.ResourceManager.GetString("DeclarationType_" + Declaration.DeclarationType, CultureInfo.CurrentUICulture)})"; if (string.IsNullOrEmpty(Declaration.AsTypeName)) { diff --git a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerSubMemberViewModel.cs b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerSubMemberViewModel.cs index bca88bbf3a..5ec9360321 100644 --- a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerSubMemberViewModel.cs +++ b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerSubMemberViewModel.cs @@ -11,14 +11,11 @@ public sealed class CodeExplorerSubMemberViewModel : CodeExplorerItemViewModel DeclarationType.UserDefinedTypeMember }; - private readonly string _signature = string.Empty; + private string _signature = string.Empty; public CodeExplorerSubMemberViewModel(ICodeExplorerNode parent, Declaration declaration) : base(parent, declaration) { - if (Declaration is ValuedDeclaration value && !string.IsNullOrEmpty(value.Expression)) - { - _signature = $" = {value.Expression}"; - } + UpdateSignature(); } public override string Name => Declaration?.IdentifierName ?? string.Empty; @@ -30,6 +27,7 @@ public override void Synchronize(ref List updated) var signature = _signature; base.Synchronize(ref updated); + UpdateSignature(); if (Declaration is null || _signature.Equals(signature)) { return; @@ -39,6 +37,18 @@ public override void Synchronize(ref List updated) OnNameChanged(); } + private void UpdateSignature() + { + if (Declaration is ValuedDeclaration value && !string.IsNullOrEmpty(value.Expression)) + { + _signature = $" = {value.Expression}"; + } + else + { + _signature = ""; + } + } + public override Comparer SortComparer => SortOrder.HasFlag(CodeExplorerSortOrder.Name) ? CodeExplorerItemComparer.Name diff --git a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs index 8270aa709f..39920aa685 100644 --- a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs +++ b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs @@ -3,6 +3,7 @@ using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Threading.Tasks; using NLog; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; @@ -19,6 +20,7 @@ using Rubberduck.Templates; using Rubberduck.UI.CodeExplorer.Commands.DragAndDrop; using Rubberduck.UI.Command.ComCommands; +using Rubberduck.UI.Controls; using Rubberduck.UI.UnitTesting.ComCommands; using Rubberduck.VBEditor.SafeComWrappers.Abstract; @@ -35,8 +37,13 @@ public enum CodeExplorerSortOrder DeclarationTypeThenCodeLine = DeclarationType | CodeLine } + public interface IPeekDefinitionPopupProvider + { + void PeekDefinition(Declaration target); + } + [SuppressMessage("ReSharper", "InconsistentNaming")] - public sealed class CodeExplorerViewModel : ViewModelBase + public sealed class CodeExplorerViewModel : ViewModelBase, IPeekDefinitionPopupProvider { // ReSharper disable NotAccessedField.Local - The settings providers aren't used, but several enhancement requests will need them. #pragma warning disable IDE0052 // Remove unread private members @@ -53,6 +60,7 @@ public sealed class CodeExplorerViewModel : ViewModelBase public CodeExplorerViewModel( RubberduckParserState state, RemoveCommand removeCommand, + PeekDefinitionNavigateCommand peekNavigateCommand, IConfigurationService generalSettingsProvider, IConfigurationService windowSettingsProvider, IUiDispatcher uiDispatcher, @@ -86,6 +94,8 @@ public CodeExplorerViewModel( RemoveCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteRemoveCommand, _externalRemoveCommand.CanExecute); } + PeekDefinitionCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecutePeekDefinitionCommand, CanExecutePeekDefinitionCommand); + ClosePeekDefinitionCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteClosePeekDefinitionCommand); OnPropertyChanged(nameof(Projects)); @@ -445,6 +455,61 @@ private void ExecuteRemoveCommand(object param) public CommandBase CollapseAllCommand { get; } public CommandBase ExpandAllCommand { get; } + public CommandBase PeekDefinitionCommand { get; } + public CommandBase ClosePeekDefinitionCommand { get; } + public PeekDefinitionFindAllReferencesCommand PeekFindReferencesCommand { get; set; } + public PeekDefinitionNavigateCommand PeekNavigateCommand { get; set; } + + private bool _showPeekDefinitionPopup; + public bool ShowPeekDefinitionPopup + { + get => _showPeekDefinitionPopup; + set + { + if (value != _showPeekDefinitionPopup) + { + _showPeekDefinitionPopup = value; + OnPropertyChanged(); + } + } + } + + private PeekDefinitionViewModel _peekDefinitionViewModel; + public PeekDefinitionViewModel PeekDefinitionViewModel + { + get => _peekDefinitionViewModel; + private set + { + if (_peekDefinitionViewModel != value) + { + _peekDefinitionViewModel = value; + OnPropertyChanged(); + } + } + } + + private void ExecutePeekDefinitionCommand(object param) + { + if (param is ICodeExplorerNode node) + { + PeekDefinitionViewModel = new PeekDefinitionViewModel(node, PeekFindReferencesCommand, PeekNavigateCommand, ClosePeekDefinitionCommand, _state); + } + else if (param is Declaration declaration) + { + PeekDefinitionViewModel = new PeekDefinitionViewModel(declaration, PeekFindReferencesCommand, PeekNavigateCommand, ClosePeekDefinitionCommand, _state); + } + else + { + PeekDefinitionViewModel = null; + } + + ShowPeekDefinitionPopup = PeekDefinitionViewModel != null; + } + + private void ExecuteClosePeekDefinitionCommand(object param) => ShowPeekDefinitionPopup = false; + + private bool CanExecutePeekDefinitionCommand(object param) => param is Declaration || SelectedItem is CodeExplorerMemberViewModel || SelectedItem is CodeExplorerComponentViewModel; + public ICodeExplorerNode FindVisibleNodeForDeclaration(Declaration declaration) { if (declaration == null) @@ -541,5 +606,8 @@ public void Dispose() _generalSettingsProvider.SettingsChanged -= GeneralSettingsChanged; } } + + // IPeekDefinitionPopupProvider.PeekDefinition + public void PeekDefinition(Declaration target) => ExecutePeekDefinitionCommand(target); } } diff --git a/Rubberduck.Core/Properties/Settings.Designer.cs b/Rubberduck.Core/Properties/Settings.Designer.cs index 6c0e8ff9c6..017f2c6c14 100644 --- a/Rubberduck.Core/Properties/Settings.Designer.cs +++ b/Rubberduck.Core/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace Rubberduck.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -227,6 +227,23 @@ public static Settings Default { } } + [global::System.Configuration.ApplicationScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + D + true + true + false + true + PeekDefinitionCommand + ")] + public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_PeekDefinitionCommand { + get { + return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_PeekDefinitionCommand"])); + } + } + [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("\r\n + + <?xml version="1.0" encoding="utf-16"?> + <HotkeySetting xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <Key1>D</Key1> + <IsEnabled>true</IsEnabled> + <HasShiftModifier>true</HasShiftModifier> + <HasAltModifier>false</HasAltModifier> + <HasCtrlModifier>true</HasCtrlModifier> + <CommandTypeName>PeekDefinitionCommand</CommandTypeName> + </HotkeySetting> + <?xml version="1.0" encoding="utf-16"?> <ToDoMarker xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Text="TODO" /> diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodExtraction.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodExtraction.cs deleted file mode 100644 index df0250158a..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodExtraction.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Rubberduck.Parsing.Grammar; -using Rubberduck.VBEditor; -using Rubberduck.VBEditor.SafeComWrappers.Abstract; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public class ExtractMethodExtraction : IExtractMethodExtraction - { - - public void Apply(ICodeModule codeModule, IExtractMethodModel model, Selection selection) - { - var newMethodCall = model.Method.NewMethodCall(); - var positionToInsertNewMethod = model.PositionForNewMethod; - var positionForMethodCall = model.PositionForMethodCall; - var selectionToRemove = model.RowsToRemove; - // The next 4 lines are dependent on the positions of the various parts, - // so have to be applied in the correct order. - var newMethod = ConstructLinesOfProc(codeModule, model); - codeModule.InsertLines(positionToInsertNewMethod.StartLine, newMethod); - RemoveSelection(codeModule, selectionToRemove); - codeModule.InsertLines(selection.StartLine, newMethodCall); - } - - public virtual void RemoveSelection(ICodeModule codeModule, IEnumerable selection) - { - foreach (var item in selection.OrderBy(x => -x.StartLine)) - { - var start = item.StartLine; - var end = item.EndLine; - var lineCount = end - start + 1; - codeModule.DeleteLines(start,lineCount); - } - } - - public virtual string ConstructLinesOfProc(ICodeModule codeModule, IExtractMethodModel model) - { - - var newLine = Environment.NewLine; - var method = model.Method; - var keyword = Tokens.Sub; - var asTypeClause = string.Empty; - var selection = model.RowsToRemove; - - var access = method.Accessibility.ToString(); - var extractedParams = method.Parameters.Select(p => ExtractedParameter.PassedBy.ByRef + " " + p.Name + " " + Tokens.As + " " + p.TypeName); - var parameters = "(" + string.Join(", ", extractedParams) + ")"; - //method signature - var result = access + ' ' + keyword + ' ' + method.MethodName + parameters + ' ' + asTypeClause + newLine; - // method body - string textToMove = ""; - foreach (var item in selection) - { - textToMove += codeModule.GetLines(item.StartLine, item.EndLine - item.StartLine + 1); - textToMove += Environment.NewLine; - } - // method end; - result += textToMove; - result += Tokens.End + " " + Tokens.Sub; - return result; - } - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodModel.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodModel.cs deleted file mode 100644 index 161a01af3e..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodModel.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Antlr4.Runtime; -using Rubberduck.Common; -using Rubberduck.Parsing; -using Rubberduck.Parsing.Symbols; -using Rubberduck.VBEditor; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public static class IEnumerableExt - { - /// - /// Yields an Enumeration of selector Type, - /// by checking for gaps between elements - /// using the supplied increment function to work out the next value - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable GroupByMissing(this IEnumerable inputs, Func getIncr, Func selector, Func comparisonFunc) - { - - var initialized = false; - T first = default; - T last = default; - - foreach (var input in inputs) - { - if (!initialized) - { - first = input; - last = input; - initialized = true; - continue; - } - if (comparisonFunc(last, input) < 0) - { - throw new ArgumentException(string.Format("Values are not monotonically increasing. {0} should be less than {1}", last, input)); - } - var inc = getIncr(last); - if (!input.Equals(inc)) - { - yield return selector(first, last); - first = input; - } - last = input; - } - if (initialized) - { - yield return selector(first, last); - } - } - } - - public class ExtractMethodModel : IExtractMethodModel - { - private readonly List _extractDeclarations = new List(); - private readonly IExtractMethodParameterClassification _paramClassify; - private readonly IExtractedMethod _extractedMethod; - - public ExtractMethodModel(IExtractedMethod extractedMethod, IExtractMethodParameterClassification paramClassify) - { - _extractedMethod = extractedMethod; - _paramClassify = paramClassify; - _sourceMember = null; - } - - public void extract(IEnumerable declarations, QualifiedSelection selection, string selectedCode) - { - var items = declarations.ToList(); - _selection = selection; - _selectedCode = selectedCode; - _rowsToRemove = new List(); - - var sourceMember = FindSelectedDeclaration( - items, - selection, - ExtractedMethod.ProcedureTypes, - d => ((ParserRuleContext)d.Context.Parent).GetSelection()); - - if (sourceMember == null) - { - throw new InvalidOperationException("Invalid selection."); - } - - var inScopeDeclarations = items.Where(item => item.ParentScope == sourceMember.Scope).ToList(); - var selectionStartLine = selection.Selection.StartLine; - var selectionEndLine = selection.Selection.EndLine; - var methodInsertLine = sourceMember.Context.Stop.Line + 1; - - _positionForNewMethod = new Selection(methodInsertLine, 1, methodInsertLine, 1); - - foreach (var item in inScopeDeclarations) - { - _paramClassify.classifyDeclarations(selection, item); - } - _declarationsToMove = _paramClassify.DeclarationsToMove.ToList(); - - _rowsToRemove = SplitSelection(selection.Selection, _declarationsToMove).ToList(); - - var methodCallPositionStartLine = selectionStartLine - _declarationsToMove.Count(d => d.Selection.StartLine < selectionStartLine); - _positionForMethodCall = new Selection(methodCallPositionStartLine, 1, methodCallPositionStartLine, 1); - _extractedMethod.ReturnValue = null; - _extractedMethod.Accessibility = Accessibility.Private; - _extractedMethod.SetReturnValue = false; - _extractedMethod.Parameters = _paramClassify.ExtractedParameters.ToList(); - - } - - private static Declaration FindSelectedDeclaration(IEnumerable declarations, QualifiedSelection selection, IEnumerable types, Func selector = null) - { - var userDeclarations = declarations.Where(item => item.IsUserDefined); - var items = userDeclarations.Where(item => types.Contains(item.DeclarationType) - && item.QualifiedName.QualifiedModuleName == selection.QualifiedName).ToList(); - - var declaration = items.SingleOrDefault(item => - selector?.Invoke(item).Contains(selection.Selection) ?? item.Selection.Contains(selection.Selection)); - - if (declaration != null) - { - return declaration; - } - - // if we haven't returned yet, then we must be on an identifier reference. - declaration = items.SingleOrDefault(item => item.IsUserDefined - && types.Contains(item.DeclarationType) - && item.References.Any(reference => - reference.QualifiedModuleName == selection.QualifiedName - && reference.Selection.Contains(selection.Selection))); - - return declaration; - } - - public IEnumerable SplitSelection(Selection selection, IEnumerable declarations) - { - var tupleList = new List>(); - var declarationRows = declarations - .Where(decl => - selection.StartLine <= decl.Selection.StartLine && - decl.Selection.StartLine <= selection.EndLine) - .Select(decl => decl.Selection.StartLine) - .OrderBy(x => x) - .ToList(); - - var gappedSelectionRows = Enumerable.Range(selection.StartLine, selection.EndLine - selection.StartLine + 1).Except(declarationRows).ToList(); - var returnList = gappedSelectionRows.GroupByMissing(x => (x + 1), (x, y) => new Selection(x, 1, y, 1), (x, y) => y - x); - return returnList; - } - - private readonly Declaration _sourceMember; - public Declaration SourceMember { get { return _sourceMember; } } - - private QualifiedSelection _selection; - public QualifiedSelection Selection { get { return _selection; } } - - private string _selectedCode; - public string SelectedCode { get { return _selectedCode; } } - - private readonly List _locals = new List(); - public IEnumerable Locals { get { return _locals; } } - - private readonly IEnumerable _input = new List(); - public IEnumerable Inputs { get { return _input; } } - private readonly IEnumerable _output = new List(); - public IEnumerable Outputs { get { return _output; } } - - private List _declarationsToMove = new List(); - public IEnumerable DeclarationsToMove { get { return _declarationsToMove; } } - - public IExtractedMethod Method { get { return _extractedMethod; } } - - private Selection _positionForMethodCall; - public Selection PositionForMethodCall { get { return _positionForMethodCall; } } - - public string NewMethodCall { get { return _extractedMethod.NewMethodCall(); } } - - private Selection _positionForNewMethod; - public Selection PositionForNewMethod { get { return _positionForNewMethod; } } - - private IList _rowsToRemove; - public IEnumerable RowsToRemove - { - // we need to split selectionToRemove around any declarations that - // are within the selection. - get { return _declarationsToMove.Select(decl => decl.Selection).Union(_rowsToRemove) - .Select( x => new Selection(x.StartLine,1,x.EndLine,1)) ; } - } - - public IEnumerable DeclarationsToExtract - { - get { return _extractDeclarations; } - } - } -} \ No newline at end of file diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodParameterClassification.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodParameterClassification.cs deleted file mode 100644 index 2852a10b06..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodParameterClassification.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Rubberduck.Parsing.Symbols; -using Rubberduck.VBEditor; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public class ExtractMethodParameterClassification : IExtractMethodParameterClassification - { - // https://github.com/rubberduck-vba/Rubberduck/wiki/Extract-Method-Refactoring-%3A-Workings---Determining-what-params-to-move - private readonly IEnumerable _emRules; - private List _byref; - private List _byval; - private List _declarationsToMove; - private List _extractDeclarations; - - public ExtractMethodParameterClassification(IEnumerable emRules) - { - _emRules = emRules; - _byref = new List(); - _byval = new List(); - _declarationsToMove = new List(); - _extractDeclarations = new List(); - } - - public void classifyDeclarations(QualifiedSelection selection, Declaration item) - { - - byte flags = new Byte(); - foreach (var oRef in item.References) - { - foreach (var rule in _emRules) - { - var byteFlag = rule.setValidFlag(oRef, selection.Selection); - flags = (byte)(flags | (byte)byteFlag); - - } - } - - if (flags < 4) { /*ignore the variable*/ } - else if (flags < 12) - _byref.Add(item); - else if (flags == 12) - _declarationsToMove.Add(item); - else if (flags > 12) - _byval.Add(item); - - if (flags >= 18) - { - _extractDeclarations.Add(item); - } - } - - public IEnumerable ExtractedParameters - { - get { - return _byref.Select(dec => new ExtractedParameter(dec.AsTypeName, ExtractedParameter.PassedBy.ByRef, dec.IdentifierName)). - Union(_byval.Select(dec => new ExtractedParameter(dec.AsTypeName, ExtractedParameter.PassedBy.ByVal, dec.IdentifierName))); - } - } - - public IEnumerable DeclarationsToMove { get { return _declarationsToMove; } } - public IEnumerable ExtractedDeclarations { get { return _extractDeclarations; } } - - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodPresenter.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodPresenter.cs deleted file mode 100644 index 9d6ffe4792..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodPresenter.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Linq; -using System.Windows.Forms; -using Rubberduck.SmartIndenter; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public interface IExtractMethodPresenter - { - bool Show(IExtractMethodModel model, IExtractMethodProc createProc); - } - - public class ExtractMethodPresenter : IExtractMethodPresenter - { - private readonly IExtractMethodDialog _view; - private readonly IIndenter _indenter; - - public ExtractMethodPresenter(IExtractMethodDialog view, IIndenter indenter) - { - _view = view; - _indenter = indenter; - } - - public bool Show(IExtractMethodModel methodModel, IExtractMethodProc extractMethodProc) - { - PrepareView(methodModel,extractMethodProc); - - if (_view.ShowDialog() != DialogResult.OK) - { - return false; - } - - return true; - } - - private void PrepareView(IExtractMethodModel extractedMethodModel, IExtractMethodProc extractMethodProc) - { - _view.OldMethodName = extractedMethodModel.SourceMember.IdentifierName; - _view.MethodName = extractedMethodModel.SourceMember.IdentifierName + "_1"; - _view.Inputs = extractedMethodModel.Inputs; - _view.Outputs = extractedMethodModel.Outputs; - _view.Locals = - extractedMethodModel.Locals.Select( - variable => - new ExtractedParameter(variable.AsTypeName, ExtractedParameter.PassedBy.ByVal, variable.IdentifierName)) - .ToList(); - - var returnValues = new[] {new ExtractedParameter(string.Empty, ExtractedParameter.PassedBy.ByVal)} - .Union(_view.Outputs) - .Union(_view.Inputs) - .ToList(); - - _view.ReturnValues = returnValues; - - _view.RefreshPreview += (object sender, EventArgs e) => { GeneratePreview(extractedMethodModel, extractMethodProc); }; - - _view.OnRefreshPreview(); - } - - private void GeneratePreview(IExtractMethodModel extractMethodModel,IExtractMethodProc extractMethodProc ) - { - extractMethodModel.Method.MethodName = _view.MethodName; - extractMethodModel.Method.Accessibility = _view.Accessibility; - extractMethodModel.Method.Parameters = _view.Parameters; - /* - * extractMethodModel.Method.ReturnValue = _view.ReturnValue; - * extractMethodModel.Method.SetReturnValue = _view.SetReturnValue; - */ - var extractedMethod = extractMethodProc.createProc(extractMethodModel); - var code = extractedMethod.Split(new[]{Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries); - code = _indenter.Indent(code).ToArray(); - _view.Preview = string.Join(Environment.NewLine, code); - } - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodRefactoring.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodRefactoring.cs deleted file mode 100644 index 0485bbc547..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodRefactoring.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using Rubberduck.Parsing.Symbols; -using Rubberduck.VBEditor; -using Rubberduck.VBEditor.SafeComWrappers.Abstract; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - /// - /// A refactoring that extracts a method (procedure or function) - /// out of a selection in the active code pane and - /// replaces the selected code with a call to the extracted method. - /// - public class ExtractMethodRefactoring : IRefactoring - { - private readonly ICodeModule _codeModule; - private Func _createMethodModel; - private IExtractMethodExtraction _extraction; - private Action _onParseRequest; - - public ExtractMethodRefactoring( - ICodeModule codeModule, - Action onParseRequest, - Func createMethodModel, - IExtractMethodExtraction extraction) - { - _codeModule = codeModule; - _createMethodModel = createMethodModel; - _extraction = extraction; - _onParseRequest = onParseRequest; - } - - public void Refactor() - { - // TODO : move all this presenter code out - /* - var presenter = _factory.Create(); - if (presenter == null) - { - OnInvalidSelection(); - return; - } - - */ - var qualifiedSelection = _codeModule.GetQualifiedSelection(); - if (!qualifiedSelection.HasValue) - { - return; - } - - var selection = qualifiedSelection.Value.Selection; - var selectedCode = _codeModule.GetLines(selection); - var model = _createMethodModel(qualifiedSelection, selectedCode); - if (model == null) - { - return; - } - - /* - var success = presenter.Show(model,_createProc); - if (!success) - { - return; - } - */ - - _extraction.Apply(_codeModule, model, selection); - - _onParseRequest(this); - } - - public void Refactor(QualifiedSelection target) - { - var pane = _codeModule.CodePane; - { - pane.Selection = target.Selection; - Refactor(); - } - } - - public void Refactor(Declaration target) - { - OnInvalidSelection(); - } - - private void ExtractMethod() - { - - #region to be put back when allow subs and functions - /* Remove this entirely for now. - // assumes these are declared *before* the selection... - var offset = 0; - foreach (var declaration in model.DeclarationsToMove.OrderBy(e => e.Selection.StartLine)) - { - var target = new Selection( - declaration.Selection.StartLine - offset, - declaration.Selection.StartColumn, - declaration.Selection.EndLine - offset, - declaration.Selection.EndColumn); - - _codeModule.DeleteLines(target); - offset += declaration.Selection.LineCount; - } - */ - #endregion - - } - - - /// - /// An event that is raised when refactoring is not possible due to an invalid selection. - /// - public event EventHandler InvalidSelection; - private void OnInvalidSelection() - { - var handler = InvalidSelection; - if (handler != null) - { - handler(this, EventArgs.Empty); - } - } - - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodSelectionValidation.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodSelectionValidation.cs deleted file mode 100644 index 4e7e7533f5..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractMethodSelectionValidation.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Antlr4.Runtime; -using Rubberduck.Common; -using Rubberduck.Parsing.Grammar; -using Rubberduck.Parsing.Symbols; -using Rubberduck.VBEditor; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public class ExtractMethodSelectionValidation : IExtractMethodSelectionValidation - { - private IEnumerable _declarations; - - - - public ExtractMethodSelectionValidation(IEnumerable declarations) - { - _declarations = declarations; - } - public bool withinSingleProcedure(QualifiedSelection qualifiedSelection) - { - - var selection = qualifiedSelection.Selection; - IEnumerable procedures = _declarations.Where(d => d.IsUserDefined && (ExtractedMethod.ProcedureTypes.Contains(d.DeclarationType))); - Func ProcOfLine = (sl) => procedures.FirstOrDefault(d => d.Context.Start.Line < sl && d.Context.Stop.Line > sl); - - var startLine = selection.StartLine; - var endLine = selection.EndLine; - - // End of line is easy - var procEnd = ProcOfLine(endLine); - if (procEnd == null) - { - return false; - } - - var procEndContext = procEnd.Context as ParserRuleContext; - var procEndLine = procEndContext.Stop.Line; - - /* Handle: function signature continuations - * public function(byval a as string _ - * byval b as string) as integer - */ - var procStart = ProcOfLine(startLine); - if (procStart == null) - { - return false; - } - - dynamic procStartContext; - procStartContext = procStart.Context as VBAParser.FunctionStmtContext; - if (procStartContext == null) - { - procStartContext = procStart.Context as VBAParser.SubStmtContext; - } - // TOOD: Doesn't support properties. - if (procStartContext == null) - { - return false; - } - var procEndOfSignature = procStartContext.endOfStatement() as VBAParser.EndOfStatementContext; - var procSignatureLastLine = procEndOfSignature.Start.Line; - - return (procEnd as Declaration).QualifiedSelection.Equals((procStart as Declaration).QualifiedSelection) - && (procSignatureLastLine < startLine); - } - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractedMethod.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractedMethod.cs deleted file mode 100644 index bdcfc8d0a4..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractedMethod.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Rubberduck.Parsing.Symbols; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public class ExtractedMethod : IExtractedMethod - { - private const string NEW_METHOD = "NewMethod"; - - public string MethodName { get; set; } - public Accessibility Accessibility { get; set; } - public bool SetReturnValue { get; set; } - public ExtractedParameter ReturnValue { get; set; } - public IEnumerable Parameters { get; set; } - - public virtual string NewMethodCall() - { - if (String.IsNullOrWhiteSpace(MethodName)) - { - MethodName = NEW_METHOD; - } - string result = "" + MethodName; - string argList; - if (Parameters.Any()) - { - argList = String.Join(", ", Parameters.Select(p => p.Name)); - result += " " + argList; - } - return result; - } - public string getNewMethodName(IEnumerable declarations) - { - var newMethodName = NEW_METHOD; - - var newMethodInc = 0; - // iterate until we have a non-clashing method name. - while (isConflictingName(declarations, newMethodName)) - { - newMethodInc++; - newMethodName = NEW_METHOD + newMethodInc; - } - return newMethodName; - } - - public bool isConflictingName(IEnumerable declarations, string methodName) - { - var existingName = declarations.FirstOrDefault(d => - Enumerable.Contains(ProcedureTypes, d.DeclarationType) - && d.IdentifierName.Equals(methodName)); - return (existingName != null); - } - - public static readonly DeclarationType[] ProcedureTypes = - { - DeclarationType.Procedure, - DeclarationType.Function, - DeclarationType.PropertyGet, - DeclarationType.PropertyLet, - DeclarationType.PropertySet - }; - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractedParameter.cs b/Rubberduck.Core/Refactorings/ExtractMethod/ExtractedParameter.cs deleted file mode 100644 index 3c6d5ad147..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/ExtractedParameter.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Rubberduck.Parsing.Grammar; -using Rubberduck.Resources; -using Tokens = Rubberduck.Resources.Tokens; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public class ExtractedParameter - { - public enum PassedBy - { - ByRef, - ByVal - } - - public static readonly string None = RubberduckUI.ExtractMethod_OutputNone; - - private readonly string _name; - private readonly string _typeName; - private readonly PassedBy _passedBy; - - public ExtractedParameter(string typeName, PassedBy passedBy, string name = null) - { - _name = name ?? None; - _typeName = typeName; - _passedBy = passedBy; - } - - public string Name - { - get { return _name; } - } - - public string TypeName - { - get { return _typeName; } - } - - public PassedBy Passed - { - get { return _passedBy; } - } - - public override string ToString() - { - return _passedBy.ToString() + ' ' + Name + ' ' + Tokens.As + ' ' + TypeName; - } - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodDialog.cs b/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodDialog.cs deleted file mode 100644 index c5e56194d2..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodDialog.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using Rubberduck.Parsing.Symbols; -using Rubberduck.UI; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public interface IExtractMethodDialog : IDialogView - { - IEnumerable ReturnValues { get; set; } - - event EventHandler RefreshPreview; - void OnRefreshPreview(); - string Preview { get; set; } - - string MethodName { get; set; } - string OldMethodName { get; set; } - Accessibility Accessibility { get; set; } - IEnumerable Parameters { get; set; } - IEnumerable Inputs { get; set; } - IEnumerable Outputs { get; set; } - IEnumerable Locals { get; set; } - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodExtraction.cs b/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodExtraction.cs deleted file mode 100644 index 15d0a53fb0..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodExtraction.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Rubberduck.VBEditor; -using Rubberduck.VBEditor.SafeComWrappers.Abstract; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public interface IExtractMethodExtraction - { - void Apply(ICodeModule codeModule, IExtractMethodModel model, Selection selection); - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodParameterClassification.cs b/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodParameterClassification.cs deleted file mode 100644 index ae93a8b711..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodParameterClassification.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using Rubberduck.Parsing.Symbols; -using Rubberduck.VBEditor; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public interface IExtractMethodParameterClassification - { - IEnumerable ExtractedParameters { get; } - void classifyDeclarations(QualifiedSelection selection, Declaration item); - IEnumerable DeclarationsToMove { get; } - IEnumerable ExtractedDeclarations { get; } - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodProc.cs b/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodProc.cs deleted file mode 100644 index 607107f40e..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodProc.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Rubberduck.Refactorings.ExtractMethod -{ - public interface IExtractMethodProc - { - string createProc(IExtractMethodModel model); - } -} diff --git a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodRule.cs b/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodRule.cs deleted file mode 100644 index 1727c31c78..0000000000 --- a/Rubberduck.Core/Refactorings/ExtractMethod/IExtractMethodRule.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using Rubberduck.Parsing.Symbols; -using Rubberduck.VBEditor; - -namespace Rubberduck.Refactorings.ExtractMethod -{ - public interface IExtractMethodRule - { - Byte setValidFlag(IdentifierReference reference, Selection selection); - } - - public enum ExtractMethodRuleFlags - { - UsedBefore = 1, - UsedAfter = 2, - IsAssigned = 4, - InSelection = 8, - IsExternallyReferenced = 16 - - } - - public class ExtractMethodRuleUsedBefore : IExtractMethodRule - { - public Byte setValidFlag(IdentifierReference reference, Selection selection) - { - if (reference.Selection.StartLine < selection.StartLine) - return ((byte)ExtractMethodRuleFlags.UsedBefore); - return 0; - } - } - - public class ExtractMethodRuleExternalReference : IExtractMethodRule - { - public Byte setValidFlag(IdentifierReference reference, Selection selection) - { - var decStartLine = reference.Declaration.Selection.StartLine; - if (reference.Selection.StartLine > selection.EndLine && - selection.StartLine <= decStartLine && decStartLine <= selection.EndLine) - { - return ((byte)ExtractMethodRuleFlags.IsExternallyReferenced); - } - return 0; - } - } - - public class ExtractMethodRuleUsedAfter : IExtractMethodRule - { - public Byte setValidFlag(IdentifierReference reference, Selection selection) - { - if (reference.Selection.StartLine > selection.EndLine) - return ((byte)ExtractMethodRuleFlags.UsedAfter); - return 0; - } - } - - public class ExtractMethodRuleIsAssignedInSelection : IExtractMethodRule - { - public Byte setValidFlag(IdentifierReference reference, Selection selection) - { - if (selection.StartLine <= reference.Selection.StartLine && reference.Selection.StartLine <= selection.EndLine) - { - if (reference.IsAssignment) - return ((byte)ExtractMethodRuleFlags.IsAssigned); - } - return 0; - } - } - - public class ExtractMethodRuleInSelection : IExtractMethodRule - { - public Byte setValidFlag(IdentifierReference reference, Selection selection) - { - if (selection.StartLine <= reference.Selection.StartLine && - reference.Selection.StartLine <= selection.EndLine && - ((reference.Declaration == null) ? false : reference.Declaration.Selection.StartLine != reference.Selection.StartLine)) - { - return ((byte)ExtractMethodRuleFlags.InSelection); - - } - return 0; - } - } -} diff --git a/Rubberduck.Core/Rubberduck.Core.csproj b/Rubberduck.Core/Rubberduck.Core.csproj index 2960a7b9fb..9c4dc78bb9 100644 --- a/Rubberduck.Core/Rubberduck.Core.csproj +++ b/Rubberduck.Core/Rubberduck.Core.csproj @@ -5,7 +5,7 @@ Rubberduck.Core Rubberduck.Core Rubberduck.Core - Copyright © 2014-2021 + Copyright © 2014-2023 {A1587EAC-7B54-407E-853F-4C7493D0323E} bin\Debug\Rubberduck.Core.xml @@ -77,12 +77,14 @@ 1.8.4 + 4.5.10 4.5.10 + 4.5.0 @@ -91,17 +93,4 @@ 2.0.20525 - - - True - True - Resources.resx - - - - - ResXFileCodeGenerator - Resources.Designer.cs - - diff --git a/Rubberduck.Core/Runtime/BeepInterceptor.cs b/Rubberduck.Core/Runtime/BeepInterceptor.cs index 5fe298e386..0d3ff67449 100644 --- a/Rubberduck.Core/Runtime/BeepInterceptor.cs +++ b/Rubberduck.Core/Runtime/BeepInterceptor.cs @@ -15,6 +15,7 @@ public interface IBeepInterceptor : IDisposable { void SuppressBeep(double millisecondsToSuppress); event EventHandler Beep; + void NativeCall(); } public sealed class BeepInterceptor : IBeepInterceptor @@ -24,6 +25,7 @@ public sealed class BeepInterceptor : IBeepInterceptor private readonly IVbeNativeApi _vbeApi; private readonly LocalHook _hook; private readonly Timer _timer; + private VbaBeepDelegate nativeCall; public BeepInterceptor(IVbeNativeApi vbeApi) { @@ -40,12 +42,19 @@ public void SuppressBeep(double millisecondsToSuppress) _timer.Enabled = true; } + public void NativeCall() + { + nativeCall(); + } + private LocalHook HookVbaBeep() { var processAddress = LocalHook.GetProcAddress(_vbeApi.DllName, "rtcBeep"); var callbackDelegate = new VbaBeepDelegate(VbaBeepCallback); var hook = LocalHook.Create(processAddress, callbackDelegate, null); hook.ThreadACL.SetInclusiveACL(new[] { 0 }); + var nativeFunctionAddress = hook.HookBypassAddress; + nativeCall = Marshal.GetDelegateForFunctionPointer(nativeFunctionAddress); return hook; } @@ -65,7 +74,7 @@ private void VbaBeepCallback() if (!e.Handled) { - _vbeApi.Beep(); + nativeCall(); } } diff --git a/Rubberduck.Core/Settings/MinimumLogLevel.cs b/Rubberduck.Core/Settings/MinimumLogLevel.cs index aec40dc896..fbea44d7b1 100644 --- a/Rubberduck.Core/Settings/MinimumLogLevel.cs +++ b/Rubberduck.Core/Settings/MinimumLogLevel.cs @@ -1,5 +1,5 @@ using System.Globalization; -using Rubberduck.Resources; +using Rubberduck.UI.Settings; namespace Rubberduck.Settings { @@ -8,7 +8,7 @@ public sealed class MinimumLogLevel public MinimumLogLevel(int ordinal, string logLevelName) { Ordinal = ordinal; - Name = RubberduckUI.ResourceManager.GetString("GeneralSettings_" + logLevelName + "LogLevel", CultureInfo.CurrentUICulture); + Name = GeneralSettingsUI.ResourceManager.GetString(logLevelName + "LogLevel", CultureInfo.CurrentUICulture); } public int Ordinal { get; } diff --git a/Rubberduck.Core/Templates/TemplateFileHandler.cs b/Rubberduck.Core/Templates/TemplateFileHandler.cs index 81b1ea6f99..d4fc29392d 100644 --- a/Rubberduck.Core/Templates/TemplateFileHandler.cs +++ b/Rubberduck.Core/Templates/TemplateFileHandler.cs @@ -14,25 +14,21 @@ public interface ITemplateFileHandlerProvider public class TemplateFileHandlerProvider : ITemplateFileHandlerProvider { - private readonly string _rootPath; + private readonly Lazy _rootPath; private readonly IFileSystem _filesystem; public TemplateFileHandlerProvider( IPersistencePathProvider pathProvider, IFileSystem fileSystem) { - _rootPath = pathProvider.DataFolderPath("Templates"); + _rootPath = new Lazy(() => pathProvider.DataFolderPath("Templates")); _filesystem = fileSystem; } public ITemplateFileHandler CreateTemplateFileHandler(string templateName) { - if (!_filesystem.Directory.Exists(_rootPath)) - { - _filesystem.Directory.CreateDirectory(_rootPath); - } - - var fullPath = _filesystem.Path.Combine(_rootPath, templateName); + EnsureRootPathExists(); + var fullPath = _filesystem.Path.Combine(_rootPath.Value, templateName); if (!_filesystem.Directory.Exists(_filesystem.Path.GetDirectoryName(fullPath))) { throw new InvalidOperationException("Cannot provide a path for where the parent directory do not exist"); @@ -42,9 +38,18 @@ public ITemplateFileHandler CreateTemplateFileHandler(string templateName) public IEnumerable GetTemplateNames() { - var info = _filesystem.DirectoryInfo.FromDirectoryName(_rootPath); + EnsureRootPathExists(); + var info = _filesystem.DirectoryInfo.FromDirectoryName(_rootPath.Value); return info.GetFiles().Select(file => file.Name).ToList(); } + + private void EnsureRootPathExists() + { + if (!_filesystem.Directory.Exists(_rootPath.Value)) + { + _filesystem.Directory.CreateDirectory(_rootPath.Value); + } + } } public interface ITemplateFileHandler diff --git a/Rubberduck.Core/UI/About/AboutControl.xaml b/Rubberduck.Core/UI/About/AboutControl.xaml index fe61c06657..71d2f43e7b 100644 --- a/Rubberduck.Core/UI/About/AboutControl.xaml +++ b/Rubberduck.Core/UI/About/AboutControl.xaml @@ -4,7 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:about="clr-namespace:Rubberduck.UI.About" - mc:Ignorable="d" + mc:Ignorable="d" d:DataContext="{d:DesignInstance {x:Type about:AboutControlViewModel}, IsDesignTimeCreatable=False}" KeyDown="OnKeyDownHandler"> @@ -13,13 +13,13 @@ - + - - - - - + + - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + rubberduckvba.com + - - - rubberduckvba.com - - - - - - - - - + - - - - JetBrains ReSharper Community Team -Code Review Stack Exchange + + + + + + + + + Code Review (Stack Exchange) Stack Overflow Digital Ocean Hacktoberfest - +JetBrains ReSharper Community Team +Microsoft MVP Award Program + - - Abraham Hosch + + Abraham Hosch Andrew Jackson Andrew Zschetzsche Andrew Mansell @@ -215,6 +186,7 @@ Max Dörner Michal Krzych @mjolka Nelson Vides +@PhilCattivocaratere Philip Wales Radosław Kapka Rob Bovey (Smart Indenter) @@ -223,20 +195,23 @@ Ross Knudsen Simon Forsberg Stephen Bullen (Smart Indenter) @tommy9 -Wayne Phillips (vbWatchdog) - +Wayne Phillips (vbWatchdog, twinBASIC) + - + + - - + + - + + + + diff --git a/Rubberduck.Core/UI/About/AboutControlViewModel.cs b/Rubberduck.Core/UI/About/AboutControlViewModel.cs index 048a0f6d30..93272b9980 100644 --- a/Rubberduck.Core/UI/About/AboutControlViewModel.cs +++ b/Rubberduck.Core/UI/About/AboutControlViewModel.cs @@ -12,10 +12,10 @@ namespace Rubberduck.UI.About { public class AboutControlViewModel { - private readonly IVersionCheck _version; + private readonly IVersionCheckService _version; private readonly IWebNavigator _web; - public AboutControlViewModel(IVersionCheck version, IWebNavigator web) + public AboutControlViewModel(IVersionCheckService version, IWebNavigator web) { _version = version; _web = web; @@ -24,7 +24,7 @@ public AboutControlViewModel(IVersionCheck version, IWebNavigator web) ViewLogCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteViewLog); } - public string Version => string.Format(Resources.RubberduckUI.Rubberduck_AboutBuild, _version.CurrentVersion); + public string Version => string.Format(Resources.RubberduckUI.Rubberduck_AboutBuild, _version.VersionString); public string OperatingSystem => string.Format(AboutUI.AboutWindow_OperatingSystem, Environment.OSVersion.VersionString, Environment.Is64BitOperatingSystem ? "x64" : "x86"); diff --git a/Rubberduck.Core/UI/About/AboutDialog.cs b/Rubberduck.Core/UI/About/AboutDialog.cs index a0cc6e0f3a..fc0de5fbfd 100644 --- a/Rubberduck.Core/UI/About/AboutDialog.cs +++ b/Rubberduck.Core/UI/About/AboutDialog.cs @@ -5,7 +5,7 @@ namespace Rubberduck.UI.About { public partial class AboutDialog : Form { - public AboutDialog(IVersionCheck versionCheck, IWebNavigator web) : this() + public AboutDialog(IVersionCheckService versionCheck, IWebNavigator web) : this() { ViewModel = new AboutControlViewModel(versionCheck, web); } diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.Designer.cs b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.Designer.cs new file mode 100644 index 0000000000..fea1d9a5c1 --- /dev/null +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.Designer.cs @@ -0,0 +1,342 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Rubberduck.UI.AddRemoveReferences { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class AddRemoveReferencesUI { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal AddRemoveReferencesUI() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Rubberduck.UI.AddRemoveReferences.AddRemoveReferencesUI", typeof(AddRemoveReferencesUI).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Could not add reference. + /// + public static string AddFailedCaption { + get { + return ResourceManager.GetString("AddFailedCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add to project. + /// + public static string AddToolTip { + get { + return ResourceManager.GetString("AddToolTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Browse.... + /// + public static string BrowseButtonText { + get { + return ResourceManager.GetString("BrowseButtonText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Browse for reference. + /// + public static string BrowseCaption { + get { + return ResourceManager.GetString("BrowseCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Microsoft Access Databases({0})|{0}. + /// + public static string BrowseFilterAccess { + get { + return ResourceManager.GetString("BrowseFilterAccess", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to ActiveX Controls (*.ocx)|*.ocx. + /// + public static string BrowseFilterActiveX { + get { + return ResourceManager.GetString("BrowseFilterActiveX", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All files (*.*)|*.*. + /// + public static string BrowseFilterAllFiles { + get { + return ResourceManager.GetString("BrowseFilterAllFiles", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Microsoft Excel Files ({0})|{0}. + /// + public static string BrowseFilterExcel { + get { + return ResourceManager.GetString("BrowseFilterExcel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Executable Files (*.exe;*.dll)|*.exe;*.dll. + /// + public static string BrowseFilterExecutable { + get { + return ResourceManager.GetString("BrowseFilterExecutable", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Outlook VBA Files ({0})|{0}. + /// + public static string BrowseFilterOutlook { + get { + return ResourceManager.GetString("BrowseFilterOutlook", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PowerPoint Addin Files({0})|{0}. + /// + public static string BrowseFilterPowerPoint { + get { + return ResourceManager.GetString("BrowseFilterPowerPoint", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Publisher Files ({0}|{0}. + /// + public static string BrowseFilterPublisher { + get { + return ResourceManager.GetString("BrowseFilterPublisher", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type Libraries (*.olb;*.tlb;*.dll)|*.olb;*.tlb;*.dll. + /// + public static string BrowseFilterTypes { + get { + return ResourceManager.GetString("BrowseFilterTypes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to All Visio Files ({0})|{0}. + /// + public static string BrowseFilterVisio { + get { + return ResourceManager.GetString("BrowseFilterVisio", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Word Documents ({0})|{0}. + /// + public static string BrowseFilterWord { + get { + return ResourceManager.GetString("BrowseFilterWord", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add/Remove References.... + /// + public static string Caption { + get { + return ResourceManager.GetString("Caption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Add/Remove References - {0}. + /// + public static string CaptionTemplate { + get { + return ResourceManager.GetString("CaptionTemplate", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Standard. + /// + public static string DefaultLocale { + get { + return ResourceManager.GetString("DefaultLocale", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Locale:. + /// + public static string Locale { + get { + return ResourceManager.GetString("Locale", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Move down. + /// + public static string MoveDownToolTip { + get { + return ResourceManager.GetString("MoveDownToolTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Move up. + /// + public static string MoveUpToolTip { + get { + return ResourceManager.GetString("MoveUpToolTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pinned. + /// + public static string Pinned { + get { + return ResourceManager.GetString("Pinned", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pin reference. + /// + public static string PinToolTip { + get { + return ResourceManager.GetString("PinToolTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Projects. + /// + public static string Projects { + get { + return ResourceManager.GetString("Projects", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Recent. + /// + public static string Recent { + get { + return ResourceManager.GetString("Recent", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to References. + /// + public static string References { + get { + return ResourceManager.GetString("References", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Remove from project. + /// + public static string RemoveToolTip { + get { + return ResourceManager.GetString("RemoveToolTip", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Search for reference.... + /// + public static string SearchPlaceholder { + get { + return ResourceManager.GetString("SearchPlaceholder", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Select type libraries and VB projects to add or remove.. + /// + public static string SubCaption { + get { + return ResourceManager.GetString("SubCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type Libraries. + /// + public static string TypeLibs { + get { + return ResourceManager.GetString("TypeLibs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Version:. + /// + public static string Version { + get { + return ResourceManager.GetString("Version", resourceCulture); + } + } + } +} diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.cs.resx b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.cs.resx new file mode 100644 index 0000000000..543b345dc9 --- /dev/null +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.cs.resx @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Reference + + + Nepovedlo se přidat reference + + + Přidat do projektu + + + Procházet... + + + Procházet pro reference + + + Microsoft Access Databáze ({0})|{0} + + + ActiveX Controls (*.ocx)|*.ocx + + + Všechny soubory (*.*)|*.* + + + Microsoft Excel Soubory ({0})|{0} + + + Spustitelné Soubory (*.exe;*.dll)|*.exe;*.dll + + + Outlook VBA Soubory ({0})|{0} + + + PowerPoint Addin Soubory ({0})|{0} + + + Publisher Soubory ({0})|{0} + + + Knihovny (*.olb;*.tlb;*.dll)|*.olb;*.tlb;*.dll + + + Všechny Visio Soubory ({0})|{0} + + + Word Dokumenty ({0})|{0} + + + Přidat/Odebrat Reference... + + + Přidat/Odebrat Reference = {0} + + + Standardní + + + Lokalizace: + + + Posunout dolů + + + Posunout nahorů + + + Připíchnuté + + + Přišpendlit referenci + + + Projekty + + + Nedávné + + + Odebrat z projektu + + + Hledat referenci... + + + Vybrat knihovny a VB projekty pro přidání nebo odebrání. + + + Knihovny + + + Verze: + + \ No newline at end of file diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.de.resx b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.de.resx new file mode 100644 index 0000000000..5a89580922 --- /dev/null +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.de.resx @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Referenzen + + + Hinzufügen der Referenz fehlgeschlagen + + + Zu Projekt hinzufügen + + + Durchsuchen... + + + Verzeichnis der Referenz öffnen + + + Microsoft-Access-Datenbanken({0})|{0} + + + ActiveX-Kontrollelemente (*.ocx)|*.ocx + + + Alle Dateien(*.*)|*.* + + + Microsoft-Excel-Dateien ({0})|{0} + + + Ausführbare Dateien (*.exe;*.dll)|*.exe;*.dll + + + Outlook-VBA-Dateien ({0})|{0} + + + PowerPoint-Addin-Dateien({0})|{0} + + + Publisher-Dateien ({0}|{0} + + + Typbibliotheken (*.olb;*.tlb;*.dll)|*.olb;*.tlb;*.dll + + + Alle Visio-Dateien ({0})|{0} + + + Word-Dokumente ({0})|{0} + + + Referenzen hinzufügen/entfernen... + + + Referenzen hinzufügen/entfernen - {0} + + + Standard + + + Sprache: + + + Aufwärts bewegen + + + Abwärts bewegen + + + Angeheftet + + + Referenz anheften + + + Projekte + + + Zuletzt verwendet + + + Vom Projekt enfernen + + + Nach Referenz suchen... + + + Wähle Typbibliotheken und VB-Projekte zum Hinzufügen oder Entfernen. + + + Typbibliotheken + + + Version: + + \ No newline at end of file diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.es.resx b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.es.resx new file mode 100644 index 0000000000..9b2ec5ab14 --- /dev/null +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.es.resx @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Referencias + + + No se pudo agregar la referencia + + + Agregar al proyecto + + + Navegando... + + + Buscar referencias + + + Bases de datos de Microsoft Access ({0})|{0} + + + Controles ActiveX (* .ocx)|*.ocx + + + Todos los archivos (*.*)|*.* + + + Archivos de Microsoft Excel ({0})|{0} + + + Archivos ejecutables (*.exe;*.dll)|*.exe;*.dll + + + Archivos de Outlook VBA ({0})|{0} + + + Archivos de Complementos de PowerPoint ({0})|{0} + + + Archivos de Publisher ({0}|{0} + + + Bibliotecas de tipos (*.olb;*.tlb;*.dll)|*.olb;*.tlb;*.dll + + + Todos los archivos de Visio ({0})|{0} + + + Documentos de Word ({0})|{0} + + + Agregar/Eliminar referencias... + + + Agregar/Eliminar referencias - {0} + + + Estándar + + + Local: + + + Mover hacia abajo + + + Mover hacia arriba + + + Fijado + + + Fijar Referencia + + + Proyectos + + + Reciente + + + Eliminar del proyecto + + + Buscar referencia ... + + + Seleccione bibliotecas de tipos y proyectos VB para agregar o eliminar. + + + Bibliotecas de tipos + + + Versión: + + \ No newline at end of file diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.fr.resx b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.fr.resx new file mode 100644 index 0000000000..2a8067a2c4 --- /dev/null +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.fr.resx @@ -0,0 +1,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Références + + + La référence n'a pu être ajoutée + + + Ajouter au projet + + + Parcourir... + + + Parcourir... + + + Base de données Microsoft Access ({0})|{0} + + + Contrôles ActiveX (*.ocx)|*.ocx + + + Tous (*.*)|*.* + + + Fichiers Microsoft Excel ({0})|{0} + + + Exécutables (*.exe,*.dll)|*.exe;*.dll + + + Fichiers VBA Outlook ({0})|{0} + + + Fichiers complément PowerPoint ({0})|{0} + + + Fichiers Publisher ({0})|{0} + + + Bibliothêques (*.olb;*.tlb;*.dll)|*.olb;*.tlb;*.dll + + + Tous les fichiers Visio ({0})|{0} + + + Documents Word ({0})|{0} + + + Ajouter/Supprimer Références... + + + Ajouter/Supprimer Références - {0} + + + Standard + + + Langue: + + + Déplacer vers le haut + + + Déplacer vers le bas + + + Épingles + + + Épingler la référence + + + Projets + + + Récents + + + Supprimer du projet + + + Rechercher une référence... + + + Sélectionner les librairies et projets à ajouter ou supprimer aux références du projet. + + + Bibliothèques + + + Version: + + \ No newline at end of file diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.it.resx b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.it.resx new file mode 100644 index 0000000000..6972611447 --- /dev/null +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.it.resx @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Impossibile aggiungere riferimenti + + + Aggiugni al progetto + + + Sfoglia... + + + Sfoglia riferimenti + + + Database di Microsoft Access({0})|{0} + {0} = elenco delle estensioni delimitato da punto e virgola nel formato *.ext + + + Controlli ActiveX (*.ocx)|*.ocx + + + Tutti i file (*.*)|*.* + + + File di Microsoft Excel ({0})|{0} + {0} = elenco delle estensioni delimitato da punto e virgola nel formato *.ext + + + File eseguibili (*.exe;*.dll)|*.exe;*.dll + + + File VBA di Outlook ({0})|{0} + {0} = elenco delle estensioni delimitato da punto e virgola nel formato *.ext + + + File Addin di PowerPoint({0})|{0} + {0} = elenco delle estensioni delimitato da punto e virgola nel formato *.ext + + + File di Publisher ({0}|{0} + {0} = elenco delle estensioni delimitato da punto e virgola nel formato *.ext + + + Tipi Libreria (*.olb;*.tlb;*.dll)|*.olb;*.tlb;*.dll + + + Tutti i file di Visio ({0})|{0} + {0} = elenco delle estensioni delimitato da punto e virgola nel formato *.ext + + + Documenti di Word ({0})|{0} + {0} = elenco delle estensioni delimitato da punto e virgola nel formato *.ext + + + Aggiungi/Rimuovi Riferimento... + + + Aggiungi/Rimuovi Riferimenti - {0} + {0} = Nome del progetto + + + Standard + + + Lingua: + + + Sposta sotto + + + Sposta sopra + + + Bloccati + + + Blocca riferimento + + + Progetti + + + Recenti + + + Rimuovi dal progetto + + + Cerca riferimenti... + + + Selezionare i tipi libreria e progetti VB da aggiungere o rimuovere. + + + Tipi Libreria + + + Versione: + + + Riferimenti + + \ No newline at end of file diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.resx b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.resx new file mode 100644 index 0000000000..33cc5e3d34 --- /dev/null +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesUI.resx @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + References + + + Could not add reference + + + Add to project + + + Browse... + + + Browse for reference + + + Microsoft Access Databases({0})|{0} + {0} = semi-colon delimited extension list in the format of *.ext + + + ActiveX Controls (*.ocx)|*.ocx + + + All files (*.*)|*.* + + + Microsoft Excel Files ({0})|{0} + {0} = semi-colon delimited extension list in the format of *.ext + + + Executable Files (*.exe;*.dll)|*.exe;*.dll + + + Outlook VBA Files ({0})|{0} + {0} = semi-colon delimited extension list in the format of *.ext + + + PowerPoint Addin Files({0})|{0} + {0} = semi-colon delimited extension list in the format of *.ext + + + Publisher Files ({0}|{0} + {0} = semi-colon delimited extension list in the format of *.ext + + + Type Libraries (*.olb;*.tlb;*.dll)|*.olb;*.tlb;*.dll + + + All Visio Files ({0})|{0} + {0} = semi-colon delimited extension list in the format of *.ext + + + Word Documents ({0})|{0} + {0} = semi-colon delimited extension list in the format of *.ext + + + Add/Remove References... + + + Add/Remove References - {0} + {0} = Project name + + + Standard + Displayed as LCID description when locale is not specified. + + + Locale: + + + Move down + + + Move up + + + Pinned + + + Pin reference + + + Projects + + + Recent + + + Remove from project + + + Search for reference... + + + Select type libraries and VB projects to add or remove. + + + Type Libraries + + + Version: + + \ No newline at end of file diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesViewModel.cs b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesViewModel.cs index 923de4bb95..48ba14bf16 100644 --- a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesViewModel.cs +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesViewModel.cs @@ -45,21 +45,21 @@ public class AddRemoveReferencesViewModel : ViewModelBase private static readonly Dictionary HostFilters = new Dictionary { - { "EXCEL.EXE", string.Format(RubberduckUI.References_BrowseFilterExcel, string.Join(";", HostFileFilters["EXCEL.EXE"].Select(_ => $"*.{_}"))) }, - { "WINWORD.EXE", string.Format(RubberduckUI.References_BrowseFilterWord, string.Join(";", HostFileFilters["WINWORD.EXE"].Select(_ => $"*.{_}"))) }, - { "MSACCESS.EXE", string.Format(RubberduckUI.References_BrowseFilterAccess, string.Join(";", HostFileFilters["MSACCESS.EXE"].Select(_ => $"*.{_}"))) }, - { "POWERPNT.EXE", string.Format(RubberduckUI.References_BrowseFilterPowerPoint, string.Join(";", HostFileFilters["POWERPNT.EXE"].Select(_ => $"*.{_}"))) }, - { "OUTLOOK.EXE", string.Format(RubberduckUI.References_BrowseFilterOutlook, string.Join(";", HostFileFilters["OUTLOOK.EXE"].Select(_ => $"*.{_}"))) }, - { "MSPUB.EXE", string.Format(RubberduckUI.References_BrowseFilterOutlook, string.Join(";", HostFileFilters["MSPUB.EXE"].Select(_ => $"*.{_}"))) }, - { "VISIO.EXE", string.Format(RubberduckUI.References_BrowseFilterVisio, string.Join(";", HostFileFilters["VISIO.EXE"].Select(_ => $"*.{_}"))) }, + { "EXCEL.EXE", string.Format(AddRemoveReferencesUI.BrowseFilterExcel, string.Join(";", HostFileFilters["EXCEL.EXE"].Select(_ => $"*.{_}"))) }, + { "WINWORD.EXE", string.Format(AddRemoveReferencesUI.BrowseFilterWord, string.Join(";", HostFileFilters["WINWORD.EXE"].Select(_ => $"*.{_}"))) }, + { "MSACCESS.EXE", string.Format(AddRemoveReferencesUI.BrowseFilterAccess, string.Join(";", HostFileFilters["MSACCESS.EXE"].Select(_ => $"*.{_}"))) }, + { "POWERPNT.EXE", string.Format(AddRemoveReferencesUI.BrowseFilterPowerPoint, string.Join(";", HostFileFilters["POWERPNT.EXE"].Select(_ => $"*.{_}"))) }, + { "OUTLOOK.EXE", string.Format(AddRemoveReferencesUI.BrowseFilterOutlook, string.Join(";", HostFileFilters["OUTLOOK.EXE"].Select(_ => $"*.{_}"))) }, + { "MSPUB.EXE", string.Format(AddRemoveReferencesUI.BrowseFilterOutlook, string.Join(";", HostFileFilters["MSPUB.EXE"].Select(_ => $"*.{_}"))) }, + { "VISIO.EXE", string.Format(AddRemoveReferencesUI.BrowseFilterVisio, string.Join(";", HostFileFilters["VISIO.EXE"].Select(_ => $"*.{_}"))) }, }; private static readonly List FileFilters = new List { - RubberduckUI.References_BrowseFilterExecutable, - RubberduckUI.References_BrowseFilterTypes, - RubberduckUI.References_BrowseFilterActiveX, - RubberduckUI.References_BrowseFilterAllFiles, + AddRemoveReferencesUI.BrowseFilterExecutable, + AddRemoveReferencesUI.BrowseFilterTypes, + AddRemoveReferencesUI.BrowseFilterActiveX, + AddRemoveReferencesUI.BrowseFilterAllFiles, }; public static bool HostHasProjects { get; } @@ -127,14 +127,14 @@ public string ProjectCaption { if (string.IsNullOrEmpty(Model?.Project?.IdentifierName)) { - return RubberduckUI.References_Caption; + return AddRemoveReferencesUI.Caption; } var project = _projectsProvider.Project(Model.Project.ProjectId); if (project == null) { - return RubberduckUI.References_Caption; + return AddRemoveReferencesUI.Caption; } return project.ProjectDisplayName; @@ -277,7 +277,7 @@ private void ExecuteBrowseCommand(object parameter) using (var dialog = _browser.CreateOpenFileDialog()) { dialog.Filter = string.Join("|", FileFilters); - dialog.Title = RubberduckUI.References_BrowseCaption; + dialog.Title = AddRemoveReferencesUI.BrowseCaption; var result = dialog.ShowDialog(); if (result != DialogResult.OK || string.IsNullOrEmpty(dialog.FileName)) { diff --git a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesWindow.xaml b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesWindow.xaml index 96135d1c2d..e2e3f1a5a5 100644 --- a/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesWindow.xaml +++ b/Rubberduck.Core/UI/AddRemoveReferences/AddRemoveReferencesWindow.xaml @@ -85,7 +85,7 @@ @@ -106,12 +106,12 @@ - + - - + + @@ -123,7 +123,7 @@ - + @@ -131,7 +131,7 @@ - + @@ -139,7 +139,7 @@ - + @@ -147,17 +147,17 @@ - + - @@ -171,16 +171,16 @@ + Hint="{Resx ResxName=Rubberduck.UI.AddRemoveReferences.AddRemoveReferencesUI, Key=SearchPlaceholder}" /> + SelectionChanged="ListView_SynchronizeCurrentSelection_OnSelectionChanged"> - + @@ -178,7 +178,7 @@ - + @@ -196,7 +196,7 @@ - + @@ -227,14 +227,14 @@ - + - + @@ -258,7 +258,7 @@ @@ -416,7 +416,7 @@ - + - + - + @@ -485,15 +485,15 @@ Command="{Binding CodeExplorerExtractInterfaceCommand}" CommandParameter="{Binding SelectedItem, Mode=OneWay}"> - + - - + - + + ItemsSource="{DynamicResource AddModuleCommands}"> - + - + - + - + + @@ -571,14 +574,14 @@ Command="{Binding ExpandAllSubnodesCommand}" CommandParameter="{Binding SelectedItem, Mode=OneWay}"> - + - + @@ -586,7 +589,7 @@ Command="{Binding PrintCommand}" CommandParameter="{Binding SelectedItem, Mode=OneWay}"> - + @@ -605,7 +608,7 @@ - @@ -618,13 +621,14 @@ - - + + @@ -636,15 +640,15 @@ - - + + - + @@ -656,10 +660,10 @@ - - + + - + + + + + \ No newline at end of file diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerMoveToFolderCommandBase.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerMoveToFolderCommandBase.cs index af9be22963..c733e98b12 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerMoveToFolderCommandBase.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerMoveToFolderCommandBase.cs @@ -46,13 +46,11 @@ protected CodeExplorerMoveToFolderCommandBase( _state = state; _failureNotifier = failureNotifier; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } - private bool SpecialEvaluateCanExecute(object parameter) - { - return _parserStatusProvider.Status == ParserState.Ready; - } + private bool EvaluateCanExecute(object parameter) => + _parserStatusProvider.Status == ParserState.Ready; protected abstract ICodeExplorerNode NodeFromParameter(object parameter); protected abstract MoveMultipleFoldersModel ModifiedFolderModel(MoveMultipleFoldersModel model, object parameter); diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerRefactoringCommandBase.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerRefactoringCommandBase.cs index 3ccc54554a..a92368402b 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerRefactoringCommandBase.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/Abstract/CodeExplorerRefactoringCommandBase.cs @@ -26,13 +26,10 @@ protected CodeExplorerRefactoringCommandBase( _parserStatusProvider = parserStatusProvider; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } - private bool SpecialEvaluateCanExecute(object parameter) - { - return _parserStatusProvider.Status == ParserState.Ready; - } + private bool EvaluateCanExecute(object parameter) => _parserStatusProvider.Status == ParserState.Ready; protected abstract TModel ModelFromParameter(object parameter); protected abstract void ValidateModel(TModel model); diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/AddComponentCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/AddComponentCommand.cs index 2d9a2262d9..911a1c778d 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/AddComponentCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/AddComponentCommand.cs @@ -31,7 +31,7 @@ protected AddComponentCommandBase( _addComponentService = addComponentService; _projectsProvider = projectsProvider; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecuteBase); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; @@ -45,7 +45,7 @@ protected override void OnExecute(object parameter) AddComponent(parameter as CodeExplorerItemViewModel); } - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecuteBase(object parameter) { if (!(parameter is CodeExplorerItemViewModel node) || node.Declaration == null) diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/AddMDIFormCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/AddMDIFormCommand.cs index 3e895ef720..0b4bd6b905 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/AddMDIFormCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/AddMDIFormCommand.cs @@ -23,14 +23,14 @@ public AddMDIFormCommand( { _projectsProvider = projectsProvider; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public override IEnumerable AllowableProjectTypes => Types; public override ComponentType ComponentType => ComponentType.MDIForm; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { if (!(parameter is CodeExplorerItemViewModel node)) { diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/AddTemplateCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/AddTemplateCommand.cs index cc20e93804..5ee5c5626d 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/AddTemplateCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/AddTemplateCommand.cs @@ -46,7 +46,7 @@ public AddTemplateCommand( _projectsProvider = projectsProvider; _messageBox = messageBox; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public override IEnumerable ApplicableNodeTypes => new[]{typeof(System.ValueTuple)}; @@ -62,7 +62,7 @@ public bool CanExecuteForNode(ICodeExplorerNode model) return EvaluateCanExecute(model); } - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { if(parameter is ValueTuple data) { diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/AnnotateDeclarationCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/AnnotateDeclarationCommand.cs index a73ae91c88..b435ba3484 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/AnnotateDeclarationCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/AnnotateDeclarationCommand.cs @@ -40,12 +40,12 @@ public AnnotateDeclarationCommand( _userInteraction = userInteraction; _state = state; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public override IEnumerable ApplicableNodeTypes => new[] { typeof(System.ValueTuple) }; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { if (parameter is System.ValueTuple data) { diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerExtractInterfaceCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerExtractInterfaceCommand.cs index 2fb57027d7..7cfa7b7ffc 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerExtractInterfaceCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerExtractInterfaceCommand.cs @@ -30,20 +30,21 @@ public CodeExplorerExtractInterfaceCommand( _state = state; _refactoring = refactoring; _failureNotifier = failureNotifier; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); - AddToOnExecuteEvaluation(FurtherCanExecuteEvaluation); + AddToCanExecuteEvaluation(EvaluateCanExecute); + AddToOnExecuteEvaluation(EvaluateWillExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { return _state.Status == ParserState.Ready && parameter is CodeExplorerComponentViewModel node + && node.QualifiedSelection.HasValue && _refactoring.CanExecute(_state, node.QualifiedSelection.Value.QualifiedName); } - private bool FurtherCanExecuteEvaluation(object parameter) + private bool EvaluateWillExecute(object parameter) { return _state.Status == ParserState.Ready && parameter is CodeExplorerItemViewModel node diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllImplementationsCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllImplementationsCommand.cs index 57cb7b7b0e..53965a99fe 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllImplementationsCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllImplementationsCommand.cs @@ -27,12 +27,12 @@ public CodeExplorerFindAllImplementationsCommand( _state = state; _finder = finder; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { return _state.Status == ParserState.Ready && parameter is CodeExplorerItemViewModel node && diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllReferencesCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllReferencesCommand.cs index ff07afcab3..b46a3cbae5 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllReferencesCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerFindAllReferencesCommand.cs @@ -31,40 +31,63 @@ public CodeExplorerFindAllReferencesCommand( _state = state; _finder = finder; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute, true); } - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { - return _state.Status == ParserState.Ready - && ((ICodeExplorerNode)parameter).Declaration != null - && !(parameter is CodeExplorerReferenceViewModel reference - && reference.IsDimmed); + switch (parameter) + { + case CodeExplorerReferenceViewModel refNode: + return refNode.IsDimmed; + case ICodeExplorerNode node: + return !(node is CodeExplorerCustomFolderViewModel) + && !(node is CodeExplorerReferenceFolderViewModel); + case Declaration declaration: + return !(declaration is ProjectDeclaration); + default: + return false; + } } protected override void OnExecute(object parameter) { - if (_state.Status != ParserState.Ready - || !(parameter is ICodeExplorerNode node) - || node.Declaration == null) + var node = parameter as ICodeExplorerNode; + var declaration = parameter as Declaration; + var reference = parameter as CodeExplorerReferenceViewModel; + + if (_state.Status != ParserState.Ready || node == null && declaration == null) { return; } - if (!(node.Parent.Declaration is ProjectDeclaration projectDeclaration)) + if (declaration != null) { - Logger.Error($"The specified ICodeExplorerNode expected to be a direct child of a node whose declaration is a ProjectDeclaration."); + // command could have been invoked from PeekReferences code explorer popup + _finder.FindAllReferences(declaration); return; } - if (parameter is CodeExplorerReferenceViewModel reference) + if (reference != null) { - if (!(reference.Reference is ReferenceModel model)) + if (!(node.Parent.Declaration is ProjectDeclaration)) { + Logger.Error( + $"The specified ICodeExplorerNode ({node.GetType()}) is expected to be a direct child of a node whose declaration is a ProjectDeclaration."); + return; + } + + if(node.Parent?.Declaration is ProjectDeclaration projectDeclaration) + { + if (!(reference.Reference is ReferenceModel model)) + { + Logger.Warn($"Project reference '{reference.Name}' does not have an explorable reference model ({nameof(CodeExplorerReferenceViewModel)}.{nameof(CodeExplorerReferenceViewModel.Reference)} is null."); + return; + } + + _finder.FindAllReferences(projectDeclaration, model.ToReferenceInfo()); return; } - _finder.FindAllReferences(projectDeclaration, model.ToReferenceInfo()); - return; } _finder.FindAllReferences(node.Declaration); @@ -72,4 +95,4 @@ protected override void OnExecute(object parameter) public override IEnumerable ApplicableNodeTypes => ApplicableNodes; } -} +} \ No newline at end of file diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerMoveToFolderCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerMoveToFolderCommand.cs index 3f7f4708f1..fd0b6de916 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerMoveToFolderCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/CodeExplorerMoveToFolderCommand.cs @@ -31,12 +31,12 @@ public CodeExplorerMoveToFolderCommand( _moveFoldersInteraction = moveFoldersInteraction; _moveToFolderInteraction = moveToFolderInteraction; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public override IEnumerable ApplicableNodeTypes => ApplicableBaseNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { return parameter is CodeExplorerCustomFolderViewModel || parameter is CodeExplorerComponentViewModel componentViewModel diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs index ce9fd0708f..7904c4658c 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/DeleteCommand.cs @@ -34,12 +34,12 @@ public DeleteCommand( _vbe = vbe; _fileSystem = fileSystem; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public override IEnumerable ApplicableNodeTypes { get; } = new List { typeof(CodeExplorerComponentViewModel) }; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { return _vbe.Kind == VBEKind.Standalone && _removeCommand.CanExecute(parameter); diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/DragAndDrop/CodeExplorerMoveToFolderDragAndDropCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/DragAndDrop/CodeExplorerMoveToFolderDragAndDropCommand.cs index 523d27c419..990eaefcd5 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/DragAndDrop/CodeExplorerMoveToFolderDragAndDropCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/DragAndDrop/CodeExplorerMoveToFolderDragAndDropCommand.cs @@ -6,6 +6,7 @@ using Rubberduck.Navigation.CodeExplorer; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Refactorings.MoveFolder; using Rubberduck.Refactorings.MoveToFolder; @@ -35,13 +36,13 @@ public CodeExplorerMoveToFolderDragAndDropCommand( _declarationFinderProvider = declarationFinderProvider; _messageBox = messageBox; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } //We need to use the version with the interface since the type parameters always have to match exactly in the check in the base class. public override IEnumerable ApplicableNodeTypes => new []{typeof(ValueTuple)}; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { var (targetFolder, node) = (ValueTuple)parameter; return !string.IsNullOrEmpty(targetFolder) @@ -109,7 +110,7 @@ private List FoldersMergedWithTargetFolders(MoveMultipleFoldersModel mod private bool UserConfirmsToProceedWithFolderMerge(string targetFolder, List mergedTargetFolders) { var message = FolderMergeUserConfirmationMessage(targetFolder, mergedTargetFolders); - return _messageBox?.ConfirmYesNo(message, RubberduckUI.MoveFoldersDialog_Caption) ?? false; + return _messageBox?.ConfirmYesNo(message, RefactoringsUI.MoveFoldersDialog_Caption) ?? false; } private string FolderMergeUserConfirmationMessage(string targetFolder, List mergedTargetFolders) @@ -117,14 +118,14 @@ private string FolderMergeUserConfirmationMessage(string targetFolder, List ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { return _vbe.ProjectsCount == 1 || ThereIsAValidActiveProject(); } @@ -158,8 +158,8 @@ protected virtual ICollection FilesToImport(object parameter) dialog.ShowHelp = false; dialog.Title = DialogsTitle; dialog.Filter = - $"{RubberduckUI.ImportCommand_OpenDialog_Filter_VBFiles} ({FilterExtension})|{FilterExtension}|" + - $"{RubberduckUI.ImportCommand_OpenDialog_Filter_AllFiles}, (*.*)|*.*"; + $"{CodeExplorerUI.ImportCommand_OpenDialog_Filter_VBFiles} ({FilterExtension})|{FilterExtension}|" + + $"{CodeExplorerUI.ImportCommand_OpenDialog_Filter_AllFiles}, (*.*)|*.*"; if (dialog.ShowDialog() != DialogResult.OK) { @@ -178,14 +178,14 @@ protected virtual ICollection FilesToImport(object parameter) } } - protected virtual string DialogsTitle => RubberduckUI.ImportCommand_OpenDialog_Title; + protected virtual string DialogsTitle => CodeExplorerUI.ImportCommand_OpenDialog_Title; //TODO: Gather all conflicts and report them in one error dialog instead of reporting them one at a time. private void NotifyUserAboutAbortDueToUnsupportedFileExtensions(IEnumerable fileNames) { var firstUnsupportedFile = fileNames.First(filename => !ImportableExtensions.Contains(Path.GetExtension(filename))); var unsupportedFileName = Path.GetFileName(firstUnsupportedFile); - var message = string.Format(RubberduckUI.ImportCommand_UnsupportedFileExtensions, unsupportedFileName); + var message = string.Format(CodeExplorerUI.ImportCommand_UnsupportedFileExtensions, unsupportedFileName); MessageBox.NotifyWarn(message, DialogsTitle); } @@ -453,7 +453,7 @@ private void NotifyUserAboutAbortDueToDuplicateComponent(IDictionary kvp.Value) .First(moduleNameGroup => moduleNameGroup.Count() > 1) .Key; - var message = string.Format(RubberduckUI.ImportCommand_DuplicateModule, firstDuplicateModuleName); + var message = string.Format(CodeExplorerUI.ImportCommand_DuplicateModule, firstDuplicateModuleName); MessageBox.NotifyWarn(message, DialogsTitle); } @@ -476,7 +476,7 @@ private void NotifyUserAboutAbortDueToNonExistingDocument(ICollection do var firstNonExistingDocumentFilename = documentFiles.First(filename => !existingModules.ContainsKey(filename)); var firstNonExistingDocumentModuleName = moduleNames[firstNonExistingDocumentFilename]; var message = string.Format( - RubberduckUI.ImportCommand_DocumentDoesNotExist, + CodeExplorerUI.ImportCommand_DocumentDoesNotExist, firstNonExistingDocumentModuleName, firstNonExistingDocumentFilename); MessageBox.NotifyWarn(message, DialogsTitle); @@ -487,7 +487,7 @@ private void NotifyUserAboutAbortDueToNonExistingBinaryFile(ICollection var firstFilenameForFileWithoutBinaryAndComponent = filesWithoutBinary.First(); var missingBinariesOfFirstFilenameWithoutBinaryAndComponent = string.Join(", ", missingBinaries[firstFilenameForFileWithoutBinaryAndComponent]); var message = string.Format( - RubberduckUI.ImportCommand_BinaryDoesNotExist, + CodeExplorerUI.ImportCommand_BinaryDoesNotExist, firstFilenameForFileWithoutBinaryAndComponent, missingBinariesOfFirstFilenameWithoutBinaryAndComponent); MessageBox.NotifyWarn(message, DialogsTitle); @@ -499,7 +499,7 @@ private void NotifyUserAboutAbortDueToNonExistingBinaryFileAndComponent(ICollect var moduleNameOfFirstFilenameWithoutBinaryAndComponent = moduleNames[firstFilenameForFileWithoutBinaryAndComponent]; var missingBinariesOfFirstFilenameWithoutBinaryAndComponent = string.Join("', '", missingBinaries[firstFilenameForFileWithoutBinaryAndComponent]); var message = string.Format( - RubberduckUI.ImportCommand_BinaryAndComponentDoNotExist, + CodeExplorerUI.ImportCommand_BinaryAndComponentDoNotExist, firstFilenameForFileWithoutBinaryAndComponent, moduleNameOfFirstFilenameWithoutBinaryAndComponent, missingBinariesOfFirstFilenameWithoutBinaryAndComponent); diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/IndentCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/IndentCommand.cs index f52817504b..b939cdd8a2 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/IndentCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/IndentCommand.cs @@ -36,12 +36,12 @@ public IndentCommand( _indenter = indenter; _navigateCommand = navigateCommand; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { if (_state.Status != ParserState.Ready) { diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenCommand.cs index e2cd6e1d77..97c8bf4077 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenCommand.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using Rubberduck.Interaction.Navigation; using Rubberduck.Navigation.CodeExplorer; +using Rubberduck.Parsing.Symbols; using Rubberduck.VBEditor.Events; namespace Rubberduck.UI.CodeExplorer.Commands @@ -25,25 +26,22 @@ public OpenCommand( { _openCommand = openCommand; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { - return ((CodeExplorerItemViewModel)parameter).QualifiedSelection.HasValue; + return (parameter as CodeExplorerItemViewModel)?.QualifiedSelection.HasValue ?? false; } protected override void OnExecute(object parameter) { - if (!CanExecute(parameter)) + if (parameter is CodeExplorerItemViewModel item && item.QualifiedSelection.HasValue) { - return; + _openCommand.Execute(item.QualifiedSelection.Value.GetNavitationArgs()); } - - // ReSharper disable once PossibleInvalidOperationException - tested above. - _openCommand.Execute(((CodeExplorerItemViewModel)parameter).QualifiedSelection.Value.GetNavitationArgs()); } } } diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs index 49c0b22908..af68b6a439 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs @@ -30,12 +30,12 @@ public OpenDesignerCommand( _projectsProvider = projectsProvider; _vbe = vbe; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { if (!(parameter is CodeExplorerItemViewModel node)) { diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenProjectPropertiesCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenProjectPropertiesCommand.cs index 0a7bd86816..eadac16e0a 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenProjectPropertiesCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenProjectPropertiesCommand.cs @@ -30,12 +30,12 @@ public OpenProjectPropertiesCommand( _vbe = vbe; _projectsProvider = projectsProvider; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { if (!(parameter is CodeExplorerItemViewModel node)) { diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/PrintCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/PrintCommand.cs index 1823933c86..2913bd523c 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/PrintCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/PrintCommand.cs @@ -25,12 +25,12 @@ public PrintCommand( { _projectsProvider = projectsProvider; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { if (!(parameter is CodeExplorerComponentViewModel node) || node.Declaration == null) diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/RemoveCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/RemoveCommand.cs index 1ecf48efa5..ad7a987bec 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/RemoveCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/RemoveCommand.cs @@ -31,12 +31,12 @@ public RemoveCommand( _messageBox = messageBox; _vbe = vbe; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public override IEnumerable ApplicableNodeTypes { get; } = new List { typeof(CodeExplorerComponentViewModel)}; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { return _exportCommand.CanExecute(parameter) && parameter is CodeExplorerComponentViewModel viewModel && diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs index f8e5eb17b7..ac4e7fa7ac 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs @@ -41,12 +41,12 @@ public RenameCommand( _parserStatusProvider = parserStatusProvider; _renameFolderCommand = renameFolderCommand; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { return _parserStatusProvider.Status == ParserState.Ready && (!(parameter is CodeExplorerCustomFolderViewModel folderModel) diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/SetAsStartupProjectCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/SetAsStartupProjectCommand.cs index 38e8f24b22..4c6b17993e 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/SetAsStartupProjectCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/SetAsStartupProjectCommand.cs @@ -30,12 +30,12 @@ public SetAsStartupProjectCommand( _parserState = parserState; _projectsProvider = projectsProvider; - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); + AddToCanExecuteEvaluation(EvaluateCanExecute); } public sealed override IEnumerable ApplicableNodeTypes => ApplicableNodes; - private bool SpecialEvaluateCanExecute(object parameter) + private bool EvaluateCanExecute(object parameter) { try { diff --git a/Rubberduck.Core/UI/CodeMetrics/CodeMetricsControl.xaml b/Rubberduck.Core/UI/CodeMetrics/CodeMetricsControl.xaml index d4a58e938d..dd6acee7d8 100644 --- a/Rubberduck.Core/UI/CodeMetrics/CodeMetricsControl.xaml +++ b/Rubberduck.Core/UI/CodeMetrics/CodeMetricsControl.xaml @@ -38,7 +38,7 @@ - + - + @@ -78,7 +78,7 @@ - + @@ -89,9 +89,9 @@ - + - + diff --git a/Rubberduck.Core/UI/CodeMetrics/CodeMetricsWindow.cs b/Rubberduck.Core/UI/CodeMetrics/CodeMetricsWindow.cs index 325375306c..75bd3fc659 100644 --- a/Rubberduck.Core/UI/CodeMetrics/CodeMetricsWindow.cs +++ b/Rubberduck.Core/UI/CodeMetrics/CodeMetricsWindow.cs @@ -1,6 +1,6 @@ using System.Diagnostics.CodeAnalysis; using System.Windows.Forms; -using Rubberduck.Resources; +using Rubberduck.CodeAnalysis; using Rubberduck.CodeAnalysis.CodeMetrics; namespace Rubberduck.UI.CodeMetrics @@ -10,7 +10,7 @@ public sealed partial class CodeMetricsWindow : UserControl, IDockableUserContro { private const string ClassId = "C5318B5A-172F-417C-88E3-B377CDA2D809"; string IDockableUserControl.ClassId => ClassId; - string IDockableUserControl.Caption => RubberduckUI.CodeMetricsDockablePresenter_Caption; + string IDockableUserControl.Caption => CodeAnalysisUI.CodeMetricsDockablePresenter_Caption; private CodeMetricsWindow() { @@ -19,14 +19,10 @@ private CodeMetricsWindow() public CodeMetricsWindow(CodeMetricsViewModel viewModel) : this() { - _viewModel = viewModel; - codeMetricsControl1.DataContext = _viewModel; + ViewModel = viewModel; + codeMetricsControl1.DataContext = ViewModel; } - private readonly CodeMetricsViewModel _viewModel; - public CodeMetricsViewModel ViewModel - { - get { return _viewModel; } - } + public CodeMetricsViewModel ViewModel { get; } } } diff --git a/Rubberduck.Core/UI/Command/AboutCommand.cs b/Rubberduck.Core/UI/Command/AboutCommand.cs index 12d55e165a..c101b9246d 100644 --- a/Rubberduck.Core/UI/Command/AboutCommand.cs +++ b/Rubberduck.Core/UI/Command/AboutCommand.cs @@ -10,13 +10,13 @@ namespace Rubberduck.UI.Command [ComVisible(false)] public class AboutCommand : CommandBase { - public AboutCommand(IVersionCheck versionService, IWebNavigator web) + public AboutCommand(IVersionCheckService versionService, IWebNavigator web) { _versionService = versionService; _web = web; } - private readonly IVersionCheck _versionService; + private readonly IVersionCheckService _versionService; private readonly IWebNavigator _web; protected override void OnExecute(object parameter) diff --git a/Rubberduck.Core/UI/Command/ComCommands/CodeExplorerCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/CodeExplorerCommand.cs index 9d24d2b1d2..8e1caac308 100644 --- a/Rubberduck.Core/UI/Command/ComCommands/CodeExplorerCommand.cs +++ b/Rubberduck.Core/UI/Command/ComCommands/CodeExplorerCommand.cs @@ -1,6 +1,8 @@ using System.Runtime.InteropServices; +using Rubberduck.Navigation.CodeExplorer; using Rubberduck.UI.CodeExplorer; using Rubberduck.VBEditor.Events; +using Rubberduck.VBEditor.Utility; namespace Rubberduck.UI.Command.ComCommands { diff --git a/Rubberduck.Core/UI/Command/ComCommands/ExportAllCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/ExportAllCommand.cs index 6d0e2adc4d..01ba967f84 100644 --- a/Rubberduck.Core/UI/Command/ComCommands/ExportAllCommand.cs +++ b/Rubberduck.Core/UI/Command/ComCommands/ExportAllCommand.cs @@ -1,4 +1,5 @@ using Path = System.IO.Path; +using Directory = System.IO.Directory; using System.Windows.Forms; using Rubberduck.Navigation.CodeExplorer; using Rubberduck.Resources; @@ -6,25 +7,29 @@ using Rubberduck.VBEditor.Events; using Rubberduck.VBEditor.SafeComWrappers; using Rubberduck.VBEditor.SafeComWrappers.Abstract; +using System.Collections.Generic; namespace Rubberduck.UI.Command.ComCommands { public class ExportAllCommand : ComCommandBase { private readonly IVBE _vbe; - private readonly IFileSystemBrowserFactory _factory; private readonly IProjectsProvider _projectsProvider; + private readonly IFileSystemBrowserFactory _factory; + private readonly ProjectToExportFolderMap _projectToExportFolderMap; public ExportAllCommand( IVBE vbe, IFileSystemBrowserFactory folderBrowserFactory, IVbeEvents vbeEvents, - IProjectsProvider projectsProvider) + IProjectsProvider projectsProvider, + ProjectToExportFolderMap projectToExportFolderMap) : base(vbeEvents) { _vbe = vbe; _factory = folderBrowserFactory; _projectsProvider = projectsProvider; + _projectToExportFolderMap = projectToExportFolderMap; AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); } @@ -103,23 +108,62 @@ protected override void OnExecute(object parameter) private void Export(IVBProject project) { - var desc = string.Format(RubberduckUI.ExportAllCommand_SaveAsDialog_Title, project.Name); + var initialFolderBrowserPath = GetInitialFolderBrowserPath(project); - // If .GetDirectoryName is passed an empty string for a RootFolder, - // it defaults to the Documents library (Win 7+) or equivalent. - var path = string.IsNullOrWhiteSpace(project.FileName) - ? string.Empty - : Path.GetDirectoryName(project.FileName); + var desc = string.Format(RubberduckUI.ExportAllCommand_SaveAsDialog_Title, project.Name); - using (var _folderBrowser = _factory.CreateFolderBrowser(desc, true, path)) + using (var _folderBrowser = _factory.CreateFolderBrowser(desc, true, initialFolderBrowserPath)) { var result = _folderBrowser.ShowDialog(); if (result == DialogResult.OK) { + _projectToExportFolderMap.AssignProjectExportFolder(project, _folderBrowser.SelectedPath); project.ExportSourceFiles(_folderBrowser.SelectedPath); } } } + + //protected scope to support testing + protected string GetInitialFolderBrowserPath(IVBProject project) + { + if (_projectToExportFolderMap.TryGetExportPathForProject(project, out string initialFolderBrowserPath)) + { + if (FolderExists(initialFolderBrowserPath)) + { + //Return the cached folderpath of the previous ExportAllCommand process + return initialFolderBrowserPath; + } + + //The folder used in the previous ExportAllComand process no longer exists, remove the cached folderpath + _projectToExportFolderMap.RemoveProject(project); + } + + //The folder of the workbook, or an empty string + initialFolderBrowserPath = GetDefaultExportFolder(project.FileName); + + if (!string.IsNullOrEmpty(initialFolderBrowserPath)) + { + _projectToExportFolderMap.AssignProjectExportFolder(project, initialFolderBrowserPath); + } + + return initialFolderBrowserPath; + } + + //protected scope to support testing + protected string GetDefaultExportFolder(string projectFileName) + { + // If .GetDirectoryName is passed an empty string for a RootFolder, + // it defaults to the Documents library (Win 7+) or equivalent. + return string.IsNullOrWhiteSpace(projectFileName) + ? string.Empty + : Path.GetDirectoryName(projectFileName); + } + + //protected virtual to support testing + protected virtual bool FolderExists(string path) + { + return Directory.Exists(path); + } } } \ No newline at end of file diff --git a/Rubberduck.Core/UI/Command/ComCommands/FindAllImplementationsCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/FindAllImplementationsCommand.cs index 5e6cbad824..49e3389e3f 100644 --- a/Rubberduck.Core/UI/Command/ComCommands/FindAllImplementationsCommand.cs +++ b/Rubberduck.Core/UI/Command/ComCommands/FindAllImplementationsCommand.cs @@ -7,10 +7,35 @@ namespace Rubberduck.UI.Command.ComCommands { + public class ProjectExplorerFindAllImplementationsCommand : FindAllImplementationsCommand + { + private readonly ISelectedDeclarationProvider _selectedDeclarationProvider; + + public ProjectExplorerFindAllImplementationsCommand( + IParserStatusProvider parserStatusProvider, + ISelectedDeclarationProvider selectedDeclarationProvider, + ISearchResultsWindowViewModel viewModel, + FindAllImplementationsService finder, + IVbeEvents vbeEvents) + : base(parserStatusProvider, selectedDeclarationProvider, viewModel, finder, vbeEvents) + { + _selectedDeclarationProvider = selectedDeclarationProvider; + } + + protected override Declaration FindTarget(object parameter) + { + if (parameter is Declaration declaration) + { + return declaration; + } + + return _selectedDeclarationProvider.SelectedProjectExplorerModule(); + } + } + /// /// A command that finds all implementations of a specified method, or of the active interface module. /// - [ComVisible(false)] public class FindAllImplementationsCommand : ComCommandBase { private readonly ISelectedDeclarationProvider _selectedDeclarationProvider; @@ -59,7 +84,7 @@ protected override void OnExecute(object parameter) _finder.FindAllImplementations(declaration); } - private Declaration FindTarget(object parameter) + protected virtual Declaration FindTarget(object parameter) { if (parameter is Declaration declaration) { diff --git a/Rubberduck.Core/UI/Command/ComCommands/FindAllReferencesCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/FindAllReferencesCommand.cs index a76ca7e010..c631a74e3c 100644 --- a/Rubberduck.Core/UI/Command/ComCommands/FindAllReferencesCommand.cs +++ b/Rubberduck.Core/UI/Command/ComCommands/FindAllReferencesCommand.cs @@ -8,24 +8,56 @@ namespace Rubberduck.UI.Command.ComCommands { + public class ProjectExplorerFindAllReferencesCommand : FindAllReferencesCommand + { + private readonly IParserStatusProvider _parserStatusProvider; + private readonly ISelectedDeclarationProvider _finder; + + public ProjectExplorerFindAllReferencesCommand( + IParserStatusProvider parserStatusProvider, + IDeclarationFinderProvider declarationFinderProvider, + ISelectedDeclarationProvider selectedDeclarationProvider, + IVBE vbe, + FindAllReferencesAction finder, + IVbeEvents vbeEvents) + : base(parserStatusProvider, declarationFinderProvider, selectedDeclarationProvider, vbe, finder, vbeEvents) + { + _parserStatusProvider = parserStatusProvider; + _finder = selectedDeclarationProvider; + } + + protected override void OnExecute(object parameter) + { + if (_parserStatusProvider.Status != ParserState.Ready) + { + return; + } + + var declaration = _finder.SelectedProjectExplorerModule(); + if (declaration == null) + { + return; + } + + Service.FindAllReferences(declaration); + } + } + /// /// A command that locates all references to a specified identifier, or of the active code module. /// - [ComVisible(false)] public class FindAllReferencesCommand : ComCommandBase { private readonly IParserStatusProvider _parserStatusProvider; private readonly IDeclarationFinderProvider _declarationFinderProvider; private readonly ISelectedDeclarationProvider _selectedDeclarationProvider; private readonly IVBE _vbe; - private readonly FindAllReferencesAction _service; public FindAllReferencesCommand( IParserStatusProvider parserStatusProvider, IDeclarationFinderProvider declarationFinderProvider, ISelectedDeclarationProvider selectedDeclarationProvider, - IVBE vbe, - ISearchResultsWindowViewModel viewModel, + IVBE vbe, FindAllReferencesAction finder, IVbeEvents vbeEvents) : base(vbeEvents) @@ -34,11 +66,13 @@ public FindAllReferencesCommand( _declarationFinderProvider = declarationFinderProvider; _selectedDeclarationProvider = selectedDeclarationProvider; _vbe = vbe; - _service = finder; + Service = finder; AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); } + protected FindAllReferencesAction Service { get; } + private bool SpecialEvaluateCanExecute(object parameter) { if (_parserStatusProvider.Status != ParserState.Ready) @@ -77,7 +111,7 @@ protected override void OnExecute(object parameter) return; } - _service.FindAllReferences(declaration); + Service.FindAllReferences(declaration); } private Declaration FindTarget(object parameter) @@ -89,33 +123,30 @@ private Declaration FindTarget(object parameter) Declaration target = null; using (var activePane = _vbe.ActiveCodePane) + using (var selectedComponent = _vbe.SelectedVBComponent) { - using (var selectedComponent = _vbe.SelectedVBComponent) + if (activePane != null + && !activePane.IsWrappingNullReference + && (selectedComponent?.HasDesigner ?? false)) { - if (activePane != null - && !activePane.IsWrappingNullReference - && (selectedComponent?.HasDesigner ?? false)) + using (var activeWindow = activePane.Window) + using (var designer = selectedComponent.DesignerWindow()) { - using (var activeWindow = activePane.Window) - using (var designer = selectedComponent.DesignerWindow()) + // Handle() is 0 for both windows, and IsVisible is true whenever the window is merely opened (active or not, regardless of state). + // Caption will be "UserForm1 (Code)" vs "UserForm1 (UserForm)" + if (designer.IsVisible && designer.Caption == activeWindow.Caption) { - // Handle() is 0 for both windows, and IsVisible is true whenever the window is merely opened (active or not, regardless of state). - // Caption will be "UserForm1 (Code)" vs "UserForm1 (UserForm)" - if (designer.IsVisible && designer.Caption == activeWindow.Caption) - { - target = FindFormDesignerTarget(selectedComponent); - } + target = FindFormDesignerTarget(selectedComponent); } } } } + return target ?? FindCodePaneTarget(); } - private Declaration FindCodePaneTarget() - { - return _selectedDeclarationProvider.SelectedDeclaration(); - } + private Declaration FindCodePaneTarget() => _selectedDeclarationProvider.SelectedDeclaration(); + private Declaration FindFormDesignerTarget(IVBComponent component) { @@ -153,6 +184,7 @@ private Declaration FindFormDesignerTarget(IVBComponent component) private static (DeclarationType, string Name) GetSelectedName(IVBComponent component, IControls selectedControls, int selectedCount) { // Cannot use DeclarationType.UserForm, parser only assigns UserForms the ClassModule flag + // TODO determine if the above comment is still true. if (selectedCount == 0) { return (DeclarationType.ClassModule, component.Name); diff --git a/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentModuleCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentModuleCommand.cs index c44edd14c8..d2be62cb71 100644 --- a/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentModuleCommand.cs +++ b/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentModuleCommand.cs @@ -1,4 +1,8 @@ -using System.Runtime.InteropServices; +using System.Linq; +using System.Runtime.InteropServices; +using Rubberduck.Interaction; +using Rubberduck.Parsing.Annotations.Concrete; +using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.SmartIndenter; using Rubberduck.VBEditor.Events; @@ -12,17 +16,20 @@ public class IndentCurrentModuleCommand : ComCommandBase private readonly IVBE _vbe; private readonly IIndenter _indenter; private readonly RubberduckParserState _state; + private readonly IMessageBox _messageBox; public IndentCurrentModuleCommand( IVBE vbe, IIndenter indenter, RubberduckParserState state, - IVbeEvents vbeEvents) + IVbeEvents vbeEvents, + IMessageBox messageBox) : base(vbeEvents) { _vbe = vbe; _indenter = indenter; _state = state; + _messageBox = messageBox; AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); } @@ -36,8 +43,32 @@ private bool SpecialEvaluateCanExecute(object parameter) } protected override void OnExecute(object parameter) - { - _indenter.IndentCurrentModule(); + { + if (_state.IsDirty()) + { + if (!_messageBox.ConfirmYesNo( + Resources.RubberduckUI.Indenter_ContinueIndentWithoutAnnotations, + Resources.RubberduckUI.Indenter_ContinueIndentWithoutAnnotations_DialogCaption, + false)) + return; + + _indenter.IndentCurrentModule(); + } + else + { + var componentDeclarations = _state.AllUserDeclarations.Where(c => + c.DeclarationType.HasFlag(DeclarationType.Module) && + !c.Annotations.Any(pta => pta.Annotation is NoIndentAnnotation) && + c.ProjectId == _vbe.ActiveVBProject.ProjectId && + c.QualifiedModuleName == _vbe.ActiveCodePane.QualifiedModuleName + ); + + foreach (var componentDeclaration in componentDeclarations) + { + _indenter.Indent(_state.ProjectsProvider.Component(componentDeclaration.QualifiedName.QualifiedModuleName)); + } + } + if (_state.Status >= ParserState.Ready || _state.Status == ParserState.Pending) { _state.OnParseRequested(this); diff --git a/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentProjectCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentProjectCommand.cs index bfee2a17d0..1aa759027a 100644 --- a/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentProjectCommand.cs +++ b/Rubberduck.Core/UI/Command/ComCommands/IndentCurrentProjectCommand.cs @@ -1,4 +1,8 @@ -using System.Runtime.InteropServices; +using System.Linq; +using System.Runtime.InteropServices; +using Rubberduck.Interaction; +using Rubberduck.Parsing.Annotations.Concrete; +using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.SmartIndenter; using Rubberduck.VBEditor.Events; @@ -13,17 +17,20 @@ public class IndentCurrentProjectCommand : ComCommandBase private readonly IVBE _vbe; private readonly IIndenter _indenter; private readonly RubberduckParserState _state; + private readonly IMessageBox _messageBox; public IndentCurrentProjectCommand( IVBE vbe, IIndenter indenter, RubberduckParserState state, - IVbeEvents vbeEvents) + IVbeEvents vbeEvents, + IMessageBox messageBox) : base(vbeEvents) { _vbe = vbe; _indenter = indenter; _state = state; + _messageBox = messageBox; AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); } @@ -39,7 +46,29 @@ private bool SpecialEvaluateCanExecute(object parameter) protected override void OnExecute(object parameter) { - _indenter.IndentCurrentProject(); + if (_state.IsDirty()) + { + if (!_messageBox.ConfirmYesNo( + Resources.RubberduckUI.Indenter_ContinueIndentWithoutAnnotations, + Resources.RubberduckUI.Indenter_ContinueIndentWithoutAnnotations_DialogCaption, + false)) + return; + + _indenter.IndentCurrentProject(); + } + else + { + var componentDeclarations = _state.AllUserDeclarations.Where(c => + c.DeclarationType.HasFlag(DeclarationType.Module) && + !c.Annotations.Any(pta => pta.Annotation is NoIndentAnnotation) && + c.ProjectId == _vbe.ActiveVBProject.ProjectId); + + foreach (var componentDeclaration in componentDeclarations) + { + _indenter.Indent(_state.ProjectsProvider.Component(componentDeclaration.QualifiedName.QualifiedModuleName)); + } + } + if (_state.Status >= ParserState.Ready || _state.Status == ParserState.Pending) { _state.OnParseRequested(this); diff --git a/Rubberduck.Core/UI/Command/ComCommands/PeekDefinitionCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/PeekDefinitionCommand.cs new file mode 100644 index 0000000000..5b1a972548 --- /dev/null +++ b/Rubberduck.Core/UI/Command/ComCommands/PeekDefinitionCommand.cs @@ -0,0 +1,65 @@ +using System.Runtime.InteropServices; +using Rubberduck.Navigation.CodeExplorer; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.UI.CodeExplorer; +using Rubberduck.VBEditor.Events; + +namespace Rubberduck.UI.Command.ComCommands +{ + /// + /// A command that displays a popup near the cursor, owned by the Code Explorer WPF UserControl. + /// + public class PeekDefinitionCommand : ComCommandBase + { + public PeekDefinitionCommand(IPeekDefinitionPopupProvider provider, IVbeEvents vbeEvents, ISelectedDeclarationProvider selection) + : base(vbeEvents) + { + PopupProvider = provider; + SelectedDeclarationProvider = selection; + AddToCanExecuteEvaluation(EvaluateCanExecute); + } + + protected ISelectedDeclarationProvider SelectedDeclarationProvider { get; } + protected IPeekDefinitionPopupProvider PopupProvider { get; } + + private bool EvaluateCanExecute(object parameter) + { + if (parameter is ModuleDeclaration || parameter is ModuleBodyElementDeclaration || parameter is VariableDeclaration || parameter is ValuedDeclaration) + { + return true; + } + + return SelectedDeclarationProvider.SelectedDeclaration() != null; + } + + protected override void OnExecute(object parameter) + { + if (parameter is Declaration target) + { + PopupProvider.PeekDefinition(target); + } + else + { + var selection = SelectedDeclarationProvider.SelectedDeclaration(); + if (selection != null) + { + PopupProvider.PeekDefinition(selection); + } + } + } + } + + public class ProjectExplorerPeekDefinitionCommand : PeekDefinitionCommand + { + public ProjectExplorerPeekDefinitionCommand(IPeekDefinitionPopupProvider provider, IVbeEvents vbeEvents, ISelectedDeclarationProvider selection) + : base(provider, vbeEvents, selection) + {} + + protected override void OnExecute(object parameter) + { + var module = SelectedDeclarationProvider.SelectedProjectExplorerModule(); + base.OnExecute(module); + } + } +} \ No newline at end of file diff --git a/Rubberduck.Core/UI/Command/ComCommands/PeekDefinitionFindAllReferencesCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/PeekDefinitionFindAllReferencesCommand.cs new file mode 100644 index 0000000000..45e994bfae --- /dev/null +++ b/Rubberduck.Core/UI/Command/ComCommands/PeekDefinitionFindAllReferencesCommand.cs @@ -0,0 +1,58 @@ +using Rubberduck.Interaction.Navigation; +using Rubberduck.Parsing.Symbols; +using Rubberduck.UI.Controls; +using Rubberduck.VBEditor.Events; + +namespace Rubberduck.UI.Command.ComCommands +{ + public class PeekDefinitionFindAllReferencesCommand : ComCommandBase + { + private readonly FindAllReferencesAction _action; + + public PeekDefinitionFindAllReferencesCommand( + FindAllReferencesAction action, + IVbeEvents vbeEvents) : base(vbeEvents) + { + AddToCanExecuteEvaluation(EvaluateCanExecute, true); + _action = action; + } + + private bool EvaluateCanExecute(object parameter) + { + if (parameter is Declaration declaration) + { + return declaration.IsUserDefined && !(declaration is ProjectDeclaration); + } + + return false; + } + + protected override void OnExecute(object parameter) => _action?.FindAllReferences((Declaration)parameter); + } + + public class PeekDefinitionNavigateCommand : ComCommandBase + { + private readonly INavigateCommand _action; + + public PeekDefinitionNavigateCommand(INavigateCommand action, IVbeEvents vbeEvents) + : base(vbeEvents) + { + AddToCanExecuteEvaluation(EvaluateCanExecute, true); + _action = action; + } + + private bool EvaluateCanExecute(object parameter) + { + if (parameter is Declaration declaration) + { + return declaration.IsUserDefined + && !(declaration is ProjectDeclaration); + } + + return false; + } + + protected override void OnExecute(object parameter) => + _action?.Execute(((Declaration) parameter).QualifiedSelection.GetNavitationArgs()); + } +} \ No newline at end of file diff --git a/Rubberduck.Core/UI/Command/ComCommands/ReparseCommand.cs b/Rubberduck.Core/UI/Command/ComCommands/ReparseCommand.cs index 945bf386e2..0f2a12ae33 100644 --- a/Rubberduck.Core/UI/Command/ComCommands/ReparseCommand.cs +++ b/Rubberduck.Core/UI/Command/ComCommands/ReparseCommand.cs @@ -4,7 +4,7 @@ using System.Runtime.InteropServices; using Rubberduck.Interaction; using Rubberduck.Parsing.VBA; -using Rubberduck.Resources; +using Rubberduck.CodeAnalysis; using Rubberduck.Settings; using Rubberduck.SettingsProvider; using Rubberduck.VBEditor.ComManagement.TypeLibs.Abstract; @@ -100,7 +100,7 @@ private bool VerifyCompileOnDemand() { if (_vbeSettings.CompileOnDemand) { - return _messageBox.ConfirmYesNo(RubberduckUI.Command_Reparse_CompileOnDemandEnabled, RubberduckUI.Command_Reparse_CompileOnDemandEnabled_Caption, false); + return _messageBox.ConfirmYesNo(CodeAnalysisUI.Command_Reparse_CompileOnDemandEnabled, CodeAnalysisUI.Command_Reparse_CompileOnDemandEnabled_Caption, false); } return true; @@ -137,9 +137,9 @@ private bool PromptUserToContinue(List failedNames) string.Join(Environment.NewLine, failedNames)); // FIXME using Exclamation instead of warning now... return _messageBox.ConfirmYesNo( - string.Format(RubberduckUI.Command_Reparse_CannotCompile, + string.Format(CodeAnalysisUI.Command_Reparse_CannotCompile, formattedList), - RubberduckUI.Command_Reparse_CannotCompile_Caption, false); + CodeAnalysisUI.Command_Reparse_CannotCompile_Caption, false); } } diff --git a/Rubberduck.Core/UI/Command/MenuItems/CodeExplorerCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/CodeExplorerCommandMenuItem.cs index b25dce88fc..2150022895 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/CodeExplorerCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/CodeExplorerCommandMenuItem.cs @@ -16,4 +16,14 @@ public CodeExplorerCommandMenuItem(CodeExplorerCommand command) public override string Key => "RubberduckMenu_CodeExplorer"; public override int DisplayOrder => (int)NavigationMenuItemDisplayOrder.CodeExplorer; } + + public class WindowsCodeExplorerCommandMenuItem : CodeExplorerCommandMenuItem + { + public WindowsCodeExplorerCommandMenuItem(CodeExplorerCommand command) + : base(command) + { } + + public override int DisplayOrder => (int)WindowMenuItemDisplayOrder.CodeExplorer; + } + } diff --git a/Rubberduck.Core/UI/Command/MenuItems/CodeMetricsCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/CodeMetricsCommandMenuItem.cs index 947f5ae37a..b517e2b607 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/CodeMetricsCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/CodeMetricsCommandMenuItem.cs @@ -15,4 +15,14 @@ public CodeMetricsCommandMenuItem(CodeMetricsCommand command) public override string Key => "RubberduckMenu_CodeMetrics"; public override int DisplayOrder => (int)ToolsMenuItemDisplayOrder.CodeMetrics; } + + public class WindowsCodeMetricsCommandMenuItem : CodeMetricsCommandMenuItem + { + public WindowsCodeMetricsCommandMenuItem(CodeMetricsCommand command) + : base(command) + { + } + + public override int DisplayOrder => (int)WindowMenuItemDisplayOrder.CodeMetrics; + } } diff --git a/Rubberduck.Core/UI/Command/MenuItems/CommandBars/IContextFormatter.cs b/Rubberduck.Core/UI/Command/MenuItems/CommandBars/IContextFormatter.cs index fb6d90e51a..faa2e35be0 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/CommandBars/IContextFormatter.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/CommandBars/IContextFormatter.cs @@ -4,6 +4,7 @@ using Rubberduck.VBEditor.SafeComWrappers.Abstract; using Rubberduck.Resources; using Rubberduck.VBEditor; +using Rubberduck.CodeAnalysis; using System.Threading.Tasks; namespace Rubberduck.UI.Command.MenuItems.CommandBars @@ -58,7 +59,7 @@ private async Task FormatDeclarationAsync(Declaration declaration, Cance { token.ThrowIfCancellationRequested(); var moduleName = declaration.QualifiedName.QualifiedModuleName; - var declarationType = RubberduckUI.ResourceManager.GetString("DeclarationType_" + declaration.DeclarationType, Settings.Settings.Culture); + var declarationType = CodeAnalysisUI.ResourceManager.GetString("DeclarationType_" + declaration.DeclarationType, Settings.Settings.Culture); var typeName = TypeName(declaration, multipleControls, declarationType); var formattedDeclaration = await FormattedDeclarationAsync(declaration, typeName, moduleName, declarationType, token); diff --git a/Rubberduck.Core/UI/Command/MenuItems/CommandBars/RubberduckCommandBar.cs b/Rubberduck.Core/UI/Command/MenuItems/CommandBars/RubberduckCommandBar.cs index 5861112924..f803df5899 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/CommandBars/RubberduckCommandBar.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/CommandBars/RubberduckCommandBar.cs @@ -79,7 +79,7 @@ private async void OnSelectionChange(object sender, DeclarationChangedEventArgs var source = _tokenSources.GetOrAdd(nameof(OnSelectionChange), k => new CancellationTokenSource()); var token = source.Token; - await Task.Run(async () => + Task.Run(async () => { var caption = await _formatter.FormatAsync(e.Declaration, e.MultipleControlsSelected, token); token.ThrowIfCancellationRequested(); diff --git a/Rubberduck.Core/UI/Command/MenuItems/FindAllImplementationsCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/FindAllImplementationsCommandMenuItem.cs index 0ab4c68edb..2ef351892d 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/FindAllImplementationsCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/FindAllImplementationsCommandMenuItem.cs @@ -29,7 +29,7 @@ public FindAllImplementationsCommandMenuItem(FindAllImplementationsCommand comma public class ProjectExplorerFindAllImplementationsCommandMenuItem : FindAllImplementationsCommandMenuItemBase { - public ProjectExplorerFindAllImplementationsCommandMenuItem(FindAllImplementationsCommand command) + public ProjectExplorerFindAllImplementationsCommandMenuItem(ProjectExplorerFindAllImplementationsCommand command) : base(command) {} diff --git a/Rubberduck.Core/UI/Command/MenuItems/FindAllReferencesCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/FindAllReferencesCommandMenuItem.cs index 7044822537..9ce05d512e 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/FindAllReferencesCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/FindAllReferencesCommandMenuItem.cs @@ -31,7 +31,7 @@ public FindAllReferencesCommandMenuItem(FindAllReferencesCommand command) public class ProjectExplorerFindAllReferencesCommandMenuItem : FindAllReferencesCommandMenuItemBase { - public ProjectExplorerFindAllReferencesCommandMenuItem(FindAllReferencesCommand command) + public ProjectExplorerFindAllReferencesCommandMenuItem(ProjectExplorerFindAllReferencesCommand command) : base(command) {} diff --git a/Rubberduck.Core/UI/Command/MenuItems/FindSymbolCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/FindSymbolCommandMenuItem.cs index 14af3b49c7..d8b7c38275 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/FindSymbolCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/FindSymbolCommandMenuItem.cs @@ -12,8 +12,6 @@ protected FindSymbolCommandMenuItemBase(FindSymbolCommand command) {} public override string Key => "ContextMenu_FindSymbol"; - public override bool BeginGroup => true; - public override Image Image => Resources.CommandBarIcons.FindSymbol; public override Image Mask => Resources.CommandBarIcons.FindSymbolMask; diff --git a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/CodePaneContextParentMenu.cs b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/CodePaneContextParentMenu.cs index 41109510ac..5d36d69c75 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/CodePaneContextParentMenu.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/CodePaneContextParentMenu.cs @@ -19,6 +19,7 @@ public enum CodePaneContextMenuItemDisplayOrder Annotate, Indenter, RegexSearchReplace, + PeekDefinition, FindSymbol, FindAllReferences, FindAllImplementations, diff --git a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/ProjectWindowContextParentMenu.cs b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/ProjectWindowContextParentMenu.cs index c0fa82f1a1..bbca7dccb2 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/ProjectWindowContextParentMenu.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/ProjectWindowContextParentMenu.cs @@ -16,6 +16,7 @@ public ProjectWindowContextParentMenu(IEnumerable items, int beforeIn public enum ProjectExplorerContextMenuItemDisplayOrder { RenameIdentifier, + PeekDefinition, FindSymbol, FindAllReferences, FindAllImplementations, diff --git a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RefactoringsParentMenu.cs b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RefactoringsParentMenu.cs index c0bcf2789e..7deaaf0074 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RefactoringsParentMenu.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RefactoringsParentMenu.cs @@ -23,7 +23,7 @@ public enum RefactoringsMenuItemDisplayOrder ReorderParameters, MoveCloserToUsage, EncapsulateField, - IntroduceParameter, + PromoteToParameter, IntroduceField, MoveToFolder, MoveContainingFolder, diff --git a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RubberduckParentMenu.cs b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RubberduckParentMenu.cs index 0f939568b9..8b7bbbf5bf 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RubberduckParentMenu.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/RubberduckParentMenu.cs @@ -18,6 +18,7 @@ public enum RubberduckMenuItemDisplayOrder Refactorings, Navigate, Tools, + Windows, CodeInspections, Settings, About, diff --git a/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/WindowParentMenu.cs b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/WindowParentMenu.cs new file mode 100644 index 0000000000..de39f2bba2 --- /dev/null +++ b/Rubberduck.Core/UI/Command/MenuItems/ParentMenus/WindowParentMenu.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using Rubberduck.Parsing.UIContext; + +namespace Rubberduck.UI.Command.MenuItems.ParentMenus +{ + public class WindowParentMenu : ParentMenuItemBase + { + public WindowParentMenu(IEnumerable items, IUiDispatcher dispatcher) + : base(dispatcher, "WindowMenu", items) + { + } + + public override int DisplayOrder => (int)RubberduckMenuItemDisplayOrder.Tools; + } + + public enum WindowMenuItemDisplayOrder + { + TestExplorer, + CodeExplorer, + CodeMetrics, + ToDoExplorer + } +} diff --git a/Rubberduck.Core/UI/Command/MenuItems/PeekDefinitionCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/PeekDefinitionCommandMenuItem.cs new file mode 100644 index 0000000000..89a4369283 --- /dev/null +++ b/Rubberduck.Core/UI/Command/MenuItems/PeekDefinitionCommandMenuItem.cs @@ -0,0 +1,32 @@ +using Rubberduck.Parsing.VBA; +using Rubberduck.UI.Command.ComCommands; +using Rubberduck.UI.Command.MenuItems.ParentMenus; + +namespace Rubberduck.UI.Command.MenuItems +{ + public class PeekDefinitionCommandMenuItem : CommandMenuItemBase + { + public PeekDefinitionCommandMenuItem(PeekDefinitionCommand command) + : base(command) + {} + + public override string Key => "ContextMenu_PeekDefinition"; + public override bool BeginGroup => true; + + public override int DisplayOrder => (int) CodePaneContextMenuItemDisplayOrder.PeekDefinition; + + public override bool EvaluateCanExecute(RubberduckParserState state) + { + return state?.Status == ParserState.Ready; + } + } + + public class ProjectExplorerPeekDefinitionCommandMenuItem : PeekDefinitionCommandMenuItem + { + public ProjectExplorerPeekDefinitionCommandMenuItem(ProjectExplorerPeekDefinitionCommand command) + : base(command) + {} + + public override int DisplayOrder => (int) ProjectExplorerContextMenuItemDisplayOrder.PeekDefinition; + } +} \ No newline at end of file diff --git a/Rubberduck.Core/UI/Command/MenuItems/RefactorExtractMethodCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/RefactorExtractMethodCommandMenuItem.cs index dd6175094f..18ba05746a 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/RefactorExtractMethodCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/RefactorExtractMethodCommandMenuItem.cs @@ -6,7 +6,6 @@ namespace Rubberduck.UI.Command.MenuItems { - [Disabled] public class RefactorExtractMethodCommandMenuItem : CommandMenuItemBase { public RefactorExtractMethodCommandMenuItem(RefactorExtractMethodCommand command) diff --git a/Rubberduck.Core/UI/Command/MenuItems/RefactorIntroduceParameterCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/RefactorPromoteToParameterCommandMenuItem.cs similarity index 72% rename from Rubberduck.Core/UI/Command/MenuItems/RefactorIntroduceParameterCommandMenuItem.cs rename to Rubberduck.Core/UI/Command/MenuItems/RefactorPromoteToParameterCommandMenuItem.cs index 9a4fda1e80..c26ca0426e 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/RefactorIntroduceParameterCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/RefactorPromoteToParameterCommandMenuItem.cs @@ -5,15 +5,15 @@ namespace Rubberduck.UI.Command.MenuItems { - public class RefactorIntroduceParameterCommandMenuItem : CommandMenuItemBase + public class RefactorPromoteToParameterCommandMenuItem : CommandMenuItemBase { - public RefactorIntroduceParameterCommandMenuItem (RefactorIntroduceParameterCommand command) + public RefactorPromoteToParameterCommandMenuItem (RefactorPromoteToParameterCommand command) : base(command) { } - public override string Key => "RefactorMenu_IntroduceParameter"; - public override int DisplayOrder => (int)RefactoringsMenuItemDisplayOrder.IntroduceParameter; + public override string Key => "RefactorMenu_PromoteToParameter"; + public override int DisplayOrder => (int)RefactoringsMenuItemDisplayOrder.PromoteToParameter; public override bool BeginGroup => true; public override Image Image => Resources.CommandBarIcons.PromoteLocal; diff --git a/Rubberduck.Core/UI/Command/MenuItems/TestExplorerCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/TestExplorerCommandMenuItem.cs index c83d6b0abf..b1562b3a8f 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/TestExplorerCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/TestExplorerCommandMenuItem.cs @@ -13,4 +13,14 @@ public TestExplorerCommandMenuItem(TestExplorerCommand command) public override string Key => "TestMenu_TextExplorer"; public override int DisplayOrder => (int)UnitTestingMenuItemDisplayOrder.TestExplorer; } + + internal class WindowsTestExplorerCommandMenuItem : TestExplorerCommandMenuItem + { + public WindowsTestExplorerCommandMenuItem(TestExplorerCommand command) + : base(command) + { + } + + public override int DisplayOrder => (int)WindowMenuItemDisplayOrder.TestExplorer; + } } diff --git a/Rubberduck.Core/UI/Command/MenuItems/ToDoExplorerCommandMenuItem.cs b/Rubberduck.Core/UI/Command/MenuItems/ToDoExplorerCommandMenuItem.cs index ae56a35aeb..91d33a3d33 100644 --- a/Rubberduck.Core/UI/Command/MenuItems/ToDoExplorerCommandMenuItem.cs +++ b/Rubberduck.Core/UI/Command/MenuItems/ToDoExplorerCommandMenuItem.cs @@ -13,4 +13,14 @@ public ToDoExplorerCommandMenuItem(ToDoExplorerCommand command) public override string Key => "ToolsMenu_TodoItems"; public override int DisplayOrder => (int)ToolsMenuItemDisplayOrder.ToDoExplorer; } + + public class WindowsToDoExplorerCommandMenuItem : ToDoExplorerCommandMenuItem + { + public WindowsToDoExplorerCommandMenuItem(ToDoExplorerCommand command) + : base(command) + { + } + + public override int DisplayOrder => (int)WindowMenuItemDisplayOrder.ToDoExplorer; + } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/AnnotateDeclarationFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/AnnotateDeclarationFailedNotifier.cs index 52c51a917a..066e60b424 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/AnnotateDeclarationFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/AnnotateDeclarationFailedNotifier.cs @@ -2,6 +2,7 @@ using Rubberduck.Interaction; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Resources; +using Rubberduck.Refactorings; namespace Rubberduck.UI.Command.Refactorings.Notifiers { @@ -11,7 +12,7 @@ public AnnotateDeclarationFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => RubberduckUI.AnnotateDeclarationDialog_Caption; + protected override string Caption => RefactoringsUI.AnnotateDeclarationDialog_Caption; protected override string Message(RefactoringException exception) { @@ -19,7 +20,7 @@ protected override string Message(RefactoringException exception) { Logger.Warn(invalidTypeException); return string.Format( - RubberduckUI.RefactoringFailure_AnnotateDeclaration_InvalidType, + RefactoringsUI.RefactoringFailure_AnnotateDeclaration_InvalidType, invalidTypeException.TargetDeclaration.DeclarationType.ToLocalizedString()); } diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/EncapsulateFieldFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/EncapsulateFieldFailedNotifier.cs index 8680ef3d62..9558932310 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/EncapsulateFieldFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/EncapsulateFieldFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; namespace Rubberduck.UI.Command.Refactorings.Notifiers @@ -10,7 +11,7 @@ public EncapsulateFieldFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => Resources.RubberduckUI.EncapsulateField_Caption; + protected override string Caption => RefactoringsUI.EncapsulateField_Caption; protected override string Message(RefactoringException exception) { @@ -18,7 +19,7 @@ protected override string Message(RefactoringException exception) { case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedModuleName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.Variable); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ExtractInterfaceFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ExtractInterfaceFailedNotifier.cs index df3b3f6dbe..eaa88bbdd0 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ExtractInterfaceFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ExtractInterfaceFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; namespace Rubberduck.UI.Command.Refactorings.Notifiers @@ -10,7 +11,7 @@ public ExtractInterfaceFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => Resources.RubberduckUI.ExtractInterface_Caption; + protected override string Caption => RefactoringsUI.ExtractInterface_Caption; protected override string Message(RefactoringException exception) { @@ -18,7 +19,7 @@ protected override string Message(RefactoringException exception) { case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedModuleName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.ClassModule); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ExtractMethodFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ExtractMethodFailedNotifier.cs new file mode 100644 index 0000000000..abca998199 --- /dev/null +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ExtractMethodFailedNotifier.cs @@ -0,0 +1,31 @@ +using Rubberduck.Interaction; +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.Exceptions; +using Rubberduck.Refactorings.Exceptions.ExtractMethod; + +namespace Rubberduck.UI.Command.Refactorings.Notifiers +{ + public class ExtractMethodFailedNotifier : RefactoringFailureNotifierBase + { + public ExtractMethodFailedNotifier(IMessageBox messageBox) + : base(messageBox) + {} + + protected override string Caption => RefactoringsUI.ExtractMethod_Caption; + + protected override string Message(RefactoringException exception) + { + switch (exception) + { + case UnableToMoveVariableDeclarationException unableToMoveVariableDeclaration: + Logger.Warn(unableToMoveVariableDeclaration); + return RefactoringsUI.ExtractMethod_UnableToMoveVariableDeclarationMessage; //TODO - improve this message to show declaration + case InvalidTargetSelectionException invalidTargetSelection: + return string.Format(RefactoringsUI.ExtractMethod_InvalidSelectionMessage, invalidTargetSelection.Message); + //case + default: + return base.Message(exception); + } + } + } +} \ No newline at end of file diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ImplementInterfaceFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ImplementInterfaceFailedNotifier.cs index fd1ff7471c..83da31733d 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ImplementInterfaceFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ImplementInterfaceFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Refactorings.Exceptions.ImplementInterface; @@ -11,7 +12,7 @@ public ImplementInterfaceFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => Resources.RubberduckUI.ImplementInterface_Caption; + protected override string Caption => RefactoringsUI.ImplementInterface_Caption; protected override string Message(RefactoringException exception) { @@ -19,10 +20,10 @@ protected override string Message(RefactoringException exception) { case NoImplementsStatementSelectedException noImplementsStatementSelected: Logger.Warn(noImplementsStatementSelected); - return Resources.RubberduckUI.ImplementInterfaceFailed_NoImplementsStatementSelected; + return RefactoringsUI.ImplementInterfaceFailed_NoImplementsStatementSelected; case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedModuleName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.ClassModule); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/IntroduceFieldFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/IntroduceFieldFailedNotifier.cs index 29f3549f1e..3f3bbd630b 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/IntroduceFieldFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/IntroduceFieldFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Refactorings.Exceptions.IntroduceField; @@ -11,7 +12,7 @@ public IntroduceFieldFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => Resources.RubberduckUI.IntroduceField_Caption; + protected override string Caption => RefactoringsUI.IntroduceField_Caption; protected override string Message(RefactoringException exception) { @@ -19,11 +20,11 @@ protected override string Message(RefactoringException exception) { case TargetIsAlreadyAFieldException isAlreadyAField: Logger.Warn(isAlreadyAField); - return string.Format(Resources.RubberduckUI.IntroduceFieldFailed_TargetIsAlreadyAField, + return string.Format(RefactoringsUI.IntroduceFieldFailed_TargetIsAlreadyAField, isAlreadyAField.TargetDeclaration.QualifiedName); case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedModuleName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.Variable); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveCloserToUsageFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveCloserToUsageFailedNotifier.cs index e8e6bcdfe6..0527cf93e4 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveCloserToUsageFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveCloserToUsageFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Refactorings.Exceptions.MoveCloserToUsage; @@ -11,7 +12,7 @@ public MoveCloserToUsageFailedNotifier(IMessageBox messageBox) : base(messageBox) {} - protected override string Caption => Resources.RubberduckUI.MoveCloserToUsage_Caption; + protected override string Caption => RefactoringsUI.MoveCloserToUsage_Caption; protected override string Message(RefactoringException exception) { @@ -19,32 +20,32 @@ protected override string Message(RefactoringException exception) { case TargetDeclarationConflictsWithPreexistingDeclaration conflictWithPreexistingDeclaration: Logger.Warn(conflictWithPreexistingDeclaration); - return string.Format(Resources.RubberduckUI.MoveCloserToUsageFailure_ReferencingMethodHasSameNameDeclarationInScope, + return string.Format(RefactoringsUI.MoveCloserToUsageFailure_ReferencingMethodHasSameNameDeclarationInScope, conflictWithPreexistingDeclaration.TargetDeclaration.QualifiedName, conflictWithPreexistingDeclaration.ConflictingDeclaration.QualifiedName); case TargetDeclarationNonPrivateInNonStandardModule nonPrivateInNonStandardModule: Logger.Warn(nonPrivateInNonStandardModule); - return string.Format(Resources.RubberduckUI.MoveCloserToUsageFailure_TargetIsNonPrivateInNonStandardModule, + return string.Format(RefactoringsUI.MoveCloserToUsageFailure_TargetIsNonPrivateInNonStandardModule, nonPrivateInNonStandardModule.TargetDeclaration.QualifiedName); case TargetDeclarationInDifferentNonStandardModuleException inDifferentNonStandardModule: Logger.Warn(inDifferentNonStandardModule); - return string.Format(Resources.RubberduckUI.MoveCloserToUsageFailure_TargetIsInOtherNonStandardModule, + return string.Format(RefactoringsUI.MoveCloserToUsageFailure_TargetIsInOtherNonStandardModule, inDifferentNonStandardModule.TargetDeclaration.QualifiedName); case TargetDeclarationInDifferentProjectThanUses inDifferentProject: Logger.Warn(inDifferentProject); - return string.Format(Resources.RubberduckUI.MoveCloserToUsageFailure_TargetIsInDifferentProject, + return string.Format(RefactoringsUI.MoveCloserToUsageFailure_TargetIsInDifferentProject, inDifferentProject.TargetDeclaration.QualifiedName); case TargetDeclarationUsedInMultipleMethodsException usedInMultiple: Logger.Warn(usedInMultiple); - return string.Format(Resources.RubberduckUI.MoveCloserToUsageFailure_TargetIsUsedInMultipleMethods, + return string.Format(RefactoringsUI.MoveCloserToUsageFailure_TargetIsUsedInMultipleMethods, usedInMultiple.TargetDeclaration.QualifiedName); case TargetDeclarationNotUserDefinedException notUsed: Logger.Warn(notUsed); - return string.Format(Resources.RubberduckUI.MoveCloserToUsageFailure_TargetHasNoReferences, + return string.Format(RefactoringsUI.MoveCloserToUsageFailure_TargetHasNoReferences, notUsed.TargetDeclaration.QualifiedName); case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.Variable); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveContainingFolderRefactoringFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveContainingFolderRefactoringFailedNotifier.cs index d2c4e084bb..2442d8f0bd 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveContainingFolderRefactoringFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveContainingFolderRefactoringFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Refactorings.Exceptions.MoveToFolder; @@ -11,7 +12,7 @@ public MoveContainingFolderRefactoringFailedNotifier(IMessageBox messageBox) : base(messageBox) {} - protected override string Caption => Resources.RubberduckUI.MoveFoldersDialog_Caption; + protected override string Caption => RefactoringsUI.MoveFoldersDialog_Caption; protected override string Message(RefactoringException exception) { @@ -20,12 +21,12 @@ protected override string Message(RefactoringException exception) case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); return string.Format( - Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.Module); case NoTargetFolderException noTargetFolder: - return Resources.RubberduckUI.RefactoringFailure_NoTargetFolder; + return RefactoringsUI.RefactoringFailure_NoTargetFolder; default: return base.Message(exception); } diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveToFolderRefactoringFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveToFolderRefactoringFailedNotifier.cs index b674a64c84..3126cda3a7 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveToFolderRefactoringFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/MoveToFolderRefactoringFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Refactorings.Exceptions.MoveToFolder; @@ -11,7 +12,7 @@ public MoveToFolderRefactoringFailedNotifier(IMessageBox messageBox) : base(messageBox) {} - protected override string Caption => Resources.RubberduckUI.MoveToFolderDialog_Caption; + protected override string Caption => RefactoringsUI.MoveToFolderDialog_Caption; protected override string Message(RefactoringException exception) { @@ -20,12 +21,12 @@ protected override string Message(RefactoringException exception) case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); return string.Format( - Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.Module); case NoTargetFolderException noTargetFolder: - return Resources.RubberduckUI.RefactoringFailure_NoTargetFolder; + return RefactoringsUI.RefactoringFailure_NoTargetFolder; default: return base.Message(exception); } diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/IntroduceParameterFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/PromoteToParameterFailedNotifier.cs similarity index 68% rename from Rubberduck.Core/UI/Command/Refactorings/Notifiers/IntroduceParameterFailedNotifier.cs rename to Rubberduck.Core/UI/Command/Refactorings/Notifiers/PromoteToParameterFailedNotifier.cs index 3abcc6cb02..ab78ff3a17 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/IntroduceParameterFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/PromoteToParameterFailedNotifier.cs @@ -1,18 +1,19 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; -using Rubberduck.Refactorings.Exceptions.IntroduceParameter; +using Rubberduck.Refactorings.Exceptions.PromoteToParameter; using Rubberduck.CodeAnalysis.Inspections.Extensions; namespace Rubberduck.UI.Command.Refactorings.Notifiers { - public class IntroduceParameterFailedNotifier : RefactoringFailureNotifierBase + public class PromoteToParameterFailedNotifier : RefactoringFailureNotifierBase { - public IntroduceParameterFailedNotifier(IMessageBox messageBox) + public PromoteToParameterFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => Resources.RubberduckUI.IntroduceParameter_Caption; + protected override string Caption => RefactoringsUI.PromoteToParameter_Caption; protected override string Message(RefactoringException exception) { @@ -20,11 +21,11 @@ protected override string Message(RefactoringException exception) { case TargetDeclarationIsNotContainedInAMethodException targetNotInMethod: Logger.Warn(targetNotInMethod); - return string.Format(Resources.RubberduckUI.IntroduceParameterFailed_TargetNotContainedInMethod, + return string.Format(RefactoringsUI.PromoteToParameterFailed_TargetNotContainedInMethod, targetNotInMethod.TargetDeclaration.QualifiedName); case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedModuleName, invalidDeclarationType.TargetDeclaration.DeclarationType.ToLocalizedString(), DeclarationType.Variable.ToLocalizedString()); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RefactoringFailureNotifierBase.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RefactoringFailureNotifierBase.cs index 5ce8c70e89..ff3475b67c 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RefactoringFailureNotifierBase.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RefactoringFailureNotifierBase.cs @@ -1,6 +1,7 @@ using System; using NLog; using Rubberduck.Interaction; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; namespace Rubberduck.UI.Command.Refactorings.Notifiers @@ -22,7 +23,7 @@ protected RefactoringFailureNotifierBase(IMessageBox messageBox) public void Notify(RefactoringException exception) { - var message = $"{Resources.RubberduckUI.RefactoringFailure_BaseMessage}{Environment.NewLine}{Environment.NewLine}{Message(exception)}"; + var message = $"{RefactoringsUI.RefactoringFailure_BaseMessage}{Environment.NewLine}{Environment.NewLine}{Message(exception)}"; _messageBox.NotifyWarn(message, Caption); } @@ -32,21 +33,21 @@ protected virtual string Message(RefactoringException exception) { case NoActiveSelectionException noActiveSelection: Logger.Error(noActiveSelection); - return Resources.RubberduckUI.RefactoringFailure_NoActiveSelection; + return RefactoringsUI.RefactoringFailure_NoActiveSelection; case NoDeclarationForSelectionException noDeclarationForSelection: Logger.Warn(noDeclarationForSelection); - return Resources.RubberduckUI.RefactoringFailure_NoTargetDeclarationForSelection; + return RefactoringsUI.RefactoringFailure_NoTargetDeclarationForSelection; case TargetDeclarationIsNullException targetNull: Logger.Error(targetNull); - return Resources.RubberduckUI.RefactoringFailure_TargetNull; + return RefactoringsUI.RefactoringFailure_TargetNull; case TargetDeclarationNotUserDefinedException targetBuiltIn: - return string.Format(Resources.RubberduckUI.RefactoringFailure_TargetNotUserDefined, targetBuiltIn.TargetDeclaration.QualifiedName); + return string.Format(RefactoringsUI.RefactoringFailure_TargetNotUserDefined, targetBuiltIn.TargetDeclaration.QualifiedName); case SuspendParserFailureException suspendParserFailure: Logger.Warn(suspendParserFailure); - return Resources.RubberduckUI.RefactoringFailure_SuspendParserFailure; + return RefactoringsUI.RefactoringFailure_SuspendParserFailure; case AffectedModuleIsStaleException affectedModuleIsStale: return string.Format( - Resources.RubberduckUI.RefactoringFailure_AffectedModuleIsStale, + RefactoringsUI.RefactoringFailure_AffectedModuleIsStale, affectedModuleIsStale.StaleModule.ToString()); default: Logger.Error(exception); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RemoveParameterFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RemoveParameterFailedNotifier.cs index 60e76e403c..60da91b81e 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RemoveParameterFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RemoveParameterFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; namespace Rubberduck.UI.Command.Refactorings.Notifiers @@ -10,7 +11,7 @@ public RemoveParameterFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => Resources.RubberduckUI.RemoveParamsDialog_Caption; + protected override string Caption => RefactoringsUI.RemoveParamsDialog_Caption; protected override string Message(RefactoringException exception) { @@ -18,7 +19,7 @@ protected override string Message(RefactoringException exception) { case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType, invalidDeclarationType.TargetDeclaration.QualifiedModuleName, invalidDeclarationType.TargetDeclaration.DeclarationType, DeclarationType.Parameter); diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFailedNotifier.cs index 177eb70c93..619a49fe5e 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFailedNotifier.cs @@ -1,4 +1,5 @@ using Rubberduck.Interaction; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; using Rubberduck.Refactorings.Exceptions.Rename; @@ -10,7 +11,7 @@ public RenameFailedNotifier(IMessageBox messageBox) : base(messageBox) {} - protected override string Caption => Resources.RubberduckUI.RenameDialog_Caption; + protected override string Caption => RefactoringsUI.RenameDialog_Caption; protected override string Message(RefactoringException exception) { @@ -18,12 +19,12 @@ protected override string Message(RefactoringException exception) { case CodeModuleNotFoundException codeModuleNotFound: Logger.Warn(codeModuleNotFound); - return string.Format(Resources.RubberduckUI.RenameFailure_TargetModuleWithoutCodeModule, codeModuleNotFound.TargetDeclaration.QualifiedModuleName); + return string.Format(RefactoringsUI.RenameFailure_TargetModuleWithoutCodeModule, codeModuleNotFound.TargetDeclaration.QualifiedModuleName); case TargetControlNotFoundException controlNotFound: Logger.Warn(controlNotFound); - return string.Format(Resources.RubberduckUI.RenameFailure_TargetControlNotFound, controlNotFound.TargetDeclaration.QualifiedName); + return string.Format(RefactoringsUI.RenameFailure_TargetControlNotFound, controlNotFound.TargetDeclaration.QualifiedName); case TargetDeclarationIsStandardEventHandlerException standardHandler: - return string.Format(Resources.RubberduckUI.RenameFailure_StandardEventHandler, standardHandler.TargetDeclaration.QualifiedName); + return string.Format(RefactoringsUI.RenameFailure_StandardEventHandler, standardHandler.TargetDeclaration.QualifiedName); default: return base.Message(exception); } diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFolderFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFolderFailedNotifier.cs index 96f321ff61..7751e612a8 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFolderFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/RenameFolderFailedNotifier.cs @@ -1,4 +1,5 @@ using Rubberduck.Interaction; +using Rubberduck.Refactorings; namespace Rubberduck.UI.Command.Refactorings.Notifiers { @@ -8,6 +9,6 @@ public RenameFolderFailedNotifier(IMessageBox messageBox) : base(messageBox) {} - protected override string Caption => Resources.RubberduckUI.RenameDialog_Caption; + protected override string Caption => RefactoringsUI.RenameDialog_Caption; } } \ No newline at end of file diff --git a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ReorderParametersFailedNotifier.cs b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ReorderParametersFailedNotifier.cs index c64ca6f36a..5193c9275f 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ReorderParametersFailedNotifier.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/Notifiers/ReorderParametersFailedNotifier.cs @@ -1,5 +1,6 @@ using Rubberduck.Interaction; using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; using Rubberduck.Refactorings.Exceptions; namespace Rubberduck.UI.Command.Refactorings.Notifiers @@ -10,7 +11,7 @@ public ReorderParametersFailedNotifier(IMessageBox messageBox) : base(messageBox) { } - protected override string Caption => Resources.RubberduckUI.ReorderParamsDialog_Caption; + protected override string Caption => RefactoringsUI.ReorderParamsDialog_Caption; protected override string Message(RefactoringException exception) { @@ -18,7 +19,7 @@ protected override string Message(RefactoringException exception) { case InvalidDeclarationTypeException invalidDeclarationType: Logger.Warn(invalidDeclarationType); - return string.Format(Resources.RubberduckUI.RefactoringFailure_InvalidDeclarationType_multipleValid, + return string.Format(RefactoringsUI.RefactoringFailure_InvalidDeclarationType_multipleValid, invalidDeclarationType.TargetDeclaration.QualifiedModuleName, invalidDeclarationType.TargetDeclaration.DeclarationType, $"{DeclarationType.Member}, {DeclarationType.Event}"); diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractMethodCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractMethodCommand.cs index cda68c02c2..f5a6e2f61e 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractMethodCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractMethodCommand.cs @@ -1,109 +1,51 @@ -using System; -using System.Runtime.InteropServices; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.ExtractMethod; -using Rubberduck.SmartIndenter; -using Rubberduck.VBEditor; -using System.Collections.Generic; -using System.Windows.Forms; -using Rubberduck.Parsing.Common; -using Rubberduck.Resources; -using Rubberduck.VBEditor.SafeComWrappers.Abstract; +using Rubberduck.UI.Command.Refactorings.Notifiers; +using Rubberduck.VBEditor.Utility; namespace Rubberduck.UI.Command.Refactorings { - [Disabled] - [ComVisible(false)] - public class RefactorExtractMethodCommand : CommandBase + public class RefactorExtractMethodCommand : RefactorCodePaneCommandBase { private readonly RubberduckParserState _state; - private readonly IIndenter _indenter; - private readonly IVBE _vbe; - - public RefactorExtractMethodCommand(IVBE vbe, RubberduckParserState state, IIndenter indenter) + private readonly ISelectedDeclarationProvider _selectedDeclarationProvider; + private readonly ISelectionProvider _selectionProvider; + + public RefactorExtractMethodCommand( + ExtractMethodRefactoring refactoring, + ExtractMethodFailedNotifier failureNotifier, + RubberduckParserState state, + ISelectionProvider selectionProvider, + ISelectedDeclarationProvider selectedDeclarationProvider) + : base(refactoring, failureNotifier, selectionProvider, state) { _state = state; - _indenter = indenter; - _vbe = vbe; - - AddToCanExecuteEvaluation(SpecialEvaluateCanExecute); - } - - private bool SpecialEvaluateCanExecute(object parameter) - { - var qualifiedSelection = _vbe.GetActiveSelection(); - if (!qualifiedSelection.HasValue) - { - return false; - } - if (_state.IsNewOrModified(qualifiedSelection.Value.QualifiedName)) - { - return false; - } - - var allDeclarations = _state.AllDeclarations; - var extractMethodValidation = new ExtractMethodSelectionValidation(allDeclarations); - - var canExecute = extractMethodValidation.withinSingleProcedure(qualifiedSelection.Value); + _selectedDeclarationProvider = selectedDeclarationProvider; + _selectionProvider = selectionProvider; - return canExecute; + AddToCanExecuteEvaluation(SpecializedEvaluateCanExecute); } - - protected override void OnExecute(object parameter) + private bool SpecializedEvaluateCanExecute(object parameter) { - var declarations = _state.AllDeclarations; - var qualifiedSelection = _vbe.GetActiveSelection(); + var member = _selectedDeclarationProvider.SelectedDeclaration(); + //var moduleContext = _selectedDeclarationProvider.SelectedModule().Context; + var moduleName = _selectedDeclarationProvider.SelectedModule().QualifiedModuleName; - var extractMethodValidation = new ExtractMethodSelectionValidation(declarations); - var canExecute = extractMethodValidation.withinSingleProcedure(qualifiedSelection.Value); - if (!canExecute) + if (member == null || _state.IsNewOrModified(member.QualifiedModuleName) || !_selectionProvider.Selection(moduleName).HasValue) { - return; + return false; } - using (var pane = _vbe.ActiveCodePane) - using (var module = pane.CodeModule) - { - var extraction = new ExtractMethodExtraction(); - // bug: access to disposed closure - - // todo: make ExtractMethodRefactoring request reparse like everyone else. - var refactoring = new ExtractMethodRefactoring(module, ParseRequest, CreateMethodModel, extraction); - refactoring.InvalidSelection += HandleInvalidSelection; - refactoring.Refactor(); - - - void ParseRequest(object obj) => _state.OnParseRequested(obj); + return true; + //var parameters = _state.DeclarationFinder + // .UserDeclarations(DeclarationType.Parameter) + // .Where(item => member.Equals(item.ParentScopeDeclaration)) + // .ToList(); - IExtractMethodModel CreateMethodModel(QualifiedSelection? qs, string code) - { - if (qs == null) - { - return null; - } - //TODO: Pull these even further back; - // and implement with IProvider - var rules = new List - { - new ExtractMethodRuleInSelection(), - new ExtractMethodRuleIsAssignedInSelection(), - new ExtractMethodRuleUsedAfter(), - new ExtractMethodRuleUsedBefore() - }; - - var paramClassify = new ExtractMethodParameterClassification(rules); - - var extractedMethod = new ExtractedMethod(); - var extractedMethodModel = new ExtractMethodModel(extractedMethod, paramClassify); - extractedMethodModel.extract(declarations, qs.Value, code); - return extractedMethodModel; - } - } - } - - private void HandleInvalidSelection(object sender, EventArgs e) - { - MessageBox.Show(RubberduckUI.ExtractMethod_InvalidSelectionMessage, RubberduckUI.ExtractMethod_Caption, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + //return member.DeclarationType == DeclarationType.PropertyLet + // || member.DeclarationType == DeclarationType.PropertySet + // ? parameters.Count > 2 + // : parameters.Count > 1; } } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceParameterCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorPromoteToParameterCommand.cs similarity index 84% rename from Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceParameterCommand.cs rename to Rubberduck.Core/UI/Command/Refactorings/RefactorPromoteToParameterCommand.cs index d1d4ad93e6..6f78098db6 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceParameterCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorPromoteToParameterCommand.cs @@ -1,19 +1,19 @@ using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; -using Rubberduck.Refactorings.IntroduceParameter; +using Rubberduck.Refactorings.PromoteToParameter; using Rubberduck.UI.Command.Refactorings.Notifiers; using Rubberduck.VBEditor.Utility; namespace Rubberduck.UI.Command.Refactorings { - public class RefactorIntroduceParameterCommand : RefactorCodePaneCommandBase + public class RefactorPromoteToParameterCommand : RefactorCodePaneCommandBase { private readonly RubberduckParserState _state; private readonly ISelectedDeclarationProvider _selectedDeclarationProvider; - public RefactorIntroduceParameterCommand ( - IntroduceParameterRefactoring refactoring, - IntroduceParameterFailedNotifier introduceParameterFailedNotifier, + public RefactorPromoteToParameterCommand ( + PromoteToParameterRefactoring refactoring, + PromoteToParameterFailedNotifier introduceParameterFailedNotifier, RubberduckParserState state, ISelectionProvider selectionProvider, ISelectedDeclarationProvider selectedDeclarationProvider) diff --git a/Rubberduck.Core/UI/Command/VersionCheckCommand.cs b/Rubberduck.Core/UI/Command/VersionCheckCommand.cs index ba40ee7dae..ed6fd27e6c 100644 --- a/Rubberduck.Core/UI/Command/VersionCheckCommand.cs +++ b/Rubberduck.Core/UI/Command/VersionCheckCommand.cs @@ -5,6 +5,7 @@ using Rubberduck.Resources; using Rubberduck.SettingsProvider; using Rubberduck.Settings; +using System.Threading; namespace Rubberduck.UI.Command { @@ -27,12 +28,12 @@ public void Start(string fileName) public class VersionCheckCommand : CommandBase { - private readonly IVersionCheck _versionCheck; + private readonly IVersionCheckService _versionCheck; private readonly IMessageBox _prompt; private readonly IExternalProcess _process; IConfigurationService _config; - public VersionCheckCommand(IVersionCheck versionCheck, IMessageBox prompt, IExternalProcess process, IConfigurationService config) + public VersionCheckCommand(IVersionCheckService versionCheck, IMessageBox prompt, IExternalProcess process, IConfigurationService config) { _versionCheck = versionCheck; _prompt = prompt; @@ -43,14 +44,47 @@ public VersionCheckCommand(IVersionCheck versionCheck, IMessageBox prompt, IExte protected override async void OnExecute(object parameter) { var settings = _config.Read().UserSettings.GeneralSettings; + if (_versionCheck.IsDebugBuild) + { + Logger.Info("Version check skipped for debug build."); + return; + } + Logger.Info("Executing version check..."); + + var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)); await _versionCheck - .GetLatestVersionAsync(settings) + .GetLatestVersionAsync(settings, tokenSource.Token) .ContinueWith(t => { + if (t.IsFaulted) + { + Logger.Warn(t.Exception); + return; + } + if (_versionCheck.CurrentVersion < t.Result) { - PromptAndBrowse(t.Result, settings.IncludePreRelease); + var proceed = true; + if (_versionCheck.IsDebugBuild || !settings.IncludePreRelease) + { + // if the latest version has a revision number and isn't a pre-release build, + // avoid prompting since we can't know if the build already includes the latest version. + proceed = t.Result.Revision == 0; + } + + if (proceed) + { + PromptAndBrowse(t.Result, settings.IncludePreRelease); + } + else + { + Logger.Info("Version check skips notification of an existing newer version available."); + } + } + else + { + Logger.Info("Version check completed: running current latest."); } }); } diff --git a/Rubberduck.Core/UI/Controls/BusyIndicator.xaml b/Rubberduck.Core/UI/Controls/BusyIndicator.xaml index cec9e023b2..cabaf9c198 100644 --- a/Rubberduck.Core/UI/Controls/BusyIndicator.xaml +++ b/Rubberduck.Core/UI/Controls/BusyIndicator.xaml @@ -43,31 +43,31 @@ - + - + - + - + - + - + - + - + - + diff --git a/Rubberduck.Core/UI/Controls/CloseButton.xaml b/Rubberduck.Core/UI/Controls/CloseButton.xaml new file mode 100644 index 0000000000..feb6d11a29 --- /dev/null +++ b/Rubberduck.Core/UI/Controls/CloseButton.xaml @@ -0,0 +1,16 @@ + diff --git a/Rubberduck.Core/UI/Controls/CloseButton.xaml.cs b/Rubberduck.Core/UI/Controls/CloseButton.xaml.cs new file mode 100644 index 0000000000..e425d551c7 --- /dev/null +++ b/Rubberduck.Core/UI/Controls/CloseButton.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Rubberduck.UI.Controls +{ + /// + /// Interaction logic for CloseButton.xaml + /// + public partial class CloseButton : Button + { + public CloseButton() + { + InitializeComponent(); + } + } +} diff --git a/Rubberduck.Core/UI/Controls/DeclarationTypeToStringConverter.cs b/Rubberduck.Core/UI/Controls/DeclarationTypeToStringConverter.cs index 50af44aca7..031f17001c 100644 --- a/Rubberduck.Core/UI/Controls/DeclarationTypeToStringConverter.cs +++ b/Rubberduck.Core/UI/Controls/DeclarationTypeToStringConverter.cs @@ -1,8 +1,8 @@ using System; using System.Globalization; using System.Windows.Data; +using Rubberduck.CodeAnalysis; using Rubberduck.Parsing.Symbols; -using Rubberduck.Resources; namespace Rubberduck.UI.Controls { @@ -12,7 +12,7 @@ public object Convert(object value, Type targetType, object parameter, CultureIn { if (value is DeclarationType type) { - var text = RubberduckUI.ResourceManager.GetString("DeclarationType_" + type, CultureInfo.CurrentUICulture) ?? string.Empty; + var text = CodeAnalysisUI.ResourceManager.GetString("DeclarationType_" + type, CultureInfo.CurrentUICulture) ?? string.Empty; return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(text); } diff --git a/Rubberduck.Core/UI/Controls/EmptyUIRefresh.xaml b/Rubberduck.Core/UI/Controls/EmptyUIRefresh.xaml index 49709a5844..df0ff40823 100644 --- a/Rubberduck.Core/UI/Controls/EmptyUIRefresh.xaml +++ b/Rubberduck.Core/UI/Controls/EmptyUIRefresh.xaml @@ -14,13 +14,13 @@ - + - + + + + + diff --git a/Rubberduck.Core/UI/Refactorings/ExtractMethod/ExtractMethodView.xaml.cs b/Rubberduck.Core/UI/Refactorings/ExtractMethod/ExtractMethodView.xaml.cs new file mode 100644 index 0000000000..95f0fdb738 --- /dev/null +++ b/Rubberduck.Core/UI/Refactorings/ExtractMethod/ExtractMethodView.xaml.cs @@ -0,0 +1,16 @@ +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.ExtractMethod; + +namespace Rubberduck.UI.Refactorings.ExtractMethod +{ + /// + /// Interaction logic for ExtractMethodView.xaml + /// + public partial class ExtractMethodView : IRefactoringView + { + public ExtractMethodView() + { + InitializeComponent(); + } + } +} diff --git a/Rubberduck.Core/UI/Refactorings/ExtractMethod/ExtractMethodViewModel.cs b/Rubberduck.Core/UI/Refactorings/ExtractMethod/ExtractMethodViewModel.cs new file mode 100644 index 0000000000..0d09ad27a9 --- /dev/null +++ b/Rubberduck.Core/UI/Refactorings/ExtractMethod/ExtractMethodViewModel.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using Rubberduck.Interaction; +using Rubberduck.Parsing.Grammar; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.ExtractMethod; + +namespace Rubberduck.UI.Refactorings.ExtractMethod +{ + public class ExtractMethodViewModel : RefactoringViewModelBase + { + private readonly IMessageBox _messageBox; + + public RubberduckParserState State { get; } + + public ExtractMethodViewModel(RubberduckParserState state, ExtractMethodModel model, IMessageBox messageBox) + : base(model) + { + State = state; + _messageBox = messageBox; + //_model = model; + } + + private bool _wired; + public ObservableCollection Parameters + { + get + { + if (!_wired) + { + WireParameterEvents(); + } + return Model.Parameters; + } + set + { + Model.Parameters = value; + WireParameterEvents(); + OnPropertyChanged(nameof(PreviewCode)); + OnPropertyChanged(nameof(ReturnParameters)); + OnPropertyChanged(nameof(ReturnParameter)); + } + } + + private void WireParameterEvents() + { + foreach (var parameter in Model.Parameters) + { + parameter.PropertyChanged += Parameter_PropertyChanged; + } + _wired = true; + } + + private void Parameter_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + OnPropertyChanged(nameof(PreviewCode)); + } + + public IEnumerable ComponentNames => Model.ComponentNames; + + public string NewMethodName + { + get => Model.NewMethodName; + set + { + Model.NewMethodName = value; + OnPropertyChanged(); + OnPropertyChanged(nameof(IsValidMethodName)); + OnPropertyChanged(nameof(PreviewCode)); + } + } + + public IEnumerable ReturnParameters => + new[] + { + ExtractMethodParameter.None + }.Union(Parameters.Where(p => p.CanReturn)); + + public ExtractMethodParameter ReturnParameter + { + get => Model.ReturnParameter ?? ExtractMethodParameter.None; + set + { + Model.ReturnParameter = value ?? ExtractMethodParameter.None; + OnPropertyChanged(nameof(PreviewCode)); + } + } + + public string SourceMethodName => Model.SourceMethodName; + public string PreviewCaption => string.Format(RefactoringsUI.ExtractMethod_CodePreviewCaption, SourceMethodName); + public string PreviewCode => Model.NewMethodCode; //Model.ReplacementCode + Environment.NewLine + Model.PreviewCode; //any way to get a divider for showing both sections of code in one textbox? + public IEnumerable Inputs; + public IEnumerable Outputs; + public IEnumerable Locals; + public IEnumerable ReturnValues; + public Accessibility Accessibility; + + public bool IsValidMethodName + { + get + { + var tokenValues = typeof(Tokens).GetFields().Select(item => item.GetValue(null)).Cast().Select(item => item); + return !string.IsNullOrWhiteSpace(NewMethodName) + && char.IsLetter(NewMethodName.FirstOrDefault()) + && !NewMethodName.Any(c => !char.IsLetterOrDigit(c) && c != '_') + && !ComponentNames.Contains(NewMethodName, StringComparer.InvariantCultureIgnoreCase) + && !tokenValues.Contains(NewMethodName, StringComparer.InvariantCultureIgnoreCase); + } + } + + public bool DisplayCompilationConstantWarning => !Model.ModuleContainsCompilationDirectives; + + protected override void DialogOk() + { + base.DialogOk(); + } + } +} diff --git a/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.Designer.cs b/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.Designer.cs deleted file mode 100644 index b02cb2c203..0000000000 --- a/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.Designer.cs +++ /dev/null @@ -1,279 +0,0 @@ -using System.ComponentModel; -using System.Windows.Forms; - -namespace Rubberduck.UI.Refactorings -{ - partial class ExtractMethodDialog - { - /// - /// Required designer variable. - /// - private IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ExtractMethodDialog)); - this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); - this.CancelDialogButton = new System.Windows.Forms.Button(); - this.OkButton = new System.Windows.Forms.Button(); - this.panel2 = new System.Windows.Forms.Panel(); - this.TitleLabel = new System.Windows.Forms.Label(); - this.InstructionsLabel = new System.Windows.Forms.Label(); - this.panel1 = new System.Windows.Forms.Panel(); - this.InvalidNameValidationIcon = new System.Windows.Forms.PictureBox(); - this.PreviewBox = new System.Windows.Forms.TextBox(); - this.PreviewLabel = new System.Windows.Forms.Label(); - this.MethodParametersGrid = new System.Windows.Forms.DataGridView(); - this.ParametersLabel = new System.Windows.Forms.Label(); - this.MethodAccessibilityCombo = new System.Windows.Forms.ComboBox(); - this.AccessibilityLabel = new System.Windows.Forms.Label(); - this.MethodNameBox = new System.Windows.Forms.TextBox(); - this.NameLabel = new System.Windows.Forms.Label(); - this.flowLayoutPanel2.SuspendLayout(); - this.panel2.SuspendLayout(); - this.panel1.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.InvalidNameValidationIcon)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.MethodParametersGrid)).BeginInit(); - this.SuspendLayout(); - // - // flowLayoutPanel2 - // - this.flowLayoutPanel2.BackColor = System.Drawing.SystemColors.ControlDark; - this.flowLayoutPanel2.Controls.Add(this.CancelDialogButton); - this.flowLayoutPanel2.Controls.Add(this.OkButton); - this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Bottom; - this.flowLayoutPanel2.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft; - this.flowLayoutPanel2.Location = new System.Drawing.Point(0, 438); - this.flowLayoutPanel2.Name = "flowLayoutPanel2"; - this.flowLayoutPanel2.Padding = new System.Windows.Forms.Padding(8, 8, 0, 8); - this.flowLayoutPanel2.Size = new System.Drawing.Size(600, 43); - this.flowLayoutPanel2.TabIndex = 1; - // - // CancelDialogButton - // - this.CancelDialogButton.BackColor = System.Drawing.SystemColors.ButtonFace; - this.CancelDialogButton.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.CancelDialogButton.Location = new System.Drawing.Point(514, 11); - this.CancelDialogButton.Name = "CancelDialogButton"; - this.CancelDialogButton.Size = new System.Drawing.Size(75, 23); - this.CancelDialogButton.TabIndex = 4; - this.CancelDialogButton.Text = "Cancel"; - this.CancelDialogButton.UseVisualStyleBackColor = false; - // - // OkButton - // - this.OkButton.BackColor = System.Drawing.SystemColors.ButtonFace; - this.OkButton.DialogResult = System.Windows.Forms.DialogResult.OK; - this.OkButton.Location = new System.Drawing.Point(433, 11); - this.OkButton.Name = "OkButton"; - this.OkButton.Size = new System.Drawing.Size(75, 23); - this.OkButton.TabIndex = 3; - this.OkButton.Text = "Ok"; - this.OkButton.UseVisualStyleBackColor = false; - // - // panel2 - // - this.panel2.BackColor = System.Drawing.Color.White; - this.panel2.Controls.Add(this.TitleLabel); - this.panel2.Controls.Add(this.InstructionsLabel); - this.panel2.Dock = System.Windows.Forms.DockStyle.Top; - this.panel2.Location = new System.Drawing.Point(0, 0); - this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(600, 68); - this.panel2.TabIndex = 13; - // - // TitleLabel - // - this.TitleLabel.AutoSize = true; - this.TitleLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.TitleLabel.Location = new System.Drawing.Point(15, 9); - this.TitleLabel.Name = "TitleLabel"; - this.TitleLabel.Padding = new System.Windows.Forms.Padding(2); - this.TitleLabel.Size = new System.Drawing.Size(107, 19); - this.TitleLabel.TabIndex = 2; - this.TitleLabel.Text = "Extract Method"; - // - // InstructionsLabel - // - this.InstructionsLabel.Location = new System.Drawing.Point(15, 24); - this.InstructionsLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); - this.InstructionsLabel.Name = "InstructionsLabel"; - this.InstructionsLabel.Padding = new System.Windows.Forms.Padding(3); - this.InstructionsLabel.Size = new System.Drawing.Size(412, 28); - this.InstructionsLabel.TabIndex = 3; - this.InstructionsLabel.Text = "Please specify method name, return type and/or parameters (if applicable), and ot" + - "her options."; - // - // panel1 - // - this.panel1.Controls.Add(this.InvalidNameValidationIcon); - this.panel1.Controls.Add(this.PreviewBox); - this.panel1.Controls.Add(this.PreviewLabel); - this.panel1.Controls.Add(this.MethodParametersGrid); - this.panel1.Controls.Add(this.ParametersLabel); - this.panel1.Controls.Add(this.MethodAccessibilityCombo); - this.panel1.Controls.Add(this.AccessibilityLabel); - this.panel1.Controls.Add(this.MethodNameBox); - this.panel1.Controls.Add(this.NameLabel); - this.panel1.Location = new System.Drawing.Point(0, 71); - this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(600, 372); - this.panel1.TabIndex = 14; - // - // InvalidNameValidationIcon - // - this.InvalidNameValidationIcon.Image = ((System.Drawing.Image)(resources.GetObject("InvalidNameValidationIcon.Image"))); - this.InvalidNameValidationIcon.Location = new System.Drawing.Point(577, 1); - this.InvalidNameValidationIcon.Name = "InvalidNameValidationIcon"; - this.InvalidNameValidationIcon.Size = new System.Drawing.Size(16, 16); - this.InvalidNameValidationIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.InvalidNameValidationIcon.TabIndex = 10; - this.InvalidNameValidationIcon.TabStop = false; - // - // PreviewBox - // - this.PreviewBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.PreviewBox.BackColor = System.Drawing.Color.White; - this.PreviewBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.PreviewBox.Location = new System.Drawing.Point(18, 206); - this.PreviewBox.Multiline = true; - this.PreviewBox.Name = "PreviewBox"; - this.PreviewBox.ReadOnly = true; - this.PreviewBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.PreviewBox.Size = new System.Drawing.Size(570, 148); - this.PreviewBox.TabIndex = 9; - this.PreviewBox.TabStop = false; - this.PreviewBox.WordWrap = false; - // - // PreviewLabel - // - this.PreviewLabel.AutoSize = true; - this.PreviewLabel.Location = new System.Drawing.Point(15, 190); - this.PreviewLabel.Name = "PreviewLabel"; - this.PreviewLabel.Size = new System.Drawing.Size(48, 13); - this.PreviewLabel.TabIndex = 8; - this.PreviewLabel.Text = "Preview:"; - // - // MethodParametersGrid - // - this.MethodParametersGrid.AllowUserToAddRows = false; - this.MethodParametersGrid.AllowUserToDeleteRows = false; - this.MethodParametersGrid.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); - this.MethodParametersGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; - this.MethodParametersGrid.Location = new System.Drawing.Point(18, 82); - this.MethodParametersGrid.Margin = new System.Windows.Forms.Padding(8, 3, 8, 3); - this.MethodParametersGrid.Name = "MethodParametersGrid"; - this.MethodParametersGrid.Size = new System.Drawing.Size(570, 97); - this.MethodParametersGrid.TabIndex = 2; - // - // ParametersLabel - // - this.ParametersLabel.AutoSize = true; - this.ParametersLabel.Location = new System.Drawing.Point(15, 66); - this.ParametersLabel.Name = "ParametersLabel"; - this.ParametersLabel.Size = new System.Drawing.Size(63, 13); - this.ParametersLabel.TabIndex = 6; - this.ParametersLabel.Text = "Parameters:"; - // - // MethodAccessibilityCombo - // - this.MethodAccessibilityCombo.FormattingEnabled = true; - this.MethodAccessibilityCombo.Location = new System.Drawing.Point(430, 34); - this.MethodAccessibilityCombo.Name = "MethodAccessibilityCombo"; - this.MethodAccessibilityCombo.Size = new System.Drawing.Size(155, 21); - this.MethodAccessibilityCombo.TabIndex = 1; - // - // AccessibilityLabel - // - this.AccessibilityLabel.AutoSize = true; - this.AccessibilityLabel.Location = new System.Drawing.Point(356, 37); - this.AccessibilityLabel.Name = "AccessibilityLabel"; - this.AccessibilityLabel.Size = new System.Drawing.Size(67, 13); - this.AccessibilityLabel.TabIndex = 4; - this.AccessibilityLabel.Text = "Accessibility:"; - // - // MethodNameBox - // - this.MethodNameBox.Location = new System.Drawing.Point(83, 7); - this.MethodNameBox.Name = "MethodNameBox"; - this.MethodNameBox.Size = new System.Drawing.Size(501, 20); - this.MethodNameBox.TabIndex = 0; - // - // NameLabel - // - this.NameLabel.AutoSize = true; - this.NameLabel.Location = new System.Drawing.Point(15, 10); - this.NameLabel.Name = "NameLabel"; - this.NameLabel.Size = new System.Drawing.Size(38, 13); - this.NameLabel.TabIndex = 0; - this.NameLabel.Text = "Name:"; - // - // ExtractMethodDialog - // - this.AcceptButton = this.OkButton; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.CancelDialogButton; - this.ClientSize = new System.Drawing.Size(600, 481); - this.Controls.Add(this.panel1); - this.Controls.Add(this.panel2); - this.Controls.Add(this.flowLayoutPanel2); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.MaximizeBox = false; - this.MinimizeBox = false; - this.Name = "ExtractMethodDialog"; - this.ShowInTaskbar = false; - this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.Text = "Rubberduck - Extract Method"; - this.flowLayoutPanel2.ResumeLayout(false); - this.panel2.ResumeLayout(false); - this.panel2.PerformLayout(); - this.panel1.ResumeLayout(false); - this.panel1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.InvalidNameValidationIcon)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.MethodParametersGrid)).EndInit(); - this.ResumeLayout(false); - - } - - #endregion - - private FlowLayoutPanel flowLayoutPanel2; - private Button CancelDialogButton; - private Button OkButton; - private Panel panel2; - private Label TitleLabel; - private Label InstructionsLabel; - private Panel panel1; - private PictureBox InvalidNameValidationIcon; - private TextBox PreviewBox; - private Label PreviewLabel; - private DataGridView MethodParametersGrid; - private Label ParametersLabel; - private ComboBox MethodAccessibilityCombo; - private Label AccessibilityLabel; - private TextBox MethodNameBox; - private Label NameLabel; - } -} diff --git a/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.cs b/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.cs deleted file mode 100644 index 5362bcd856..0000000000 --- a/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Linq; -using System.Reflection; -using System.Windows.Forms; -using Rubberduck.Parsing.Grammar; -using Rubberduck.Parsing.Symbols; -using Rubberduck.Refactorings.ExtractMethod; -using Rubberduck.Resources; -using Tokens = Rubberduck.Resources.Tokens; - -namespace Rubberduck.UI.Refactorings -{ - public partial class ExtractMethodDialog : Form, IExtractMethodDialog - { - public ExtractMethodDialog() - { - _returnValue = null; - _parameters = new BindingList(); - - InitializeComponent(); - Localize(); - RegisterViewEvents(); - - MethodAccessibilityCombo.DataSource = new[] - { - Accessibility.Private, - Accessibility.Public, - Accessibility.Friend - }.ToList(); - } - - private void Localize() - { - Text = RubberduckUI.ExtractMethod_Caption; - OkButton.Text = RubberduckUI.OK; - CancelDialogButton.Text = RubberduckUI.CancelButtonText; - - TitleLabel.Text = RubberduckUI.ExtractMethod_TitleText; - InstructionsLabel.Text = RubberduckUI.ExtractMethod_InstructionsText; - NameLabel.Text = RubberduckUI.NameLabelText; - AccessibilityLabel.Text = RubberduckUI.ExtractMethod_AccessibilityLabel; - ParametersLabel.Text = RubberduckUI.ExtractMethod_ParametersLabel; - PreviewLabel.Text = RubberduckUI.ExtractMethod_PreviewLabel; - } - - private void InitializeParameterGrid() - { - MethodParametersGrid.AutoGenerateColumns = false; - MethodParametersGrid.Columns.Clear(); - MethodParametersGrid.DataSource = _parameters; - MethodParametersGrid.AlternatingRowsDefaultCellStyle.BackColor = Color.Lavender; - MethodParametersGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect; - - var paramNameColumn = new DataGridViewTextBoxColumn - { - Name = "Name", - DataPropertyName = "Name", - HeaderText = RubberduckUI.Name, - ReadOnly = true - }; - - var paramTypeColumn = new DataGridViewTextBoxColumn - { - Name = "TypeName", - DataPropertyName = "TypeName", - HeaderText = RubberduckUI.Type, - ReadOnly = true - }; - - var paramPassedByColumn = new DataGridViewTextBoxColumn - { - Name = "Passed", - AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill, - HeaderText = RubberduckUI.Passed, - DataPropertyName = "Passed", - ReadOnly = true - }; - - MethodParametersGrid.Columns.AddRange(paramNameColumn, paramTypeColumn, paramPassedByColumn); - } - - private void RegisterViewEvents() - { - MethodNameBox.TextChanged += MethodNameBox_TextChanged; - MethodAccessibilityCombo.SelectedIndexChanged += MethodAccessibilityCombo_SelectedIndexChanged; - } - - public event EventHandler RefreshPreview; - public void OnRefreshPreview() - { - OnViewEvent(RefreshPreview); - } - - private bool _setReturnValue; - - public bool SetReturnValue - { - get { return _setReturnValue; } - set - { - _setReturnValue = value; - OnRefreshPreview(); - } - } - - - - private Accessibility _accessibility; - public Accessibility Accessibility - { - get { return _accessibility; } - set - { - _accessibility = value; - OnRefreshPreview(); - } - } - - private void MethodAccessibilityCombo_SelectedIndexChanged(object sender, EventArgs e) - { - Accessibility = ((Accessibility) MethodAccessibilityCombo.SelectedItem); - } - - private void MethodNameBox_TextChanged(object sender, EventArgs e) - { - ValidateName(); - OnRefreshPreview(); - } - - private void OnViewEvent(EventHandler target, EventArgs args = null) - { - var handler = target; - if (handler == null) - { - return; - } - - handler(this, args ?? EventArgs.Empty); - } - - private string _preview; - public string Preview - { - get { return _preview; } - set - { - _preview = value; - PreviewBox.Text = _preview; - } - } - - private BindingList _parameters; - public IEnumerable Parameters - { - get { return _parameters.Where(p => p.Name != _returnValue?.Name); } - set - { - _parameters = new BindingList(value.ToList()); - InitializeParameterGrid(); - OnRefreshPreview(); - } - } - - private BindingList _returnValues; - public IEnumerable ReturnValues - { - get { return _returnValues; } - set - { - _returnValues = new BindingList(value.ToList()); - //var items = _returnValues.ToArray(); - } - } - - private readonly ExtractedParameter _returnValue; - - public IEnumerable Inputs { get; set; } - public IEnumerable Outputs { get; set; } - public IEnumerable Locals { get; set; } - - public string OldMethodName { get; set; } - - public string MethodName - { - get { return MethodNameBox.Text; } - set - { - MethodNameBox.Text = value; - InvalidNameValidationIcon.Visible = string.IsNullOrWhiteSpace(value); - OnRefreshPreview(); - } - } - - private void ValidateName() - { - OkButton.Enabled = MethodName != OldMethodName - && char.IsLetter(MethodName.FirstOrDefault()) - && !Tokens.IllegalIdentifierNames.Contains(MethodName, StringComparer.InvariantCultureIgnoreCase) - && !MethodName.Any(c => !char.IsLetterOrDigit(c) && c != '_'); - - InvalidNameValidationIcon.Visible = !OkButton.Enabled; - } - - } -} diff --git a/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.resx b/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.resx deleted file mode 100644 index 454658c47e..0000000000 --- a/Rubberduck.Core/UI/Refactorings/ExtractMethodDialog.resx +++ /dev/null @@ -1,392 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m - dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIbSURBVDhPpZI/SBthGMY/jGCyGHNKCAUnQcEhg4LZ - RQgOEl1EOItdlRSXrqVDKWihi0OHFv9EqFptaytRhGqvllCKcLFHS9qSP8NdiWmGDC13mY7X9znjkdB0 - qR/8ct/3vs/z3PflPkFE18L5WRdCPGO2mOdC3NgWIs5sMKkamMfRgwZaeJoFjL3y+ZTPkYhRnp42/8zN - 2b9nZ+1fsmyeDQ0Z6EHzr4CxNx0dakmWrfOZGTJkuQHUfk5NWa/9fhXahoAEtub1KvrkpPVjYoJLRN9i - sQYwvo+PUy4Wszbb2hR4uHQZsMLn+zgwYGijo47wapwODzvUj7NolI77+w14eHkZ8ESIzS/RqKlEIrTT - 0+MIq9UqlUolKhQKlM1mKZ/P09NAgNaCQUr29ZnwuAGP+Z/mt9tvBwfpMBym1c5OSqfTpGkaZTIZyuVy - tMLmRI0X3d02PG7AEi/UkRF7v7eXdrq6aJtF9WZd153aFbuhkA2PG/CIt/M+HDaTkkTJJuZisUjlctnp - gV1JMuFxAxZxcYJB/YTPV29+yWIAc6VScXjH64TPZ8DjBjzgT/LQ41FOQiFrj3cB8x4LP9XAHGY8j/x+ - a7GlRYHHDbjPl+IeX46F1lY1JUnWAYdoLK7ngPnA5gWPR4UWnoaAu8w8N+5w+rLXa6Ta282vgYANMEcN - PWigbRpwm7nFW7vJ52M2mFQNzOPoQfNXwP9D4gLaFyzB2EknBwAAAABJRU5ErkJggg== - - - - - AAABAAMAEBAAAAEAIABoBAAANgAAACAgAAABACAAqBAAAJ4EAAAwMAAAAQAgAKglAABGFQAAKAAAABAA - AAAgAAAAAQAgAAAAAAAABAAAww4AAMMOAAAAAAAAAAAAAAAAAAAAAAAARVhaAENbXQRJUVEoSVNUWElV - V3lJV1mGSVZYfUlVVltIU1QmQGJmA0NdYAAAAAAAAAAAAAAAAAA9cXgATklIAEdYWiZHXmOWQHqF3zmV - p/g1pr3+M63F/zWov/85lqj5QHiD3UdeYpBHWFolWi0mADd+iAAAAAAATkpJAEhVVi1Ea3LLM6zE/yrU - 9v8o3f//J93//yfd//8n3f//KN3//yrT9f80qsH/Q2520kZbXkBZLygAMoyaAENeYhJFZWu0MbTO/yfd - //8o2///KNv//yjb//8o2///KNv//yjb//8o3P//J93//y++2v9DbnbPRltdHkRhZgBIVlhfOpGi9yjb - /v8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8n3f//OJuu/UhWWFxLUVIARl9kqTG3 - 0f8n3f//KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///J97//zSpv/9JVlluTU5OAEVm - bMYuxOL/KNz//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjc//86lKX6SVRVUEtT - VABFZWvBLsLg/yjc//8o3P//J93//yja/f8p2Pv/KNv+/yjb//8o2///KNv//yjd//8uwNz/RGpyxUZY - WhVEY2cAR19jqDC50/8n3v//Lcfm/zaiuP49iJfvP3+L6TuQof4q0/X/KNz//yjc//8syur/QHqG6ERl - a0xNTU0AMZiqAEhYWnU4mKv9N5+0/ENsdMpIWFtwSVFSNUlVV5M7jZ3/Kdj7/yjb//8o3P//LcTi+z6E - j3U+f2cDPIqJAAAAAABGXWA6SF1g1UdcX4BFWVsWS1FTAEdWWDBAe4fkKtHx/yjc//8o2///KNz//zSo - wPs/YXvPRVZkmUZiYCZRSUIAP210CEZcYCNDYGQEQmNnAE1OTgBJVlhmNqK3/yfe//8o2///KdX3/yrS - 9P84ma3/MFmh/yVcw/9BV3HDRmNhIgAAAAAAAAAAAAAAAAAAAABOS0sASFlccDWnvf8n3v//KN3//zSr - wv85lab/K8/t/z9pgP41VpTyQVRv6kdeX1UAAAAAAAAAAAAAAAAAAAAASFhbAEhXWT0+gI3uKtDx/yfe - //8q0/P/LMrq/zWnvv9GYWWyTFdPO0deXC9Aa3IOAAAAAAAAAAAAAAAAAAAAAD1zewA6dn8ER1pdbj98 - iOc1p73/MrDJ/zuOn/ZFY2inRGBkHkdZXAAgtbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQGhtADxx - eQNHVlg6SVdZgUlXWZBIVlhZQmJmDkhUVQAM4fYAAAAAAAAAAADgDwAAwAcAAIADAAAAAQAAAAEAAAAB - AAAAAQAAAAEAAAADAAAAAwAACAEAABgAAAD4AAAA+AAAAPgHAAD8DwAAKAAAACAAAABAAAAAAQAgAAAA - AAAAEAAAww4AAMMOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAhs8kADt3pAi+SoAk9c3sQRGJmFDh+iR1DZGkRMouYDBfJ1gP/AAAAAP//AAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHb3KAAXz - /wE7dn4SQWhuQUZdYHJIWFqdSlNUuUtRUclNTUzNSlJT2ExOTstKU1TASFhbo0RhZXZBaXA9N3+KDwD/ - /wAS1d8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJaq+AAD/ - /wE/bnUiRl1hfUpTVMxLUVH0SVha/0ZmbP9CdX//PoGO/zyIl/88ipn/PYSS/0F4g/9FZ27/SVha/0tR - UfNJVVbFRGFmbzt3fxoA//8AFszZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADWE - kAAwkJ8HQmZsY0pTVNlKVVf+QXaA/zagtf8uv9z/KtDw/ynX+v8o2/7/J9z//yfc//8o2///KNj8/yrR - 8v8uvtv/N5yw/0NweP9LU1T8SVVX0EJnbVwxjZkHOXyGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AABBaW8APXJ7BkhZXHpLUVL2QnF6/zG0zv8p1vn/J93//yjd//8o3P//KNv//yjb//8o2///KNv//yjb - //8o2///KNz//yjd//8n3f//KdP1/zOsxP9DbHT/S1FR9UZdYJA2go4UQGtyAAby/wAAAAAAAAAAAAAA - AAAAAAAAMY2aAB660gRFX2N4TFBQ9j2Ekf8qz+//J93//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o3P//J93//yrO7v87ipr/S1NU/kVeYqs0hpIWOHyHAAAA - AAAAAAAAAAAAACmfsgBPSUgAQWpwUUtRUvA+f4v/KdPz/yjc//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNz//yjY+v85l6n/S1NV/0Vg - ZJEjrsAGMJGdAAAAAAAAAAAAOniCADh+iRhJVlfIRWhu/yvJ6P8o3P//KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNz//yjY - +v88iJf/S1JT8T9tdERFYGUAAP//AAAAAABWOTUAQmZra0tTVP00qL7/J93//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KN3//y3F4v9IXWH/R1tek/8AAAAoorQAAAAAADaBjQxKVFa5RGx0/yrS8v8o3P//KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNj6/0F2gP9JVVfCLpSkCzCRoAAAAAAAPm93NUtRUek5lKb/J93//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///PoOQ/0tQUc0+cHcPPnB4AAAAAABCZWtiSlNV+jGy - y/8n3f//KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yja/v8/f4v/S1FSyjp5gg46eYMAAAAAAEZe - YX5JWVv/LsHe/yjd//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o3P//KdP0/0Rsc/9JVVavJqi8BTGO - nAAAAAAASVVXf0lbXv8txeP/KNz//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yfd//8xtM7/SlVX/0Vf - Y3NYNC8AD9v1AAAAAABFYGR/SVlc/y7B3v8o3f//KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o3P//KdX2/0B5 - g/9KUlPdPnB4Jj9scwAAAAAAAAAAAEZdYGlKVVf8L7vW/yjd//8o2///KNv//yjb//8o2///KNv//yjc - //8o3f//J93//yfd//8n3f//J93//yjc//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - /v83nK//S1FS/EVgZHX/AAAALJmqAAAAAAAAAAAAQ2NoV0tTVPgysMn/J93//yjb//8o2///KNv//yjd - //8o2/3/K83t/zC30v81pLr/OJqt/zebr/80qL//LcLg/yja/v8o2///KNv//yjb//8o2///KNv//yjb - //8o3P//M6zD/0lYWv9EZmvAMputFzaPnwAAAAAAAAAAAAAAAABAanE5S1BR7Decr/8n3f//KNv//yjd - //8p1vf/MbXP/z2GlP9GY2n/SlVX/ktQUfJMT1DoS1BR7U1NTf5FZ23/K8zs/yjc//8o2///KNv//yjb - //8o2///KNz//zGxy/9IW17/R11g0DSYqDZgAAcAE/v/ACjb/wAAAAAAAAAAADp5ghdKUlPPPn+M/yjb - /v8o2vz/MLfR/0B4g/9KVVf+SlJT40hZW6NEYGVjQ2VqOT9scypFYGSeTE9Q/zqOnv8o1/r/KNv//yjb - //8o2///KNv//yjb//8o2///Oo+f/0dhZto7g5A6Vzs+ABXh8gAAAAAAAAAAAAAAAAAAAAAAAP//AkhX - WaBGZWv/LcDd/zqPoP9KV1r/SlNU3UNkaYA7dn8oJ6W4BC+SoQBYMy4AQGtxVEtRUvA+f4v/KdP0/yjc - //8o2///KNv//yjb//8o2///KNv//yjb//8q0/X7K8roeAD//wFPw/kAAP//AAAAAAAAAAAAAAAAAAAA - AABOS0oARGFmZktTVP9HYWb/S1FS9UZdYZ49cXknAP//ASKwwwAAAAAAPnB4ADt3gB5JVVfQRWpx/yvK - 6f8o3P//KNv//yjb//8o2///KNv//yjb//8o2///KNr9/y692fg/e4W4SFpaokZfYn8/bnUtDt37ASao - ugAAAAAAAAAAAD9udQA9cXkvSlRW6kpSVN1DZWpdLZioCDWFkQAAAAAAAAAAACaotgBVOzcARGBldEpV - Vv8yrsb/J93//yjb//8o2///KNv//yjb//8o2///KNv//yjd//8xssv/SVpd/0dPX/9CUW7/SU9a/0pV - VeFBaW9hIbPJBC+TogAAAAAAL5OiAC6VpQZDZGpIQWlwLQD//wAmqLwAAAAAAAAAAAAAAAAAMYybACKw - xgRJVVeuRGxz/ynT9P8o3P//KNv//yjb//8o2///KNv//yjc//8o3P//J93//zGzzP9LUlL/M1aY/xVj - 8v8fX9T/PlJ5/0tTU/JBaG5tFc7pAyyZqQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAyjZsAMouYDUpTVMZAfIf/KNr9/yjb//8o2///KNv//yjb//8o2///KdP1/yvL6/8o2v3/KNf6/z2G - lP9ITlr/IV7N/w9l//8WYu3/OlSE/0pUVe5Aa3FFRl1gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAADSHlAA1hZETSVRW0z+Cj/8o2///KNv//yjb//8o2///KNv//ynW+f8+g5D/R2Fl/zC2 - 0P8n3v//K8zr/0VrcP89Unr/IF7S/yRcxv8tWaz/SU5Y/0ZeYZwA//8BAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAMY6cADGOnQ5JVFbHQXiD/yjZ+/8o2///KNv//yjb//8o2///KdT2/0Jy - e/9MUFH/M6vD/yfd//8n3P7/PYOQ/01LTP9KUFb+TE9R9UtQVPlLUlT9RGJmg9IAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwkJ8A6AAAAEdaXJFIW1//Lr/b/yfd//8o2///KNv//yjb - //8o2///Lcbk/zG10P8p1vj/J93//y+71v9IXWH/SVZY0UNkaG9HXF8/Q2RpSUBsc083gYwTOniCAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBaG4APXJ7O0pUVehBdX//K8vq/yfd - //8o2///KNv//yjb//8o3P//J97//yfd//8vudX/RmZs/0lVVt8+cHg4T0lMAAvn7QAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACmhsQAA//8BRGFlZktQ - UfBDbnb/MbLL/ynU9/8n3P//J93//yjc//8qz/D/N52x/0hdYf9JVVfdPXF5TP8AAAAhs8IAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADp4 - ggAwkJ8DQmZsWklUVthKVVf+Q3B4/zuNnf83maz/O4yb/0Vob/9LUlP6R1pduT1zezX/AAAAHrnJAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAACOutwAA//8AOniCI0VgZHZJVFa8S1BQ3E1MS+BLUFHcSVZXsUJma140h5MRRWBrAAP4 - +QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO3+wAAP//ADOIlAxAanAhTE9QJD9scyAxjpsJUkJJAAvn - +QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/4B///gAD//gAAP/wAAA/4AAAH8AA - AA/AAAAHgAAAB4AAAAcAAAADAAAAAwAAAAMAAAADAAAABwAAAAcAAAAPAAAADwAAAB8AAAA/ADAAP4Dg - AAeD4AADj8AAAf/AAAH/wAAA/8AAAf/gAAH/4AA//+AAf//wAP///AH///8H/ygAAAAwAAAAYAAAAAEA - IAAAAAAAACQAAMMOAADDDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//ACanxAAN4f0ALpWkCzSIlSFAanEvPHR9TUVg - ZFFMTk5RQGpwbj9udXFLUlRRQGtxUT1xeTw3gIwlKp6vDxHZ9gIWy+kAAP//AAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADt//AE5LSwAsmqsHO3Z/Kz9tdGZEYWaaSFlcwkhY - WuJLUVLtS1FS+kxOT/xNTEv8TU1N/k1NTf5NTEz8TFBR/UtRUvNJV1nmRl1gy0Jla55AbHNeNYOPJyWq - vgQyipgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3i4wCtAAAAOH6IFD5vd2FGXmKySlRV50xP - UP1NS0v/TUtK/01OTv9KVFb/SVte/0ZiaP9EZ27/RGty/0Rqcf9EZmz/SF9j/0pWWf9MT0//TUtL/01L - S/9MUFD8SVZZ4kRiZqQ7doBOLpSiC0pUZgAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AN4CMACyaqww+cHdgSFlbx0xQ - UfpNS0v/TE5O/0deYv9Ad4L/OZKk/zOqwf8vu9f/LMbl/yvN7f8p0fL/KdP1/ynT9P8pz/D/LMrp/y6/ - 3P8yrcb/OJSm/0B2gP9IW1//TU1N/01MS/9LU1T1Rl5itTt3gE4jrsIIKp2wAAD//wAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB+4zwA+b3cAM4mWKENk - aapLUlP5TktL/0pWWP8/eoX/NKe+/yzH5v8o1/r/J93//yfd//8o3f//KNz//yjc//8o3P//KNv//yjc - //8o3P//KNz//yjd//8n3f//J93//yjX+v8sxOL/Np6z/0JweP9MUVH/TUtL/0pVV/VCZmyeNYSQJERj - ZwAsmKkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJaa8AEpU - VgBBaXAsR1teyE1OTv9MT1D/P3qF/y+40v8o1/n/J93//yjc//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o3P//J93//ynT9P8yq8P/Qm93/01N - Tv9NTk7/R1te0Dx0fEYA//8BKKGpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAT09sATUxOAEBrcStJVljITUxM/0lYWv82nbH/KNX2/yjd//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjc - //8n3f//KdDx/zeYqv9JWVz/TUtL/0lWWOc7d4FoE9PuBCaouwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAA3gIsAM4iVJUZdYMdNTEz/SFte/zGsxP8o2/7/KNz//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNz//yfb/v8vtc//RGdt/05LS/9JVljyOniBbAD//wIhsccAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6VowAmprcNQ2Rpp01OTv9KV1n/MavC/yfc//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8n3f//LcLf/0Rtdf9OS0v/SFha6zp4 - gklRRUQAC+f/AAAAAAAAAAAAAAAAAAAAAAAAAAAAJau2AFc2NAA+b3ZnS1JT+kxPT/82m67/KNv+/yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KN3//y3D - 4P9EaG7/TktL/0VfY8svk6IbMoyaAAAAAAAAAAAAAAAAAAAAAAAAAAAANYSRADGMmiNHWl3WTktK/z97 - h/8p1fb/KNz//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yfd//8wssv/SlZY/0xQUf4+b3ZyWTAqACWovAAAAAAAAAAAAAAAAAAWzOgA/wAAAD5v - doBMT0//SVlc/y692P8o3f//KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2fv/PYKO/05LSv9GXWDBKaGzDSyZqgAAAAAAAAAAAAAA - AAAziJUAMoyZF0ZcX9JOS0r/O4iW/yja/f8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8n3f//Ma7F/0xQUP9JVVfqOXyGLDl6 - hAAAAAAAAAAAAAAAAABFXmIAQGpxTEtQUfhKVVf/L7rU/yjd//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o3P//LMXi/0la - Xf9LUlP6OniCTj9udQAAAAAAAAAAAAAAAAD/AAAAQ2NokE1MTP9CcHn/KdT2/yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o3P//K8zs/0ZiZ/9MT0/9Q2VqVEVfYwAAAAAAAAAAAAAAAAAmp7sQRl5ixU5LSv85kKH/J9z//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o3P//Ks7u/0Zkaf9MTk79RV9jVEdbXgAAAAAAAAAAAAAAAAA1hZEkSVdZ3kxO - Tv8yqsH/J93//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o3P//LMno/0hdYf9LUFH8Pm92UkJmbAAAAAAAAAAAAAAA - AAA4fYc8SVVX8EtTVf8vutX/KN3//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o3f//L7jS/0tTVP9LUlPvPnB4Mz9s - cwAAAAAAAAAAAAAAAABDZGk8S1BR8ElYWv8twd7/KN3//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8n3P//OJSl/01L - S/9HWl3SMY2bFjKMmgAAAAAAAAAAAAAAAABDYmc8TFBR8ElYW/8twt//KN3//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjc - //8rzOv/RWZs/01NTf9DZGmPAP//ABy/2AAAAAAAAAAAAAAAAAA9cns8SlNV8EpVV/8vvdr/KN3//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yfc//83maz/TU1N/0pVVu06eIE7P210AAAAAAAAAAAAAAAAAAAAAAA0h5Q5SVdZ7UxR - Uv8wt9L/J93//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KN3//y2+2v9HXWH/TU1N/0Jla50Yx+IFLJmqAAAAAAAAAAAAAAAAAAAA - AABBaG4eS1FR2UxQUP8xsMj/J93//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNz//yjc//8o3f//KN3//yjd//8o3P//KNz//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o3P//Ks7u/0Fzff9OS0r/SFda2Dh9hilAanIAAAAAAAAA - AAAAAAAAAAAAAAAAAAA1hZEZSFlb1U1NTf81pbv/J93//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o3P//KN3//yfd//8o1/r/K83u/yzD4f8vu9f/MLjT/y692f8sxuT/KdHz/yjb/v8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjc//8p1PX/PISR/01MS/9JV1n7OoKNcP8A - AAAh0uYAAAAAAAAAAAAAAAAAAAAAAAAAAAAmqLwMR1tevk1LSv84lKX/J93//yjb//8o2///KNv//yjb - //8o2///KNz//yfd//8p0/T/L7jS/ziVp/9Ad4H/RmNp/0lZW/9KVFb/S1NU/0pVV/9IW1//RGlw/ziW - qP8p1vj/KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNz//yjW+P85jZ3/TU5O/0tS - U/47go6pJNz2HCuCngAo4P8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8BRGJnnk1LS/8/fIf/KNn8/yjb - //8o2///KNv//yjc//8n3P7/K8jn/zadsP9Cb3f/SlRV/01LS/9NS0v/TE9P/kxQUPVLUVLsSlVW7EtS - U/JNTU3/TkpJ/0laXv8tx+X/KNz//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNj7/ziR - ov9MT0//TE9Q/j9yeq4lw9kfNIakABf//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNTU0AQ2Vqak1O - Tv9FZWr/Ks7u/yjc//8o2///J93//yrM6/83lqj/RmFm/01MTP9NTEz/S1JT90daXdFFYGSWP210aUBq - cT9DZGorOH2ILkJmbKdMT1D/TE5O/ziPn/8o2Pv/KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o3P//K8vq/0deY/9NTU3/Q2xztC6svx46hpsAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAA9cnoAOniCQEpTVPRLU1X/L7nT/yfe//8o1/n/M6nA/0Rob/9NTEz/TU1O/0hYW+pDZWqjPHV+TjCR - nxYK6PgBG7/PACKxugB+AAAAO3Z/YUpUVfFNTEz/PYGO/ynU9P8o3P//KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///Kdj7/zWkuv85kqPULrnSNjyKqAAV//8AAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAA2g44ANoOPFUhXWtFNTEv/N5qt/yvI5/89g5D/S1FS/01MS/9KVVbrQGtxmzOI - lTceutIFJ6W5AAAAAAAAAAAAEdj2AEFpbwA2g485SFpc4k5LSv9Bcnv/Ks3s/yjc//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjd//om4f+OH/j/CCHy/wAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAisccAAP//AkRiZ6FNTEz/RWRq/0VmbP9NS0v/S1FS/ERh - Zrw8dX4+HrjQBCmfsgAA//8AAAAAAAAAAAAAAAAAMouYACqdrg1EYmeyTUxM/0dhZf8twNz/KN3//yjb - //8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///J93//ynS8/YzpLqjQGtxe0Bq - cX0+cHhaNoKOIBy/1wErna4AAAAAAAAAAAAAAAAAAAAAAAAAAAAO3v4ATU1NAD9tdGJMUFH+TUxL/01M - TP9JVljoPnB3eyqdrRM+cH4AAP//AAAAAAAAAAAAAAAAAAAAAAAZxd8AVDw5ADxzfGFLUlP5TFBR/zSk - uv8n3f//KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2v3/MbDJ/0Jw - eP5LU1P9TU9N/01PTf9MUVH8SFha2T5vdnctmKgPMI+eAAAAAAAAAAAAAAAAAAAAAAAAAAAANoKOADSF - ki5HWl3pTE9P/0ZdYMY8dH0+BPb/AiOttgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtlqYAJqa6CUVf - Y7lNS0v/P3mD/ynV9v8o3P//KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjc - //8rxuT/R15h/05KSv9JTln/QFJ0/z9Sdf9IT1z/TkxL/0tSUvtCZmumLZemHzaBjwAA//8AAAAAAAAA - AAAAAAAAIrDFABrD3QY+b3ddRGFldTWEkB5PSkkAD9z8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAA3gIsAN4CMJklWWOVMTk//MqnA/yfd//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjc//8qyur/RmJn/05LSf83VY3/FWPz/xRk9/8dYNz/N1WN/0xNT/9MUE//Q2RquTGN - myA6eIIAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAABDZGkAQmVrN0tQUfJJV1n/LcDc/yjd//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNv//yjc//8o3P//KNv//yjb//8n2///N5iq/01NTf9JTln/JF3G/xBk//8QZP//E2P3/y5Z - p/9LTlP/TU9O/0JnbbUrnKsVMY6cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCZWsAO3eBVUtQUfxIXWH/LMno/yjc//8o2///KNv//yjb - //8o2///KNv//yjb//8o2///KNz//ynR8v8sxeP/KNb4/yjc//8o3P//KdLy/z96hP9OS0n/Q1Fq/xph - 5P8QZP//EGT//xFk/P8sWq3/S01S/0xRUf5AbHJ5pQAAAB660gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDZGkAPXN7YEtQUf9HYmf/K83t/yjc - //8o2///KNv//yjb//8o2///KNv//yjb//8o3P//LMno/0F0ff9JWVz/OoiW/yjV9/8o2///KN3//yzE - 4f9GY2j/TkxJ/zFXnv8SZPz/FWLy/xdh7P8YYej/OFWK/05MS/9HXF/QLJipFi2XpwAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDY2gAPXJ7YEtQ - Uf9HYWb/K83t/yjc//8o2///KNv//yjb//8o2///KNv//yjb//8n3f//NaW7/01MS/9OS0v/SlZY/y3B - 3v8o3f//KNv//yfd//82m67/TUxL/0dPYP86VIT/QlFu/0VQZf9EUGn/RVBk/01MTP9HWl3mL5OjJi6V - pQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AABAanAAO3Z/RktSU/dKVln/Lr7a/yjd//8o2///KNv//yjb//8o2///KNv//yjb//8o3f//L7nU/0la - Xf9OSkr/Q2tz/yrN7f8o3P//KNv//yfd//83mKr/TUxM/01MTP9OTUv/TU9N/k1PTvpNT078TE9P/0tR - Uv9DZGmmJ6a5CC6UpAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAA4fYgAOH6JHElWWdhNTEz/N5Wm/yfc//8o2///KNv//yjb//8o2///KNv//yjb - //8o2///KNr9/zC30f83nrL/LcPg/yjb//8o2///KN3//yvI5v9FZm3/TUxL/0lXWe5DZGmsQmdsbUdb - XklCZ21aP210eTx0fGwwkZ8ePnB5AAzk/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoo7cAAP//AUFobZZNTk7/R15i/y6+2f8n3f//KNv//yjb - //8o2///KNv//yjb//8o2///KNv//yjd//8n3f//KNz//yjb//8o3f//K8zs/0B4g/9NTEv/SVZY6zl7 - hlMP3PYFNYShAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOXyGADOKlzJGXGDgTktL/0Ns - dP8swt//J93//yjb//8o2///KNv//yjb//8o2///KNv//yjb//8o2///KNv//yfd//8sxeP/QXaA/01M - S/9KVFX5PnB3eAD//wIpoKwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG7/ZAAD/ - /wA9c3taSlNU605LS/9FZWv/Ma3F/yjX+f8n3f//KNz//yjb//8o2///KNv//yjc//8o3f//KNf5/zKt - xf9FZm3/TktK/0pVV/k9cXmGIbPHCSqdrQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAADh8hgAfs8kBQWhuW0hYWulNTEv/S1NU/z97h/8yrcT/K8vq/yjX+f8n2v3/KNn8/yrQ - 8f8ws83/Pn6K/0tTVP9NTEv/SFhb6z1xem0cvdUJJaq+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfuMsAAf3/Ajl6hEFFX2TAS1FS+05LSv9MUFD/R2Fl/0F0 - ff89for/PnuH/0Vob/9LU1T/TktK/0tRUvxEYWbEN3+JRgnp/wMft8kAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIrHIADp5gwAtl6cUPXJ6ZkZe - Yb1KVFbvTE5P/U1MTP9OS0r/TktK/0xOTv9LUlPzRl1gxz5vd2ssmKkWQmZsABjJ5AAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAA//8AMY2cACuaqww7dn8zQGtyZEZeYYBNTU2AS1JTgUBrcXc+cHg/MouZEAD//wAVzegAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - AAD///////8AAP//AAP//wAA//AAAH//AAD/wAAAH/8AAP8AAAAH/wAA/gAAAAP/AAD8AAAAAP8AAPgA - AAAAfwAA8AAAAAA/AADgAAAAAD8AAOAAAAAAHwAAwAAAAAAfAADAAAAAAA8AAIAAAAAADwAAgAAAAAAP - AACAAAAAAA8AAAAAAAAADwAAAAAAAAAPAAAAAAAAAA8AAAAAAAAADwAAAAAAAAAfAAAAAAAAAB8AAAAA - AAAAHwAAAAAAAAA/AAAAAAAAAH8AAAAAAAAAfwAAAAAAAAD/AACAAAAAAf8AAIAA4AAD/wAAgAfAAAP/ - AACAH4AAAD8AAMB/gAAAHwAAwP8AAAAPAADD/wAAAAcAAP//AAAAAwAA//8AAAADAAD//wAAAAEAAP// - AAAAAQAA//8AAAABAAD//wAAAAMAAP//AAAA/wAA//+AAAH/AAD//8AAA/8AAP//wAAH/wAA///gAA// - AAD///gAP/8AAP///gD//wAA////////AAA= - - - \ No newline at end of file diff --git a/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsagePresenter.cs b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsagePresenter.cs new file mode 100644 index 0000000000..cebcd0f43c --- /dev/null +++ b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsagePresenter.cs @@ -0,0 +1,34 @@ +using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.MoveCloserToUsage; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rubberduck.UI.Refactorings.MoveCloserToUsage +{ + class MoveCloserToUsagePresenter : RefactoringPresenterBase, IMoveCloserToUsagePresenter + { + + private static readonly DialogData DialogData = DialogData.Create("RefactoringsUI.MoveCloserToUsageDialog_Caption", 164, 684); + + public MoveCloserToUsagePresenter(MoveCloserToUsageModel model, IRefactoringDialogFactory dialogFactory) : + base(DialogData, model, dialogFactory) + { + } + + public MoveCloserToUsageModel Show(VariableDeclaration target) + { + if (null == target) + { + return null; + } + + Model.Target = target; + + return Show(); + } + } +} diff --git a/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageView.xaml b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageView.xaml new file mode 100644 index 0000000000..a1bc2a9013 --- /dev/null +++ b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageView.xaml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageView.xaml.cs b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageView.xaml.cs new file mode 100644 index 0000000000..f897818bf1 --- /dev/null +++ b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageView.xaml.cs @@ -0,0 +1,31 @@ +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.MoveCloserToUsage; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace Rubberduck.UI.Refactorings.MoveCloserToUsage +{ + /// + /// Interaktionslogik für MoveCloserToUsageView.xaml + /// + public partial class MoveCloserToUsageView : IRefactoringView + { + public MoveCloserToUsageView() + { + InitializeComponent(); + } + + } +} diff --git a/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageViewModel.cs b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageViewModel.cs new file mode 100644 index 0000000000..52cbd62659 --- /dev/null +++ b/Rubberduck.Core/UI/Refactorings/MoveCloserToUsage/MoveCloserToUsageViewModel.cs @@ -0,0 +1,48 @@ +using NLog; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Refactorings; +using Rubberduck.Refactorings.MoveCloserToUsage; +using Rubberduck.UI.Command; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Rubberduck.UI.Refactorings.MoveCloserToUsage +{ + class MoveCloserToUsageViewModel : RefactoringViewModelBase + { + public MoveCloserToUsageViewModel(MoveCloserToUsageModel model) : base(model) + { + SetNewDeclarationStatementCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), (o) => SetNewDeclarationStatementExecute(o)); + } + + public Declaration Target => Model.Target; + + public string Instructions + { + get + { + if (Target == null) + { + return RefactoringsUI.MoveCloserToUsageDialog_InstructionsLabelText; + } + + return string.Format(RefactoringsUI.MoveCloserToUsageDialog_InstructionsLabelText, Target.IdentifierName); + } + } + + public DelegateCommand SetNewDeclarationStatementCommand { get; } + + void SetNewDeclarationStatementExecute(object param) + { + if (param is string newDeclarationStatement) + { + Model.DeclarationStatement = newDeclarationStatement; + } + + } + + } +} diff --git a/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersPresenter.cs b/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersPresenter.cs index 726f4b3af6..7c0e0eb49d 100644 --- a/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersPresenter.cs +++ b/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersPresenter.cs @@ -1,11 +1,11 @@ using Rubberduck.Refactorings.MoveFolder; -using Rubberduck.Resources; +using Rubberduck.Refactorings; namespace Rubberduck.UI.Refactorings.MoveFolder { internal class MoveMultipleFoldersPresenter : RefactoringPresenterBase, IMoveMultipleFoldersPresenter { - private static readonly DialogData DialogData = DialogData.Create(RubberduckUI.MoveToFolderDialog_Caption, 164, 684); + private static readonly DialogData DialogData = DialogData.Create(RefactoringsUI.MoveToFolderDialog_Caption, 164, 684); public MoveMultipleFoldersPresenter(MoveMultipleFoldersModel model, IRefactoringDialogFactory dialogFactory) : base(DialogData, model, dialogFactory) diff --git a/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersView.xaml b/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersView.xaml index 627462c46f..2451d64cb6 100644 --- a/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersView.xaml +++ b/Rubberduck.Core/UI/Refactorings/MoveFolder/MoveMultipleFoldersView.xaml @@ -19,8 +19,8 @@ - -