diff --git a/README.md b/README.md index 7707a5b45f..4be14947cb 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ If you like this project and would like to thank its contributors, you are welco [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/rubberduck-vba/Rubberduck.svg)](http://isitmaintained.com/project/rubberduck-vba/Rubberduck "Average time to resolve an issue") [![Percentage of issues still open](http://isitmaintained.com/badge/open/rubberduck-vba/Rubberduck.svg)](http://isitmaintained.com/project/rubberduck-vba/Rubberduck "Percentage of issues still open") -> **[rubberduckvba.com](http://rubberduckvba.com)** [Wiki](https://github.com/retailcoder/Rubberduck/wiki) [Rubberduck News](https://rubberduckvba.wordpress.com/) +> **[rubberduckvba.com](http://rubberduckvba.com)** [Wiki](https://github.com/rubberduck-vba/Rubberduck/wiki) [Rubberduck News](https://rubberduckvba.wordpress.com/) > devs@rubberduckvba.com > Follow [@rubberduckvba](https://twitter.com/rubberduckvba) on Twitter diff --git a/Rubberduck.API/Rubberduck.API.csproj b/Rubberduck.API/Rubberduck.API.csproj index 2aad7d3e2f..1019700262 100644 --- a/Rubberduck.API/Rubberduck.API.csproj +++ b/Rubberduck.API/Rubberduck.API.csproj @@ -1,5 +1,5 @@  - + Rubberduck.API Rubberduck Reflection API diff --git a/Rubberduck.API/VBA/Parser.cs b/Rubberduck.API/VBA/Parser.cs index 727e638298..7b24f41100 100644 --- a/Rubberduck.API/VBA/Parser.cs +++ b/Rubberduck.API/VBA/Parser.cs @@ -5,13 +5,11 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading; -using Rubberduck.Common; using Rubberduck.Parsing.ComReflection; using Rubberduck.Parsing.PreProcessing; using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols.DeclarationLoaders; using Rubberduck.Parsing.VBA; -using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.UIContext; using Rubberduck.Parsing.VBA.ComReferenceLoading; using Rubberduck.Parsing.VBA.DeclarationCaching; @@ -98,8 +96,6 @@ internal Parser(object vbe) : this() var projectRepository = new ProjectsRepository(_vbe); _state = new RubberduckParserState(_vbe, projectRepository, declarationFinderFactory, _vbeEvents); _state.StateChanged += _state_StateChanged; - - var sourceFileHandler = _vbe.TempSourceFileHandler; var vbeVersion = double.Parse(_vbe.Version, CultureInfo.InvariantCulture); var predefinedCompilationConstants = new VBAPredefinedCompilationConstants(vbeVersion); var typeLibProvider = new TypeLibWrapperProvider(projectRepository); @@ -112,7 +108,6 @@ internal Parser(object vbe) : this() var mainTokenStreamParser = new VBATokenStreamParser(mainParseErrorListenerFactory, mainParseErrorListenerFactory); var tokenStreamProvider = new SimpleVBAModuleTokenStreamProvider(); var stringParser = new TokenStreamParserStringParserAdapterWithPreprocessing(tokenStreamProvider, mainTokenStreamParser, preprocessor); - var attributesSourceCodeHandler = new SourceFileHandlerSourceCodeHandlerAdapter(sourceFileHandler, projectRepository); var projectManager = new RepositoryProjectManager(projectRepository); var moduleToModuleReferenceManager = new ModuleToModuleReferenceManager(); var parserStateManager = new ParserStateManager(_state); @@ -133,14 +128,12 @@ internal Parser(object vbe) : this() } ); var codePaneSourceCodeHandler = new CodePaneSourceCodeHandler(projectRepository); - var moduleRewriterFactory = new ModuleRewriterFactory( - codePaneSourceCodeHandler, - attributesSourceCodeHandler); + var sourceFileHandler = _vbe.TempSourceFileHandler; + var attributesSourceCodeHandler = new SourceFileHandlerSourceCodeHandlerAdapter(sourceFileHandler, projectRepository); var moduleParser = new ModuleParser( codePaneSourceCodeHandler, attributesSourceCodeHandler, - stringParser, - moduleRewriterFactory); + stringParser); var parseRunner = new ParseRunner( _state, parserStateManager, diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Extensions/NodeExtensions.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Extensions/NodeExtensions.cs index 9ddfe2f42c..f9c66e5622 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Extensions/NodeExtensions.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Extensions/NodeExtensions.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Rubberduck.Parsing.Symbols; namespace Rubberduck.Inspections.CodePathAnalysis.Extensions { @@ -50,5 +51,34 @@ public static INode GetFirstNode(this INode node, IEnumerable excludedType return GetFirstNode(node.Children[0], excludedTypes); } + + public static List GetIdentifierReferences(this INode node) + { + var nodes = new List(); + + var blockNodes = node.GetNodes(new[] { typeof(BlockNode) }); + foreach (var block in blockNodes) + { + INode lastNode = default; + foreach (var flattenedNode in block.GetFlattenedNodes(new[] { typeof(GenericNode), typeof(BlockNode) })) + { + if (flattenedNode is AssignmentNode && + lastNode is AssignmentNode) + { + nodes.Add(lastNode.Reference); + } + + lastNode = flattenedNode; + } + + if (lastNode is AssignmentNode && + block.Children[0].GetFirstNode(new[] { typeof(GenericNode) }) is DeclarationNode) + { + nodes.Add(lastNode.Reference); + } + } + + return nodes; + } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Abstract/NodeBase.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Abstract/NodeBase.cs new file mode 100644 index 0000000000..826ff1fb61 --- /dev/null +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Abstract/NodeBase.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using Antlr4.Runtime.Tree; +using Rubberduck.Parsing.Symbols; + +namespace Rubberduck.Inspections.CodePathAnalysis.Nodes +{ + public abstract class NodeBase : INode + { + protected NodeBase(IParseTree tree) + { + Children = new List().ToImmutableList(); + ParseTree = tree; + } + + public int SortOrder { get; set; } + public ImmutableList Children { get; set; } + public INode Parent { get; set; } + public IParseTree ParseTree { get; } + public Declaration Declaration { get; set; } + public IdentifierReference Reference { get; set; } + } +} diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/INode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/INode.cs index 6a11f7ff6a..e771fa8c7c 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/INode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/INode.cs @@ -1,5 +1,6 @@ using Rubberduck.Parsing.Symbols; using System.Collections.Immutable; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { @@ -8,7 +9,7 @@ public interface INode int SortOrder { get; set; } ImmutableList Children { get; set; } INode Parent { get; set; } - + IParseTree ParseTree { get; } Declaration Declaration { get; set; } IdentifierReference Reference { get; set; } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/AssignmentNode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/AssignmentNode.cs index 5203bfa6ef..a4437ef0da 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/AssignmentNode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/AssignmentNode.cs @@ -1,21 +1,9 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using Rubberduck.Parsing.Symbols; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { - public class AssignmentNode : INode + public class AssignmentNode : NodeBase { - public AssignmentNode() - { - Children = new List().ToImmutableList(); - } - - public int SortOrder { get; set; } - public ImmutableList Children { get; set; } - public INode Parent { get; set; } - - public Declaration Declaration { get; set; } - public IdentifierReference Reference { get; set; } + public AssignmentNode(IParseTree tree) : base(tree) { } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BlockNode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BlockNode.cs index 353add1db7..035052bb52 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BlockNode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BlockNode.cs @@ -1,21 +1,9 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using Rubberduck.Parsing.Symbols; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { - public class BlockNode : INode + public class BlockNode : NodeBase { - public BlockNode() - { - Children = new List().ToImmutableList(); - } - - public int SortOrder { get; set; } - public ImmutableList Children { get; set; } - public INode Parent { get; set; } - - public Declaration Declaration { get; set; } - public IdentifierReference Reference { get; set; } + public BlockNode(IParseTree tree) : base(tree) { } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BranchNode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BranchNode.cs index bef1687b54..fbc40de824 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BranchNode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/BranchNode.cs @@ -1,21 +1,9 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using Rubberduck.Parsing.Symbols; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { - public class BranchNode : IBranchNode + public class BranchNode : NodeBase, IBranchNode { - public BranchNode() - { - Children = new List().ToImmutableList(); - } - - public int SortOrder { get; set; } - public ImmutableList Children { get; set; } - public INode Parent { get; set; } - - public Declaration Declaration { get; set; } - public IdentifierReference Reference { get; set; } + public BranchNode(IParseTree tree) : base(tree) { } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/DeclarationNode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/DeclarationNode.cs index f7173b13e9..dbf0ae2d49 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/DeclarationNode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/DeclarationNode.cs @@ -1,21 +1,9 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using Rubberduck.Parsing.Symbols; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { - public class DeclarationNode : INode + public class DeclarationNode : NodeBase { - public DeclarationNode() - { - Children = new List().ToImmutableList(); - } - - public int SortOrder { get; set; } - public ImmutableList Children { get; set; } - public INode Parent { get; set; } - - public Declaration Declaration { get; set; } - public IdentifierReference Reference { get; set; } + public DeclarationNode(IParseTree tree) : base(tree) { } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/GenericNode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/GenericNode.cs index e8fb1db965..3906d4a6e5 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/GenericNode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/GenericNode.cs @@ -1,21 +1,9 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using Rubberduck.Parsing.Symbols; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { - public class GenericNode : INode + public class GenericNode : NodeBase { - public GenericNode() - { - Children = new List().ToImmutableList(); - } - - public int SortOrder { get; set; } - public ImmutableList Children { get; set; } - public INode Parent { get; set; } - - public Declaration Declaration { get; set; } - public IdentifierReference Reference { get; set; } + public GenericNode(IParseTree tree) : base(tree) { } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/LoopNode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/LoopNode.cs index 56fd6b2d89..8f6d011e59 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/LoopNode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/LoopNode.cs @@ -1,21 +1,9 @@ -using Rubberduck.Parsing.Symbols; -using System.Collections.Generic; -using System.Collections.Immutable; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { - public class LoopNode : ILoopNode + public class LoopNode : NodeBase, ILoopNode { - public LoopNode() - { - Children = new List().ToImmutableList(); - } - - public int SortOrder { get; set; } - public ImmutableList Children { get; set; } - public INode Parent { get; set; } - - public Declaration Declaration { get; set; } - public IdentifierReference Reference { get; set; } + public LoopNode(IParseTree tree) : base(tree) { } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/ReferenceNode.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/ReferenceNode.cs index 538fa01798..f1a1d66ed6 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/ReferenceNode.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Nodes/Implementations/ReferenceNode.cs @@ -1,21 +1,9 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using Rubberduck.Parsing.Symbols; +using Antlr4.Runtime.Tree; namespace Rubberduck.Inspections.CodePathAnalysis.Nodes { - public class ReferenceNode : INode + public class ReferenceNode : NodeBase { - public ReferenceNode() - { - Children = new List().ToImmutableList(); - } - - public int SortOrder { get; set; } - public ImmutableList Children { get; set; } - public INode Parent { get; set; } - - public Declaration Declaration { get; set; } - public IdentifierReference Reference { get; set; } + public ReferenceNode(IParseTree tree) : base(tree) { } } } diff --git a/Rubberduck.CodeAnalysis/CodePathAnalysis/Walker.cs b/Rubberduck.CodeAnalysis/CodePathAnalysis/Walker.cs index 080ecbdf5d..a9c2ba6522 100644 --- a/Rubberduck.CodeAnalysis/CodePathAnalysis/Walker.cs +++ b/Rubberduck.CodeAnalysis/CodePathAnalysis/Walker.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; +using Antlr4.Runtime; namespace Rubberduck.Inspections.CodePathAnalysis { @@ -19,7 +20,7 @@ public INode GenerateTree(IParseTree tree, Declaration declaration) case VBAParser.ForEachStmtContext _: case VBAParser.WhileWendStmtContext _: case VBAParser.DoLoopStmtContext _: - node = new LoopNode(); + node = new LoopNode(tree); break; case VBAParser.IfStmtContext _: case VBAParser.ElseBlockContext _: @@ -28,16 +29,16 @@ public INode GenerateTree(IParseTree tree, Declaration declaration) case VBAParser.SingleLineElseClauseContext _: case VBAParser.CaseClauseContext _: case VBAParser.CaseElseClauseContext _: - node = new BranchNode(); + node = new BranchNode(tree); break; case VBAParser.BlockContext _: - node = new BlockNode(); + node = new BlockNode(tree); break; } if (declaration.Context == tree) { - node = new DeclarationNode + node = new DeclarationNode(tree) { Declaration = declaration }; @@ -48,14 +49,14 @@ public INode GenerateTree(IParseTree tree, Declaration declaration) { if (reference.IsAssignment) { - node = new AssignmentNode + node = new AssignmentNode(tree) { Reference = reference }; } else { - node = new ReferenceNode + node = new ReferenceNode(tree) { Reference = reference }; @@ -64,7 +65,7 @@ public INode GenerateTree(IParseTree tree, Declaration declaration) if (node == null) { - node = new GenericNode(); + node = new GenericNode(tree); } var children = new List(); diff --git a/Rubberduck.CodeAnalysis/Inspections/Abstract/MemberAccessMayReturnNothingInspectionBase.cs b/Rubberduck.CodeAnalysis/Inspections/Abstract/MemberAccessMayReturnNothingInspectionBase.cs new file mode 100644 index 0000000000..b78e9cf604 --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Abstract/MemberAccessMayReturnNothingInspectionBase.cs @@ -0,0 +1,101 @@ +using System.Collections.Generic; +using System.Linq; +using Antlr4.Runtime.Tree; +using Rubberduck.Inspections.CodePathAnalysis; +using Rubberduck.Inspections.CodePathAnalysis.Nodes; +using Rubberduck.Inspections.Results; +using Rubberduck.Parsing; +using Rubberduck.Parsing.Grammar; +using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; + +namespace Rubberduck.Inspections.Abstract +{ + public abstract class MemberAccessMayReturnNothingInspectionBase : InspectionBase + { + protected MemberAccessMayReturnNothingInspectionBase(RubberduckParserState state) : base(state) { } + + public abstract List MembersUnderTest { get; } + public abstract string ResultTemplate { get; } + + protected override IEnumerable DoGetInspectionResults() + { + var interesting = MembersUnderTest.SelectMany(member => member.References).ToList(); + if (!interesting.Any()) + { + return Enumerable.Empty(); + } + + var output = new List(); + foreach (var reference in interesting.Where(use => !IsIgnoringInspectionResultFor(use, AnnotationName))) + { + var access = reference.Context.GetAncestor(); + var usageContext = access.Parent is VBAParser.IndexExprContext + ? access.Parent.Parent + : access.Parent; + + var setter = usageContext is VBAParser.LExprContext lexpr && lexpr.Parent is VBAParser.SetStmtContext + ? lexpr.Parent + : null; + + if (setter is null) + { + if (usageContext is VBAParser.MemberAccessExprContext || !ContextIsNothingTest(usageContext)) + { + output.Add(new IdentifierReferenceInspectionResult(this, + string.Format(ResultTemplate, + $"{reference.Declaration.ParentDeclaration.IdentifierName}.{reference.IdentifierName}"), + State, reference)); + } + continue; + } + + var assignedTo = Declarations.SelectMany(decl => decl.References).SingleOrDefault(assign => + assign.IsAssignment && (assign.Context.GetAncestor()?.Equals(setter) ?? false)); + if (assignedTo is null) + { + continue; + } + + var tree = new Walker().GenerateTree(assignedTo.Declaration.ParentScopeDeclaration.Context, assignedTo.Declaration); + var firstUse = GetReferenceNodes(tree).FirstOrDefault(); + if (firstUse is null || ContextIsNothingTest(firstUse.Reference.Context.Parent)) + { + continue; + } + + output.Add(new IdentifierReferenceInspectionResult(this, + string.Format(ResultTemplate, + $"{reference.Declaration.ParentDeclaration.IdentifierName}.{reference.IdentifierName}"), + State, reference)); + } + + return output; + } + + private bool ContextIsNothingTest(IParseTree context) + { + return context is VBAParser.LExprContext && + context.Parent is VBAParser.RelationalOpContext comparison && + comparison.IS() != null + && comparison.GetDescendent() != null; + } + + private IEnumerable GetReferenceNodes(INode node) + { + if (node is ReferenceNode && node.Reference != null) + { + yield return node; + } + + foreach (var child in node.Children) + { + foreach (var childNode in GetReferenceNodes(child)) + { + yield return childNode; + } + } + } + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Abstract/QuickFixBase.cs b/Rubberduck.CodeAnalysis/Inspections/Abstract/QuickFixBase.cs index 124c229ec5..b4f13d3c09 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Abstract/QuickFixBase.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Abstract/QuickFixBase.cs @@ -3,8 +3,9 @@ using System.Linq; using NLog; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA.Extensions; +using Rubberduck.Parsing.VBA.Parsing; namespace Rubberduck.Inspections.Abstract { @@ -39,7 +40,9 @@ public void RemoveInspections(params Type[] inspections) _supportedInspections = _supportedInspections.Except(inspections).ToHashSet(); } - public abstract void Fix(IInspectionResult result); + public virtual CodeKind TargetCodeKind => CodeKind.CodePaneCode; + + public abstract void Fix(IInspectionResult result, IRewriteSession rewriteSession); public abstract string Description(IInspectionResult result); public abstract bool CanFixInProcedure { get; } diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs index 47f0d0be62..88e3bc0f8f 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs @@ -4,10 +4,11 @@ using Rubberduck.Parsing.VBA; using Rubberduck.Inspections.CodePathAnalysis; using Rubberduck.Parsing.Symbols; -using Rubberduck.Inspections.CodePathAnalysis.Nodes; using Rubberduck.Inspections.CodePathAnalysis.Extensions; using System.Linq; using Rubberduck.Inspections.Results; +using Rubberduck.Parsing; +using Rubberduck.Parsing.Grammar; namespace Rubberduck.Inspections.Concrete { @@ -22,48 +23,21 @@ public AssignmentNotUsedInspection(RubberduckParserState state, Walker walker) protected override IEnumerable DoGetInspectionResults() { - var variables = State.DeclarationFinder.UserDeclarations(DeclarationType.Variable); + var variables = State.DeclarationFinder + .UserDeclarations(DeclarationType.Variable) + .Where(d => !d.IsArray); var nodes = new List(); foreach (var variable in variables) { var tree = _walker.GenerateTree(variable.ParentScopeDeclaration.Context, variable); - nodes.AddRange(GetIdentifierReferences(tree, variable)); + nodes.AddRange(tree.GetIdentifierReferences()); } return nodes .Select(issue => new IdentifierReferenceInspectionResult(this, Description, State, issue)) .ToList(); } - - private List GetIdentifierReferences(INode node, Declaration declaration) - { - var nodes = new List(); - - var blockNodes = node.GetNodes(new[] { typeof(BlockNode) }); - foreach (var block in blockNodes) - { - INode lastNode = default; - foreach (var flattenedNode in block.GetFlattenedNodes(new[] { typeof(GenericNode), typeof(BlockNode) })) - { - if (flattenedNode is AssignmentNode && - lastNode is AssignmentNode) - { - nodes.Add(lastNode.Reference); - } - - lastNode = flattenedNode; - } - - if (lastNode is AssignmentNode && - block.Children[0].GetFirstNode(new[] { typeof(GenericNode) }) is DeclarationNode) - { - nodes.Add(lastNode.Reference); - } - } - - return nodes; - } } } diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueNotUsedInspection.cs index 624c026d62..5981f4ec5d 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueNotUsedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/FunctionReturnValueNotUsedInspection.cs @@ -28,7 +28,8 @@ protected override IEnumerable DoGetInspectionResults() var interfaceImplementationMembers = State.DeclarationFinder.FindAllInterfaceImplementingMembers(); var functions = State.DeclarationFinder .UserDeclarations(DeclarationType.Function) - .Where(item => !IsIgnoringInspectionResultFor(item, AnnotationName)) + .Where(item => !IsIgnoringInspectionResultFor(item, AnnotationName) && + item.References.Any(r => !IsReturnStatement(item, r) && !r.IsAssignment)) .ToList(); var interfaceMemberIssues = GetInterfaceMemberIssues(interfaceMembers); var nonInterfaceFunctions = functions.Except(interfaceMembers.Union(interfaceImplementationMembers)); diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/MemberAccessMayReturnNothingInspection/ExcelMemberMayReturnNothingInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/MemberAccessMayReturnNothingInspection/ExcelMemberMayReturnNothingInspection.cs new file mode 100644 index 0000000000..7d422f5abc --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/MemberAccessMayReturnNothingInspection/ExcelMemberMayReturnNothingInspection.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Rubberduck.Inspections.Abstract; +using Rubberduck.Parsing.Inspections; +using Rubberduck.Parsing.Symbols; +using Rubberduck.Parsing.VBA; +using Rubberduck.Resources.Inspections; + +namespace Rubberduck.Inspections.Concrete +{ + [RequiredLibrary("Excel")] + public class ExcelMemberMayReturnNothingInspection : MemberAccessMayReturnNothingInspectionBase + { + public ExcelMemberMayReturnNothingInspection(RubberduckParserState state) : base(state) { } + + private static readonly List ExcelMembers = new List + { + "Range.Find", + "Range.FindNext", + "Range.FindPrevious" + }; + + public override List MembersUnderTest => BuiltInDeclarations + .Where(decl => decl.ProjectName.Equals("Excel") && ExcelMembers.Any(member => decl.QualifiedName.ToString().EndsWith(member))) + .ToList(); + + public override string ResultTemplate => InspectionResults.ExcelMemberMayReturnNothingInspection; + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs index 15157be98a..b7aea1d264 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs @@ -5,6 +5,7 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Results; using Rubberduck.Parsing; +using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; using Rubberduck.Resources.Inspections; using Rubberduck.Parsing.Symbols; @@ -30,7 +31,7 @@ public UnassignedVariableUsageInspection(RubberduckParserState state) protected override IEnumerable DoGetInspectionResults() { var declarations = State.DeclarationFinder.UserDeclarations(DeclarationType.Variable) - .Where(declaration => + .Where(declaration => !declaration.IsArray && State.DeclarationFinder.MatchName(declaration.AsTypeName) .All(d => d.DeclarationType != DeclarationType.UserDefinedType) && !declaration.IsSelfAssigned @@ -43,12 +44,22 @@ protected override IEnumerable DoGetInspectionResults() .SelectMany(d => d.References) .Distinct() .Where(r => !r.IsIgnoringInspectionResultFor(AnnotationName)) + .Where(r => !r.Context.TryGetAncestor(out _) && !IsArraySubscriptAssignment(r)) .Select(r => new IdentifierReferenceInspectionResult(this, string.Format(InspectionResults.UnassignedVariableUsageInspection, r.IdentifierName), State, r)).ToList(); } + private static bool IsArraySubscriptAssignment(IdentifierReference reference) + { + var isLetAssignment = reference.Context.TryGetAncestor(out var letStmt); + var isSetAssignment = reference.Context.TryGetAncestor(out var setStmt); + + return isLetAssignment && letStmt.lExpression() is VBAParser.IndexExprContext || + isSetAssignment && setStmt.lExpression() is VBAParser.IndexExprContext; + } + private static bool DeclarationReferencesContainsReference(Declaration parentDeclaration, Declaration target) { foreach (var targetReference in target.References) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/UnderscoreInPublicClassModuleMemberInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnderscoreInPublicClassModuleMemberInspection.cs new file mode 100644 index 0000000000..d28ec90c9b --- /dev/null +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnderscoreInPublicClassModuleMemberInspection.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Linq; +using Rubberduck.Inspections.Abstract; +using Rubberduck.Inspections.Results; +using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Resources.Inspections; +using Rubberduck.Parsing.VBA; + +namespace Rubberduck.Inspections.Concrete +{ + public sealed class UnderscoreInPublicClassModuleMemberInspection : InspectionBase + { + public UnderscoreInPublicClassModuleMemberInspection(RubberduckParserState state) + : base(state) { } + + protected override IEnumerable DoGetInspectionResults() + { + var interfaceMembers = State.DeclarationFinder.FindAllInterfaceImplementingMembers().ToList(); + var eventHandlers = State.DeclarationFinder.FindEventHandlers().ToList(); + + var names = State.DeclarationFinder.UserDeclarations(Parsing.Symbols.DeclarationType.Member) + .Where(w => w.ParentDeclaration.DeclarationType == Parsing.Symbols.DeclarationType.ClassModule) + .Where(w => !interfaceMembers.Contains(w) && !eventHandlers.Contains(w)) + .Where(w => w.Accessibility == Parsing.Symbols.Accessibility.Public || w.Accessibility == Parsing.Symbols.Accessibility.Implicit) + .Where(w => w.IdentifierName.Contains('_')) + .ToList(); + + return names.Select(issue => + new DeclarationInspectionResult(this, string.Format(InspectionResults.UnderscoreInPublicClassModuleMemberInspection, issue.IdentifierName), issue)); + } + } +} diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableRequiresSetAssignmentEvaluator.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableRequiresSetAssignmentEvaluator.cs index 9f4d01922e..7e000bbf67 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableRequiresSetAssignmentEvaluator.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/VariableRequiresSetAssignmentEvaluator.cs @@ -13,8 +13,8 @@ public static class VariableRequiresSetAssignmentEvaluator /// Determines whether the 'Set' keyword is required (whether it's present or not) for the specified identifier reference. /// /// The identifier reference to analyze - /// The parser state - public static bool RequiresSetAssignment(IdentifierReference reference, RubberduckParserState state) + /// The parser state + public static bool RequiresSetAssignment(IdentifierReference reference, IDeclarationFinderProvider declarationFinderProvider) { if (!reference.IsAssignment) { @@ -89,7 +89,7 @@ public static bool RequiresSetAssignment(IdentifierReference reference, Rubberdu // todo resolve expression return type - var memberRefs = state.DeclarationFinder.IdentifierReferences(reference.ParentScoping.QualifiedName); + var memberRefs = declarationFinderProvider.DeclarationFinder.IdentifierReferences(reference.ParentScoping.QualifiedName); var lastRef = memberRefs.LastOrDefault(r => !Equals(r, reference) && r.Context.GetAncestor() == letStmtContext); if (lastRef?.Declaration.AsTypeDeclaration?.DeclarationType.HasFlag(DeclarationType.ClassModule) ?? false) { @@ -104,7 +104,7 @@ public static bool RequiresSetAssignment(IdentifierReference reference, Rubberdu // is the reference referring to something else in scope that's a object? var project = Declaration.GetProjectParent(reference.ParentScoping); var module = Declaration.GetModuleParent(reference.ParentScoping); - return state.DeclarationFinder.MatchName(expression.GetText().ToLowerInvariant()) + return declarationFinderProvider.DeclarationFinder.MatchName(expression.GetText().ToLowerInvariant()) .Any(decl => (decl.DeclarationType.HasFlag(DeclarationType.ClassModule) || Tokens.Object.Equals(decl.AsTypeName)) && AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, decl)); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/AccessSheetUsingCodeNameQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/AccessSheetUsingCodeNameQuickFix.cs index 40da40d12b..767f044083 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/AccessSheetUsingCodeNameQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/AccessSheetUsingCodeNameQuickFix.cs @@ -6,25 +6,26 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { - public class AccessSheetUsingCodeNameQuickFix : QuickFixBase + public sealed class AccessSheetUsingCodeNameQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; + private readonly IDeclarationFinderProvider _declarationFinderProvider; - public AccessSheetUsingCodeNameQuickFix(RubberduckParserState state) + public AccessSheetUsingCodeNameQuickFix(IDeclarationFinderProvider declarationFinderProvider) : base(typeof(SheetAccessedUsingStringInspection)) { - _state = state; + _declarationFinderProvider = declarationFinderProvider; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var referenceResult = (IdentifierReferenceInspectionResult)result; - var rewriter = _state.GetRewriter(referenceResult.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(referenceResult.QualifiedName); var setStatement = referenceResult.Context.GetAncestor(); var isArgument = referenceResult.Context.GetAncestor() != null; @@ -36,14 +37,14 @@ public override void Fix(IInspectionResult result) var indexExprContext = referenceResult.Context.Parent.Parent as VBAParser.IndexExprContext ?? referenceResult.Context.Parent as VBAParser.IndexExprContext; - rewriter.Replace(indexExprContext, referenceResult.Properties.CodeName); + rewriter.Replace(indexExprContext, (string)referenceResult.Properties.CodeName); } else { // Sheet assigned to variable var sheetVariableName = setStatement.lExpression().GetText(); - var sheetDeclaration = _state.DeclarationFinder.MatchName(sheetVariableName) + var sheetDeclaration = _declarationFinderProvider.DeclarationFinder.MatchName(sheetVariableName) .First(declaration => { var moduleBodyElement = declaration.Context.GetAncestor(); @@ -71,7 +72,7 @@ public override void Fix(IInspectionResult result) foreach (var reference in sheetDeclaration.References) { - rewriter.Replace(reference.Context, referenceResult.Properties.CodeName); + rewriter.Replace(reference.Context, (string)referenceResult.Properties.CodeName); } rewriter.Remove(setStatement); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/AddIdentifierToWhiteListQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/AddIdentifierToWhiteListQuickFix.cs index 5c7dc054fd..83ed7f9c43 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/AddIdentifierToWhiteListQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/AddIdentifierToWhiteListQuickFix.cs @@ -2,6 +2,7 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Settings; using Rubberduck.SettingsProvider; @@ -17,7 +18,8 @@ public AddIdentifierToWhiteListQuickFix(IPersistanceService true; @@ -29,20 +24,20 @@ public override string Description(IInspectionResult result) return Resources.Inspections.QuickFixes.AddStepOneQuickFix; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - IModuleRewriter rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); - ForNextStmtContext context = result.Context as ForNextStmtContext; + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); + var context = result.Context as ForNextStmtContext; - int toExpressionEnd = this.GetToExpressionEnd(context); + var toExpressionEnd = GetToExpressionEnd(context); rewriter.InsertAfter(toExpressionEnd, " Step 1"); } - private int GetToExpressionEnd(ForNextStmtContext context) + private static int GetToExpressionEnd(ForNextStmtContext context) { - int toNodeIndex = context.TO().Symbol.TokenIndex; + var toNodeIndex = context.TO().Symbol.TokenIndex; - foreach(ExpressionContext expressionChild in context.expression()) + foreach(var expressionChild in context.expression()) { if (expressionChild.Stop.TokenIndex > toNodeIndex) { diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ApplicationWorksheetFunctionQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ApplicationWorksheetFunctionQuickFix.cs index 8d96b5565d..d17b552f66 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ApplicationWorksheetFunctionQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ApplicationWorksheetFunctionQuickFix.cs @@ -1,23 +1,19 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class ApplicationWorksheetFunctionQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ApplicationWorksheetFunctionQuickFix(RubberduckParserState state) + public ApplicationWorksheetFunctionQuickFix() : base(typeof(ApplicationWorksheetFunctionInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.InsertBefore(result.Context.Start.TokenIndex, "WorksheetFunction."); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/AssignedByValParameterMakeLocalCopyQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/AssignedByValParameterMakeLocalCopyQuickFix.cs index 2446a71c7f..bb4a3ed35d 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/AssignedByValParameterMakeLocalCopyQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/AssignedByValParameterMakeLocalCopyQuickFix.cs @@ -19,17 +19,17 @@ namespace Rubberduck.Inspections.QuickFixes public sealed class AssignedByValParameterMakeLocalCopyQuickFix : QuickFixBase { private readonly IAssignedByValParameterQuickFixDialogFactory _dialogFactory; - private readonly RubberduckParserState _parserState; + private readonly IDeclarationFinderProvider _declarationFinderProvider; private Declaration _quickFixTarget; - public AssignedByValParameterMakeLocalCopyQuickFix(RubberduckParserState state, IAssignedByValParameterQuickFixDialogFactory dialogFactory) + public AssignedByValParameterMakeLocalCopyQuickFix(IDeclarationFinderProvider declarationFinderProvider, IAssignedByValParameterQuickFixDialogFactory dialogFactory) : base(typeof(AssignedByValParameterInspection)) { _dialogFactory = dialogFactory; - _parserState = state; + _declarationFinderProvider = declarationFinderProvider; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { Debug.Assert(result.Target.Context.Parent is VBAParser.ArgListContext); Debug.Assert(null != ((ParserRuleContext)result.Target.Context.Parent.Parent).GetChild()); @@ -42,7 +42,7 @@ public override void Fix(IInspectionResult result) return; } - var rewriter = _parserState.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); ReplaceAssignedByValParameterReferences(rewriter, result.Target, localIdentifier); InsertLocalVariableDeclarationAndAssignment(rewriter, result.Target, localIdentifier); } @@ -76,7 +76,7 @@ private string PromptForLocalVariableName(Declaration target) } private bool IsNameCollision(string newName) - => _parserState.DeclarationFinder.FindNewDeclarationNameConflicts(newName, _quickFixTarget).Any(); + => _declarationFinderProvider.DeclarationFinder.FindNewDeclarationNameConflicts(newName, _quickFixTarget).Any(); private string GetDefaultLocalIdentifier(Declaration target) { @@ -116,7 +116,7 @@ private void InsertLocalVariableDeclarationAndAssignment(IModuleRewriter rewrite var localVariableDeclaration = $"{Tokens.Dim} {localIdentifier} {Tokens.As} {target.AsTypeName}"; var requiresAssignmentUsingSet = - target.References.Any(refItem => VariableRequiresSetAssignmentEvaluator.RequiresSetAssignment(refItem, _parserState)); + target.References.Any(refItem => VariableRequiresSetAssignmentEvaluator.RequiresSetAssignment(refItem, _declarationFinderProvider)); var localVariableAssignment = $"{(requiresAssignmentUsingSet ? $"{Tokens.Set} " : string.Empty)}{localIdentifier} = {target.IdentifierName}"; diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ChangeDimToPrivateQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ChangeDimToPrivateQuickFix.cs index a83c0499d3..1d9f7e4e2b 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ChangeDimToPrivateQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ChangeDimToPrivateQuickFix.cs @@ -2,23 +2,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class ChangeDimToPrivateQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ChangeDimToPrivateQuickFix(RubberduckParserState state) + public ChangeDimToPrivateQuickFix() : base(typeof(ModuleScopeDimKeywordInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var context = (VBAParser.VariableStmtContext)result.Context.Parent.Parent; rewriter.Replace(context.DIM(), Tokens.Private); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ChangeIntegerToLongQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ChangeIntegerToLongQuickFix.cs index ffcb191e1d..5bca967550 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ChangeIntegerToLongQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ChangeIntegerToLongQuickFix.cs @@ -13,19 +13,19 @@ namespace Rubberduck.Inspections.QuickFixes { - public class ChangeIntegerToLongQuickFix : QuickFixBase + public sealed class ChangeIntegerToLongQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; + private readonly IDeclarationFinderProvider _declarationFinderProvider; - public ChangeIntegerToLongQuickFix(RubberduckParserState state) + public ChangeIntegerToLongQuickFix(IDeclarationFinderProvider declarationFinderProvider) : base(typeof(IntegerDataTypeInspection)) { - _state = state; + _declarationFinderProvider = declarationFinderProvider; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); if (result.Target.HasTypeHint) { @@ -66,7 +66,7 @@ public override void Fix(IInspectionResult result) } } - var interfaceMembers = _state.DeclarationFinder.FindAllInterfaceMembers().ToArray(); + var interfaceMembers = _declarationFinderProvider.DeclarationFinder.FindAllInterfaceMembers().ToArray(); ParserRuleContext matchingInterfaceMemberContext; @@ -80,11 +80,11 @@ public override void Fix(IInspectionResult result) var interfaceParameterIndex = GetParameterIndex((VBAParser.ArgContext)result.Context); var implementationMembers = - _state.DeclarationFinder.FindInterfaceImplementationMembers(interfaceMembers.First( + _declarationFinderProvider.DeclarationFinder.FindInterfaceImplementationMembers(interfaceMembers.First( member => member.Context == matchingInterfaceMemberContext)).ToHashSet(); var parameterDeclarations = - _state.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) + _declarationFinderProvider.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) .Where(p => implementationMembers.Contains(p.ParentDeclaration)) .Cast() .ToArray(); @@ -96,7 +96,7 @@ public override void Fix(IInspectionResult result) if (parameterIndex == interfaceParameterIndex) { - var parameterRewriter = _state.GetRewriter(parameter); + var parameterRewriter = rewriteSession.CheckOutModuleRewriter(parameter.QualifiedModuleName); if (parameter.HasTypeHint) { @@ -116,14 +116,14 @@ public override void Fix(IInspectionResult result) if (matchingInterfaceMemberContext != null) { var functionDeclarations = - _state.DeclarationFinder.FindInterfaceImplementationMembers( + _declarationFinderProvider.DeclarationFinder.FindInterfaceImplementationMembers( interfaceMembers.First(member => member.Context == matchingInterfaceMemberContext)) .Cast() .ToHashSet(); foreach (var function in functionDeclarations) { - var functionRewriter = _state.GetRewriter(function); + var functionRewriter = rewriteSession.CheckOutModuleRewriter(function.QualifiedModuleName); if (function.HasTypeHint) { @@ -143,14 +143,14 @@ public override void Fix(IInspectionResult result) if (matchingInterfaceMemberContext != null) { var propertyGetDeclarations = - _state.DeclarationFinder.FindInterfaceImplementationMembers( + _declarationFinderProvider.DeclarationFinder.FindInterfaceImplementationMembers( interfaceMembers.First(member => member.Context == matchingInterfaceMemberContext)) .Cast() .ToHashSet(); foreach (var propertyGet in propertyGetDeclarations) { - var propertyGetRewriter = _state.GetRewriter(propertyGet); + var propertyGetRewriter = rewriteSession.CheckOutModuleRewriter(propertyGet.QualifiedModuleName); if (propertyGet.HasTypeHint) { diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ChangeProcedureToFunctionQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ChangeProcedureToFunctionQuickFix.cs index d85ce81c22..2103a637e4 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ChangeProcedureToFunctionQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ChangeProcedureToFunctionQuickFix.cs @@ -5,42 +5,38 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { public sealed class ChangeProcedureToFunctionQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ChangeProcedureToFunctionQuickFix(RubberduckParserState state) + public ChangeProcedureToFunctionQuickFix() : base(typeof(ProcedureCanBeWrittenAsFunctionInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var parameterizedDeclaration = (IParameterizedDeclaration) result.Target; - var arg = parameterizedDeclaration.Parameters.Cast().First(p => p.IsByRef || p.IsImplicitByRef); + var arg = parameterizedDeclaration.Parameters.First(p => p.IsByRef || p.IsImplicitByRef); var argIndex = parameterizedDeclaration.Parameters.ToList().IndexOf(arg); - UpdateSignature(result.Target, arg); + UpdateSignature(result.Target, arg, rewriteSession); foreach (var reference in result.Target.References) { - UpdateCall(reference, argIndex); + UpdateCall(reference, argIndex, rewriteSession); } } public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.ProcedureShouldBeFunctionInspectionQuickFix; - private void UpdateSignature(Declaration target, ParameterDeclaration arg) + private void UpdateSignature(Declaration target, ParameterDeclaration arg, IRewriteSession rewriteSession) { var subStmt = (VBAParser.SubStmtContext) target.Context; var argContext = (VBAParser.ArgContext)arg.Context; - var rewriter = _state.GetRewriter(target); + var rewriter = rewriteSession.CheckOutModuleRewriter(target.QualifiedModuleName); rewriter.Replace(subStmt.SUB(), Tokens.Function); rewriter.Replace(subStmt.END_SUB(), "End Function"); @@ -60,9 +56,9 @@ private void UpdateSignature(Declaration target, ParameterDeclaration arg) rewriter.InsertBefore(subStmt.END_SUB().Symbol.TokenIndex, returnStmt); } - private void UpdateCall(IdentifierReference reference, int argIndex) + private void UpdateCall(IdentifierReference reference, int argIndex, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(reference.QualifiedModuleName); + var rewriter = rewriteSession.CheckOutModuleRewriter(reference.QualifiedModuleName); var callStmtContext = reference.Context.GetAncestor(); var argListContext = callStmtContext.GetChild(); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ConvertToProcedureQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ConvertToProcedureQuickFix.cs index 9b037f0e3a..bea1f27609 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ConvertToProcedureQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ConvertToProcedureQuickFix.cs @@ -6,38 +6,34 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { public sealed class ConvertToProcedureQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ConvertToProcedureQuickFix(RubberduckParserState state) + public ConvertToProcedureQuickFix() : base(typeof(NonReturningFunctionInspection), typeof(FunctionReturnValueNotUsedInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); + switch (result.Context) { case VBAParser.FunctionStmtContext functionContext: - ConvertFunction(result, functionContext); + ConvertFunction(result, functionContext, rewriter); break; case VBAParser.PropertyGetStmtContext propertyGetContext: - ConvertPropertyGet(result, propertyGetContext); + ConvertPropertyGet(result, propertyGetContext, rewriter); break; } } - private void ConvertFunction(IInspectionResult result, VBAParser.FunctionStmtContext functionContext) + private void ConvertFunction(IInspectionResult result, VBAParser.FunctionStmtContext functionContext, IModuleRewriter rewriter) { - var rewriter = _state.GetRewriter(result.Target); - var asTypeContext = functionContext.GetChild(); if (asTypeContext != null) { @@ -59,10 +55,8 @@ private void ConvertFunction(IInspectionResult result, VBAParser.FunctionStmtCon } } - private void ConvertPropertyGet(IInspectionResult result, VBAParser.PropertyGetStmtContext propertyGetContext) + private void ConvertPropertyGet(IInspectionResult result, VBAParser.PropertyGetStmtContext propertyGetContext, IModuleRewriter rewriter) { - var rewriter = _state.GetRewriter(result.Target); - var asTypeContext = propertyGetContext.GetChild(); if (asTypeContext != null) { diff --git a/Rubberduck.CodeAnalysis/QuickFixes/DeclareAsExplicitVariantQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/DeclareAsExplicitVariantQuickFix.cs index 28a0db45bd..fa4beeaa94 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/DeclareAsExplicitVariantQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/DeclareAsExplicitVariantQuickFix.cs @@ -3,23 +3,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class DeclareAsExplicitVariantQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public DeclareAsExplicitVariantQuickFix(RubberduckParserState state) + public DeclareAsExplicitVariantQuickFix() : base(typeof(VariableTypeNotDeclaredInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); ParserRuleContext identifierNode = result.Context is VBAParser.VariableSubStmtContext || result.Context is VBAParser.ConstSubStmtContext diff --git a/Rubberduck.CodeAnalysis/QuickFixes/EncapsulateFieldQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/EncapsulateFieldQuickFix.cs index 01b8545c1a..dcbe44b31a 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/EncapsulateFieldQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/EncapsulateFieldQuickFix.cs @@ -1,6 +1,7 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.EncapsulateField; using Rubberduck.SmartIndenter; @@ -13,22 +14,25 @@ public sealed class EncapsulateFieldQuickFix : QuickFixBase { private readonly IVBE _vbe; private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IIndenter _indenter; - public EncapsulateFieldQuickFix(IVBE vbe, RubberduckParserState state, IIndenter indenter) + public EncapsulateFieldQuickFix(IVBE vbe, RubberduckParserState state, IIndenter indenter, IRewritingManager rewritingManager) : base(typeof(EncapsulatePublicFieldInspection)) { _vbe = vbe; _state = state; + _rewritingManager = rewritingManager; _indenter = indenter; } - public override void Fix(IInspectionResult result) + //The rewriteSession is optional since it is not used in this particular quickfix because it is a refactoring quickfix. + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession = null) { using (var view = new EncapsulateFieldDialog(new EncapsulateFieldViewModel(_state, _indenter))) { var factory = new EncapsulateFieldPresenterFactory(_vbe, _state, view); - var refactoring = new EncapsulateFieldRefactoring(_vbe, _indenter, factory); + var refactoring = new EncapsulateFieldRefactoring(_vbe, _indenter, factory, _rewritingManager); refactoring.Refactor(result.Target); } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/IgnoreOnceQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/IgnoreOnceQuickFix.cs index 65ae67fd15..a5aa066e0b 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/IgnoreOnceQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/IgnoreOnceQuickFix.cs @@ -8,6 +8,7 @@ using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes @@ -26,12 +27,12 @@ public IgnoreOnceQuickFix(RubberduckParserState state, IEnumerable public override bool CanFixInModule => false; public override bool CanFixInProject => false; - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var annotationText = $"'@Ignore {result.Inspection.AnnotationName}"; int annotationLine; - string codeLine; + //TODO: Make this use the parse tree instead of the code module. var component = _state.ProjectsProvider.Component(result.QualifiedSelection.QualifiedName); using (var module = component.CodeModule) { @@ -53,7 +54,7 @@ public override void Fix(IInspectionResult result) var commentContext = listener.Contexts.LastOrDefault(i => i.Stop.TokenIndex <= result.Context.Start.TokenIndex); var commented = commentContext?.Stop.Line + 1 == annotationLine; - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); if (commented) { diff --git a/Rubberduck.CodeAnalysis/QuickFixes/IntroduceLocalVariableQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/IntroduceLocalVariableQuickFix.cs index eb17717cc4..a4fca60ca3 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/IntroduceLocalVariableQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/IntroduceLocalVariableQuickFix.cs @@ -5,30 +5,27 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class IntroduceLocalVariableQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public IntroduceLocalVariableQuickFix(RubberduckParserState state) + public IntroduceLocalVariableQuickFix() : base(typeof(UndeclaredVariableInspection)) - { - _state = state; - } + {} public override bool CanFixInProcedure => true; public override bool CanFixInModule => true; public override bool CanFixInProject => true; - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var identifierContext = result.Target.Context; var enclosingStatmentContext = identifierContext.GetAncestor(); var instruction = IdentifierDeclarationText(result.Target.IdentifierName, EndOfStatementText(enclosingStatmentContext), FrontPadding(enclosingStatmentContext)); - _state.GetRewriter(result.Target).InsertBefore(enclosingStatmentContext.Start.TokenIndex, instruction); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); + rewriter.InsertBefore(enclosingStatmentContext.Start.TokenIndex, instruction); } private string EndOfStatementText(VBAParser.BlockStmtContext context) diff --git a/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs index 2b13021482..8a69d25d85 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs @@ -6,22 +6,23 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { - public class IsMissingOnInappropriateArgumentQuickFix : QuickFixBase + public sealed class IsMissingOnInappropriateArgumentQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; + private readonly IDeclarationFinderProvider _declarationFinderProvider; - public IsMissingOnInappropriateArgumentQuickFix(RubberduckParserState state) + public IsMissingOnInappropriateArgumentQuickFix(IDeclarationFinderProvider declarationFinderProvider) : base(typeof(IsMissingOnInappropriateArgumentInspection)) { - _state = state; + _declarationFinderProvider = declarationFinderProvider; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { if (!(result.Properties is ParameterDeclaration parameter)) { @@ -30,7 +31,7 @@ public override void Fix(IInspectionResult result) return; } - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); if (!result.Context.TryGetAncestor(out var context)) { Logger.Trace("IsMissingOnInappropriateArgumentQuickFix could not locate containing LExprContext for replacement."); @@ -108,7 +109,7 @@ private string UninitializedComparisonForParameter(ParameterDeclaration paramete case DeclarationType.ClassModule: return $"{parameter.IdentifierName} Is {Tokens.Nothing}"; case DeclarationType.Enumeration: - var members = _state.DeclarationFinder.AllDeclarations.OfType() + var members = _declarationFinderProvider.DeclarationFinder.AllDeclarations.OfType() .FirstOrDefault(decl => ReferenceEquals(decl.ParentDeclaration, parameter.AsTypeDeclaration) && decl.Expression.Equals("0")); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/MakeSingleLineParameterQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/MakeSingleLineParameterQuickFix.cs index 2bd56531a8..a3c79a807e 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/MakeSingleLineParameterQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/MakeSingleLineParameterQuickFix.cs @@ -1,24 +1,20 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA.Extensions; namespace Rubberduck.Inspections.QuickFixes { public sealed class MakeSingleLineParameterQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public MakeSingleLineParameterQuickFix(RubberduckParserState state) + public MakeSingleLineParameterQuickFix() : base(typeof(MultilineParameterInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var parameter = result.Context.GetText() .Replace("_", "") diff --git a/Rubberduck.CodeAnalysis/QuickFixes/MoveFieldCloserToUsageQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/MoveFieldCloserToUsageQuickFix.cs index 9a5634222f..696287fea3 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/MoveFieldCloserToUsageQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/MoveFieldCloserToUsageQuickFix.cs @@ -2,6 +2,7 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Interaction; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.MoveCloserToUsage; using Rubberduck.Resources.Inspections; @@ -13,19 +14,22 @@ public sealed class MoveFieldCloserToUsageQuickFix : QuickFixBase { private readonly IVBE _vbe; private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public MoveFieldCloserToUsageQuickFix(IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public MoveFieldCloserToUsageQuickFix(IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) : base(typeof(MoveFieldCloserToUsageInspection)) { _vbe = vbe; _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } - public override void Fix(IInspectionResult result) + //The rewriteSession is optional since it is not used in this particular quickfix because it is a refactoring quickfix. + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession = null) { - var refactoring = new MoveCloserToUsageRefactoring(_vbe, _state, _messageBox); + var refactoring = new MoveCloserToUsageRefactoring(_vbe, _state, _messageBox, _rewritingManager); refactoring.Refactor(result.Target); } @@ -34,8 +38,8 @@ public override string Description(IInspectionResult result) return string.Format(InspectionResults.MoveFieldCloserToUsageInspection, result.Target.IdentifierName); } - public override bool CanFixInProcedure => true; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; + public override bool CanFixInProcedure => false; + public override bool CanFixInModule => false; + public override bool CanFixInProject => false; } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/OptionExplicitQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/OptionExplicitQuickFix.cs index b223170ef9..f5f729013b 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/OptionExplicitQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/OptionExplicitQuickFix.cs @@ -3,23 +3,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class OptionExplicitQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public OptionExplicitQuickFix(RubberduckParserState state) + public OptionExplicitQuickFix() : base(typeof(OptionExplicitInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.InsertBefore(0, Tokens.Option + ' ' + Tokens.Explicit + Environment.NewLine + Environment.NewLine); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByReferenceQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByReferenceQuickFix.cs index 590f81c512..f4debba3f2 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByReferenceQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByReferenceQuickFix.cs @@ -2,23 +2,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class PassParameterByReferenceQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public PassParameterByReferenceQuickFix(RubberduckParserState state) + public PassParameterByReferenceQuickFix() : base(typeof(AssignedByValParameterInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); var token = ((VBAParser.ArgContext)result.Target.Context).BYVAL().Symbol; rewriter.Replace(token, Tokens.ByRef); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByValueQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByValueQuickFix.cs index 0689f17bfd..374299fd16 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByValueQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/PassParameterByValueQuickFix.cs @@ -4,6 +4,7 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.VBEditor; @@ -12,6 +13,7 @@ namespace Rubberduck.Inspections.QuickFixes { public sealed class PassParameterByValueQuickFix : QuickFixBase { + //TODO: Change this to IDeclarationFinderProvider once the FIXME below is handled. private readonly RubberduckParserState _state; public PassParameterByValueQuickFix(RubberduckParserState state) @@ -20,26 +22,26 @@ public PassParameterByValueQuickFix(RubberduckParserState state) _state = state; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { if (result.Target.ParentDeclaration.DeclarationType == DeclarationType.Event || _state.DeclarationFinder.FindAllInterfaceMembers().Contains(result.Target.ParentDeclaration)) { - FixMethods(result.Target); + FixMethods(result.Target, rewriteSession); } else { - FixMethod((VBAParser.ArgContext)result.Target.Context, result.QualifiedSelection); + FixMethod((VBAParser.ArgContext)result.Target.Context, result.QualifiedSelection, rewriteSession); } } public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.PassParameterByValueQuickFix; - private void FixMethods(Declaration target) + private void FixMethods(Declaration target, IRewriteSession rewriteSession) { var declarationParameters = - _state.AllUserDeclarations.Where(declaration => declaration.DeclarationType == DeclarationType.Parameter && - Equals(declaration.ParentDeclaration, target.ParentDeclaration)) + _state.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) + .Where(declaration => Equals(declaration.ParentDeclaration, target.ParentDeclaration)) .OrderBy(o => o.Selection.StartLine) .ThenBy(t => t.Selection.StartColumn) .ToList(); @@ -50,6 +52,7 @@ private void FixMethods(Declaration target) return; // should only happen if the parse results are stale; prevents a crash in that case } + //FIXME: Make this use the DeclarationFinder. var members = target.ParentDeclaration.DeclarationType == DeclarationType.Event ? _state.AllUserDeclarations.FindHandlersForEvent(target.ParentDeclaration) .Select(s => s.Item2) @@ -59,23 +62,23 @@ private void FixMethods(Declaration target) foreach (var member in members) { var parameters = - _state.AllUserDeclarations.Where(declaration => declaration.DeclarationType == DeclarationType.Parameter && - Equals(declaration.ParentDeclaration, member)) + _state.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) + .Where(declaration => Equals(declaration.ParentDeclaration, member)) .OrderBy(o => o.Selection.StartLine) .ThenBy(t => t.Selection.StartColumn) .ToList(); FixMethod((VBAParser.ArgContext)parameters[parameterIndex].Context, - parameters[parameterIndex].QualifiedSelection); + parameters[parameterIndex].QualifiedSelection, rewriteSession); } FixMethod((VBAParser.ArgContext)declarationParameters[parameterIndex].Context, - declarationParameters[parameterIndex].QualifiedSelection); + declarationParameters[parameterIndex].QualifiedSelection, rewriteSession); } - private void FixMethod(VBAParser.ArgContext context, QualifiedSelection qualifiedSelection) + private void FixMethod(VBAParser.ArgContext context, QualifiedSelection qualifiedSelection, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(qualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(qualifiedSelection.QualifiedName); if (context.BYREF() != null) { rewriter.Replace(context.BYREF(), Tokens.ByVal); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/QuickFixProvider.cs b/Rubberduck.CodeAnalysis/QuickFixes/QuickFixProvider.cs index a69621f420..4429adf703 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/QuickFixProvider.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/QuickFixProvider.cs @@ -4,19 +4,21 @@ using System.Linq; using Microsoft.CSharp.RuntimeBinder; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.VBA.Parsing; using Rubberduck.VBEditor; namespace Rubberduck.Inspections.QuickFixes { public class QuickFixProvider : IQuickFixProvider { - private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly Dictionary> _quickFixes = new Dictionary>(); - public QuickFixProvider(RubberduckParserState state, IEnumerable quickFixes) + public QuickFixProvider(IRewritingManager rewritingManager, IEnumerable quickFixes) { - _state = state; + _rewritingManager = rewritingManager; foreach (var quickFix in quickFixes) { foreach (var supportedInspection in quickFix.SupportedInspections) @@ -74,9 +76,22 @@ public void Fix(IQuickFix fix, IInspectionResult result) return; } - fix.Fix(result); - _state.RewriteAllModules(); - _state.OnParseRequested(this); + var rewriteSession = RewriteSession(fix.TargetCodeKind); + fix.Fix(result, rewriteSession); + rewriteSession.TryRewrite(); + } + + private IRewriteSession RewriteSession(CodeKind targetCodeKind) + { + switch (targetCodeKind) + { + case CodeKind.CodePaneCode: + return _rewritingManager.CheckOutCodePaneSession(); + case CodeKind.AttributesCode: + return _rewritingManager.CheckOutAttributesSession(); + default: + throw new NotSupportedException(nameof(targetCodeKind)); + } } public void FixInProcedure(IQuickFix fix, QualifiedMemberName? qualifiedMember, Type inspectionType, IEnumerable results) @@ -85,6 +100,12 @@ public void FixInProcedure(IQuickFix fix, QualifiedMemberName? qualifiedMember, var filteredResults = results.Where(result => result.Inspection.GetType() == inspectionType && result.QualifiedMemberName == qualifiedMember).ToList(); + if (!filteredResults.Any()) + { + return; + } + + var rewriteSession = RewriteSession(fix.TargetCodeKind); foreach (var result in filteredResults) { if (!CanFix(fix, result)) @@ -92,20 +113,21 @@ public void FixInProcedure(IQuickFix fix, QualifiedMemberName? qualifiedMember, continue; } - fix.Fix(result); - } - - if (filteredResults.Any()) - { - _state.RewriteAllModules(); - _state.OnParseRequested(this); + fix.Fix(result, rewriteSession); } + rewriteSession.TryRewrite(); } public void FixInModule(IQuickFix fix, QualifiedSelection selection, Type inspectionType, IEnumerable results) { var filteredResults = results.Where(result => result.Inspection.GetType() == inspectionType && result.QualifiedSelection.QualifiedName == selection.QualifiedName).ToList(); + if (!filteredResults.Any()) + { + return; + } + + var rewriteSession = RewriteSession(fix.TargetCodeKind); foreach (var result in filteredResults) { if (!CanFix(fix, result)) @@ -113,20 +135,21 @@ public void FixInModule(IQuickFix fix, QualifiedSelection selection, Type inspec continue; } - fix.Fix(result); - } - - if (filteredResults.Any()) - { - _state.RewriteAllModules(); - _state.OnParseRequested(this); + fix.Fix(result, rewriteSession); } + rewriteSession.TryRewrite(); } public void FixInProject(IQuickFix fix, QualifiedSelection selection, Type inspectionType, IEnumerable results) { var filteredResults = results.Where(result => result.Inspection.GetType() == inspectionType && result.QualifiedSelection.QualifiedName.ProjectId == selection.QualifiedName.ProjectId).ToList(); + if (!filteredResults.Any()) + { + return; + } + + var rewriteSession = RewriteSession(fix.TargetCodeKind); foreach (var result in filteredResults) { if (!CanFix(fix, result)) @@ -134,20 +157,21 @@ public void FixInProject(IQuickFix fix, QualifiedSelection selection, Type inspe continue; } - fix.Fix(result); - } - - if (filteredResults.Any()) - { - _state.RewriteAllModules(); - _state.OnParseRequested(this); + fix.Fix(result, rewriteSession); } + rewriteSession.TryRewrite(); } public void FixAll(IQuickFix fix, Type inspectionType, IEnumerable results) { var filteredResults = results.Where(result => result.Inspection.GetType() == inspectionType).ToArray(); + if (!filteredResults.Any()) + { + return; + } + + var rewriteSession = RewriteSession(fix.TargetCodeKind); foreach (var result in filteredResults) { if (!CanFix(fix, result)) @@ -155,14 +179,9 @@ public void FixAll(IQuickFix fix, Type inspectionType, IEnumerable annotation.AnnotationType == result.Properties.AnnotationType) .OrderBy(annotation => annotation.Context.Start.StartIndex) - .Skip(1); + .Skip(1) + .ToList(); var duplicatesPerAnnotationList = duplicateAnnotations .Select(annotation => (VBAParser.AnnotationListContext) annotation.Context.Parent) diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyElseBlockQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyElseBlockQuickFix.cs index 8d39887e7f..83ace83be6 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyElseBlockQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyElseBlockQuickFix.cs @@ -3,26 +3,20 @@ using Rubberduck.Parsing.Inspections.Abstract; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Rewriter; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { - class RemoveEmptyElseBlockQuickFix : QuickFixBase + public sealed class RemoveEmptyElseBlockQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveEmptyElseBlockQuickFix(RubberduckParserState state) + public RemoveEmptyElseBlockQuickFix() : base(typeof(EmptyElseBlockInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); - //dynamic used since it's not known at run-time - UpdateContext((dynamic)result.Context, rewriter); + UpdateContext((VBAParser.ElseBlockContext)result.Context, rewriter); } private void UpdateContext(VBAParser.ElseBlockContext context, IModuleRewriter rewriter) diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyIfBlockQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyIfBlockQuickFix.cs index 6760504a19..0a2f2fb065 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyIfBlockQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveEmptyIfBlockQuickFix.cs @@ -7,25 +7,33 @@ using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; using Rubberduck.Parsing.Rewriter; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { - internal sealed class RemoveEmptyIfBlockQuickFix : QuickFixBase + public sealed class RemoveEmptyIfBlockQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveEmptyIfBlockQuickFix(RubberduckParserState state) + public RemoveEmptyIfBlockQuickFix() : base(typeof(EmptyIfBlockInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); - - UpdateContext((dynamic)result.Context, rewriter); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); + + switch (result.Context) + { + case VBAParser.IfStmtContext ifContext: + UpdateContext(ifContext, rewriter); + break; + case VBAParser.IfWithEmptyThenContext ifWithEmtyThenContext: + UpdateContext(ifWithEmtyThenContext, rewriter); + break; + case VBAParser.ElseIfBlockContext elseIfBlockContext: + UpdateContext(elseIfBlockContext, rewriter); + break; + default: + throw new NotSupportedException(result.Context.GetType().ToString()); + } } private void UpdateContext(VBAParser.IfStmtContext context, IModuleRewriter rewriter) @@ -55,7 +63,7 @@ private void UpdateContext(VBAParser.IfStmtContext context, IModuleRewriter rewr } Debug.Assert(context.booleanExpression().children.Count == 1); - UpdateCondition((dynamic)context.booleanExpression().children[0], rewriter); + UpdateConditionDependingOnType((ParserRuleContext)context.booleanExpression().children[0], rewriter); } else { @@ -76,7 +84,7 @@ private void UpdateContext(VBAParser.IfWithEmptyThenContext context, IModuleRewr } Debug.Assert(context.booleanExpression().children.Count == 1); - UpdateCondition((dynamic)context.booleanExpression().children[0], rewriter); + UpdateConditionDependingOnType((ParserRuleContext)context.booleanExpression().children[0], rewriter); } private void UpdateContext(VBAParser.ElseIfBlockContext context, IModuleRewriter rewriter) @@ -89,6 +97,28 @@ private void UpdateContext(VBAParser.ElseIfBlockContext context, IModuleRewriter rewriter.Remove(context); } + private void UpdateConditionDependingOnType(ParserRuleContext context, IModuleRewriter rewriter) + { + switch (context) + { + case VBAParser.RelationalOpContext condition: + UpdateCondition(condition, rewriter); + break; + case VBAParser.LogicalNotOpContext condition: + UpdateCondition(condition, rewriter); + break; + case VBAParser.LogicalAndOpContext condition: + UpdateCondition(condition, rewriter); + break; + case VBAParser.LogicalOrOpContext condition: + UpdateCondition(condition, rewriter); + break; + default: + UpdateCondition(context, rewriter); + break; + } + } + private void UpdateCondition(VBAParser.RelationalOpContext condition, IModuleRewriter rewriter) { if (condition.EQ() != null) diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitByRefModifierQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitByRefModifierQuickFix.cs index f2cba020fc..f82e3fd211 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitByRefModifierQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitByRefModifierQuickFix.cs @@ -11,23 +11,23 @@ namespace Rubberduck.Inspections.QuickFixes { - public class RemoveExplicitByRefModifierQuickFix : QuickFixBase + public sealed class RemoveExplicitByRefModifierQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; + private readonly IDeclarationFinderProvider _declarationFinderProvider; - public RemoveExplicitByRefModifierQuickFix(RubberduckParserState state) + public RemoveExplicitByRefModifierQuickFix(IDeclarationFinderProvider declarationFinderProvider) : base(typeof(RedundantByRefModifierInspection)) { - _state = state; + _declarationFinderProvider = declarationFinderProvider; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var context = (VBAParser.ArgContext) result.Context; - RemoveByRefIdentifier(_state.GetRewriter(result.QualifiedSelection.QualifiedName), context); + RemoveByRefIdentifier(rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName), context); - var interfaceMembers = _state.DeclarationFinder.FindAllInterfaceMembers().ToArray(); + var interfaceMembers = _declarationFinderProvider.DeclarationFinder.FindAllInterfaceMembers().ToArray(); var matchingInterfaceMemberContext = interfaceMembers.Select(member => member.Context).FirstOrDefault(c => c == context.Parent.Parent); @@ -36,11 +36,11 @@ public override void Fix(IInspectionResult result) var interfaceParameterIndex = GetParameterIndex(context); var implementationMembers = - _state.DeclarationFinder.FindInterfaceImplementationMembers(interfaceMembers.First( + _declarationFinderProvider.DeclarationFinder.FindInterfaceImplementationMembers(interfaceMembers.First( member => member.Context == matchingInterfaceMemberContext)).ToHashSet(); var parameters = - _state.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) + _declarationFinderProvider.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) .Where(p => implementationMembers.Contains(p.ParentDeclaration)) .Cast() .ToArray(); @@ -52,7 +52,7 @@ public override void Fix(IInspectionResult result) if (parameterIndex == interfaceParameterIndex) { - RemoveByRefIdentifier(_state.GetRewriter(parameter), parameterContext); + RemoveByRefIdentifier(rewriteSession.CheckOutModuleRewriter(parameter.QualifiedModuleName), parameterContext); } } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitCallStatmentQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitCallStatementQuickFix.cs similarity index 71% rename from Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitCallStatmentQuickFix.cs rename to Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitCallStatementQuickFix.cs index 09e0a7b902..88601e6c97 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitCallStatmentQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitCallStatementQuickFix.cs @@ -2,23 +2,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { - public sealed class RemoveExplicitCallStatmentQuickFix : QuickFixBase + public sealed class RemoveExplicitCallStatementQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveExplicitCallStatmentQuickFix(RubberduckParserState state) + public RemoveExplicitCallStatementQuickFix() : base(typeof(ObsoleteCallStatementInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var context = (VBAParser.CallStmtContext)result.Context; rewriter.Remove(context.CALL()); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitLetStatementQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitLetStatementQuickFix.cs index bb891e8a67..286635fc54 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitLetStatementQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveExplicitLetStatementQuickFix.cs @@ -3,23 +3,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class RemoveExplicitLetStatementQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveExplicitLetStatementQuickFix(RubberduckParserState state) + public RemoveExplicitLetStatementQuickFix() : base(typeof(ObsoleteLetStatementInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var context = (VBAParser.LetStmtContext) result.Context; rewriter.Remove(context.LET()); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveLocalErrorQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveLocalErrorQuickFix.cs index 1982d006b4..aedb0bbbe4 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveLocalErrorQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveLocalErrorQuickFix.cs @@ -2,25 +2,21 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class RemoveLocalErrorQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveLocalErrorQuickFix(RubberduckParserState state) + public RemoveLocalErrorQuickFix() : base(typeof(OnLocalErrorInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var errorStmt = (VBAParser.OnErrorStmtContext)result.Context; - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.Replace(errorStmt.ON_LOCAL_ERROR(), Tokens.On + " " + Tokens.Error); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveOptionBaseStatementQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveOptionBaseStatementQuickFix.cs index 2b202958aa..a980f9d34c 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveOptionBaseStatementQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveOptionBaseStatementQuickFix.cs @@ -1,23 +1,19 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class RemoveOptionBaseStatementQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveOptionBaseStatementQuickFix(RubberduckParserState state) + public RemoveOptionBaseStatementQuickFix() : base(typeof(RedundantOptionInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.Remove(result.Context); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveStepOneQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveStepOneQuickFix.cs index 191e1ee909..676f013f1e 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveStepOneQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveStepOneQuickFix.cs @@ -2,19 +2,14 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; using Rubberduck.Parsing.Rewriter; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { - public class RemoveStepOneQuickFix : QuickFixBase + public sealed class RemoveStepOneQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveStepOneQuickFix(RubberduckParserState state) + public RemoveStepOneQuickFix() : base(typeof(StepOneIsRedundantInspection)) - { - _state = state; - } + {} public override bool CanFixInProcedure => true; @@ -24,9 +19,9 @@ public RemoveStepOneQuickFix(RubberduckParserState state) public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.RemoveStepOneQuickFix; - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - IModuleRewriter rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var context = result.Context; rewriter.Remove(context); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveStopKeywordQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveStopKeywordQuickFix.cs index b4bb155545..18929a6c69 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveStopKeywordQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveStopKeywordQuickFix.cs @@ -1,23 +1,19 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class RemoveStopKeywordQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveStopKeywordQuickFix(RubberduckParserState state) + public RemoveStopKeywordQuickFix() : base(typeof(StopKeywordInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.Remove(result.Context); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveTypeHintsQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveTypeHintsQuickFix.cs index 964837b6c6..c1ab54b6cf 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveTypeHintsQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveTypeHintsQuickFix.cs @@ -3,26 +3,22 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { public sealed class RemoveTypeHintsQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveTypeHintsQuickFix(RubberduckParserState state) + public RemoveTypeHintsQuickFix() : base(typeof(ObsoleteTypeHintInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { if (!string.IsNullOrWhiteSpace(result.Target.TypeHint)) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); var typeHintContext = result.Context.GetDescendent(); rewriter.Remove(typeHintContext); @@ -55,11 +51,11 @@ public override void Fix(IInspectionResult result) foreach (var reference in result.Target.References) { - var rewriter = _state.GetRewriter(reference.QualifiedModuleName); var context = reference.Context.GetDescendent(); if (context != null) { + var rewriter = rewriteSession.CheckOutModuleRewriter(reference.QualifiedModuleName); rewriter.Remove(context); } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedIdentifierQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedIdentifierQuickFix.cs index e85da40746..e2c0ab47fb 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedIdentifierQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedIdentifierQuickFix.cs @@ -1,23 +1,19 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class RemoveUnassignedIdentifierQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveUnassignedIdentifierQuickFix(RubberduckParserState state) + public RemoveUnassignedIdentifierQuickFix() : base(typeof(VariableNotAssignedInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); rewriter.Remove(result.Target); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedVariableUsageQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedVariableUsageQuickFix.cs index c84d702c57..89655ca69f 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedVariableUsageQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnassignedVariableUsageQuickFix.cs @@ -7,23 +7,19 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class RemoveUnassignedVariableUsageQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveUnassignedVariableUsageQuickFix(RubberduckParserState state) + public RemoveUnassignedVariableUsageQuickFix() : base(typeof(UnassignedVariableUsageInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); if (result.Context.Parent.Parent is VBAParser.WithStmtContext withContext) { diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedDeclarationQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedDeclarationQuickFix.cs index 395707237b..515bf8d2ac 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedDeclarationQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedDeclarationQuickFix.cs @@ -1,7 +1,7 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { @@ -10,17 +10,13 @@ namespace Rubberduck.Inspections.QuickFixes /// public sealed class RemoveUnusedDeclarationQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public RemoveUnusedDeclarationQuickFix(RubberduckParserState state) + public RemoveUnusedDeclarationQuickFix() : base(typeof(ConstantNotUsedInspection), typeof(ProcedureNotUsedInspection), typeof(VariableNotUsedInspection), typeof(LineLabelNotUsedInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); rewriter.Remove(result.Target); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedParameterQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedParameterQuickFix.cs index 77017f84c4..aa02c472ad 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedParameterQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RemoveUnusedParameterQuickFix.cs @@ -2,6 +2,7 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Interaction; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.RemoveParameters; using Rubberduck.UI.Refactorings.RemoveParameters; @@ -13,22 +14,27 @@ public sealed class RemoveUnusedParameterQuickFix : QuickFixBase { private readonly IVBE _vbe; private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public RemoveUnusedParameterQuickFix(IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public RemoveUnusedParameterQuickFix(IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) : base(typeof(ParameterNotUsedInspection)) { _vbe = vbe; _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } - public override void Fix(IInspectionResult result) + //The rewriteSession is optional since it is not used in this particular quickfix because it is a refactoring quickfix. + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession = null) { using (var dialog = new RemoveParametersDialog(new RemoveParametersViewModel(_state))) { - var refactoring = new RemoveParametersRefactoring(_vbe, - new RemoveParametersPresenterFactory(_vbe, dialog, _state, _messageBox)); + var refactoring = new RemoveParametersRefactoring( + _vbe, + new RemoveParametersPresenterFactory(_vbe, dialog, _state, _messageBox), + _rewritingManager); refactoring.QuickFix(_state, result.QualifiedSelection); } @@ -36,8 +42,8 @@ public override void Fix(IInspectionResult result) public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.RemoveUnusedParameterQuickFix; - public override bool CanFixInProcedure => true; - public override bool CanFixInModule => true; - public override bool CanFixInProject => true; + public override bool CanFixInProcedure => false; + public override bool CanFixInModule => false; + public override bool CanFixInProject => false; } } \ No newline at end of file diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RenameDeclarationQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RenameDeclarationQuickFix.cs index e7a308d5af..f2d6d2f70b 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RenameDeclarationQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RenameDeclarationQuickFix.cs @@ -4,6 +4,7 @@ using Rubberduck.Inspections.Inspections.Concrete; using Rubberduck.Interaction; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.Rename; using Rubberduck.Resources; @@ -16,25 +17,29 @@ public sealed class RenameDeclarationQuickFix : QuickFixBase { private readonly IVBE _vbe; private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public RenameDeclarationQuickFix(IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public RenameDeclarationQuickFix(IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) : base(typeof(HungarianNotationInspection), - typeof(UseMeaningfulNameInspection), - typeof(DefaultProjectNameInspection), - typeof(ExcelUdfNameIsValidCellReferenceInspection)) + typeof(UseMeaningfulNameInspection), + typeof(DefaultProjectNameInspection), + typeof(UnderscoreInPublicClassModuleMemberInspection), + typeof(ExcelUdfNameIsValidCellReferenceInspection)) { _vbe = vbe; _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } - public override void Fix(IInspectionResult result) + //The rewriteSession is optional since it is not used in this particular quickfix because it is a refactoring quickfix. + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession = null) { using (var view = new RenameDialog(new RenameViewModel(_state))) { var factory = new RenamePresenterFactory(_vbe, view, _state); - var refactoring = new RenameRefactoring(_vbe, factory, _messageBox, _state); + var refactoring = new RenameRefactoring(_vbe, factory, _messageBox, _state, _state.ProjectsProvider, _rewritingManager); refactoring.Refactor(result.Target); } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceEmptyStringLiteralStatementQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceEmptyStringLiteralStatementQuickFix.cs index cc62ac489b..27bfec7e25 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceEmptyStringLiteralStatementQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceEmptyStringLiteralStatementQuickFix.cs @@ -1,23 +1,19 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class ReplaceEmptyStringLiteralStatementQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ReplaceEmptyStringLiteralStatementQuickFix(RubberduckParserState state) + public ReplaceEmptyStringLiteralStatementQuickFix() : base(typeof(EmptyStringLiteralInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.Replace(result.Context, "vbNullString"); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceGlobalModifierQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceGlobalModifierQuickFix.cs index 2b1da070b5..0c31e2fc91 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceGlobalModifierQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceGlobalModifierQuickFix.cs @@ -4,23 +4,19 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class ReplaceGlobalModifierQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ReplaceGlobalModifierQuickFix(RubberduckParserState state) + public ReplaceGlobalModifierQuickFix() : base(typeof(ObsoleteGlobalInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); rewriter.Replace(((ParserRuleContext)result.Context.Parent.Parent).GetDescendent(), Tokens.Public); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceIfElseWithConditionalStatementQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceIfElseWithConditionalStatementQuickFix.cs index 502957de05..3020fc05bd 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceIfElseWithConditionalStatementQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceIfElseWithConditionalStatementQuickFix.cs @@ -3,22 +3,17 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.Symbols; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class ReplaceIfElseWithConditionalStatementQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ReplaceIfElseWithConditionalStatementQuickFix(RubberduckParserState state) + public ReplaceIfElseWithConditionalStatementQuickFix() : base(typeof(BooleanAssignedInIfElseInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var ifContext = (VBAParser.IfStmtContext) result.Context; var letStmt = ifContext.block().GetDescendent(); @@ -30,7 +25,7 @@ public override void Fix(IInspectionResult result) conditional = $"Not ({conditional})"; } - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.Replace(result.Context, $"{letStmt.lExpression().GetText()} = {conditional}"); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteCommentMarkerQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteCommentMarkerQuickFix.cs index be1aba443a..cc9129aef3 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteCommentMarkerQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteCommentMarkerQuickFix.cs @@ -2,23 +2,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class ReplaceObsoleteCommentMarkerQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ReplaceObsoleteCommentMarkerQuickFix(RubberduckParserState state) + public ReplaceObsoleteCommentMarkerQuickFix() : base(typeof(ObsoleteCommentSyntaxInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var context = (VBAParser.RemCommentContext) result.Context; rewriter.Replace(context.REM(), "'"); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteErrorStatementQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteErrorStatementQuickFix.cs index 2006d98ab9..35364228a8 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteErrorStatementQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/ReplaceObsoleteErrorStatementQuickFix.cs @@ -2,23 +2,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class ReplaceObsoleteErrorStatementQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public ReplaceObsoleteErrorStatementQuickFix(RubberduckParserState state) + public ReplaceObsoleteErrorStatementQuickFix() : base(typeof(ObsoleteErrorSyntaxInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var context = (VBAParser.ErrorStmtContext) result.Context; rewriter.Replace(context.ERROR(), "Err.Raise"); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/RestoreErrorHandlingQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/RestoreErrorHandlingQuickFix.cs index 02f053724c..b96dc94f0e 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/RestoreErrorHandlingQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/RestoreErrorHandlingQuickFix.cs @@ -5,22 +5,19 @@ using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { - public class RestoreErrorHandlingQuickFix : QuickFixBase + public sealed class RestoreErrorHandlingQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; private const string LabelPrefix = "ErrorHandler"; - public RestoreErrorHandlingQuickFix(RubberduckParserState state) + public RestoreErrorHandlingQuickFix() : base(typeof(UnhandledOnErrorResumeNextInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var exitStatement = "Exit "; VBAParser.BlockContext block; @@ -52,7 +49,7 @@ public override void Fix(IInspectionResult result) block = bodyElementContext.subStmt().block(); } - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); var context = (VBAParser.OnErrorStmtContext)result.Context; var labels = bodyElementContext.GetDescendents().ToArray(); var maximumExistingLabelIndex = GetMaximumExistingLabelIndex(labels); diff --git a/Rubberduck.CodeAnalysis/QuickFixes/SetExplicitVariantReturnTypeQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/SetExplicitVariantReturnTypeQuickFix.cs index b7247fdfdd..06c5d27bed 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/SetExplicitVariantReturnTypeQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/SetExplicitVariantReturnTypeQuickFix.cs @@ -2,24 +2,20 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { public sealed class SetExplicitVariantReturnTypeQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public SetExplicitVariantReturnTypeQuickFix(RubberduckParserState state) + public SetExplicitVariantReturnTypeQuickFix() :base(typeof(ImplicitVariantReturnTypeInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); const string asTypeClause = " As Variant"; switch (result.Target.DeclarationType) diff --git a/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitByRefModifierQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitByRefModifierQuickFix.cs index 836f7539d2..c6d18d0484 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitByRefModifierQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitByRefModifierQuickFix.cs @@ -11,23 +11,23 @@ namespace Rubberduck.Inspections.QuickFixes { - public class SpecifyExplicitByRefModifierQuickFix : QuickFixBase + public sealed class SpecifyExplicitByRefModifierQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; + private readonly IDeclarationFinderProvider _declarationFinderProvider; - public SpecifyExplicitByRefModifierQuickFix(RubberduckParserState state) + public SpecifyExplicitByRefModifierQuickFix(IDeclarationFinderProvider declarationFinderProvider) : base(typeof(ImplicitByRefModifierInspection)) { - _state = state; + _declarationFinderProvider = declarationFinderProvider; } - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { var context = (VBAParser.ArgContext)result.Context; - AddByRefIdentifier(_state.GetRewriter(result.QualifiedSelection.QualifiedName), context); + AddByRefIdentifier(rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName), context); - var interfaceMembers = _state.DeclarationFinder.FindAllInterfaceMembers().ToArray(); + var interfaceMembers = _declarationFinderProvider.DeclarationFinder.FindAllInterfaceMembers().ToArray(); var matchingInterfaceMemberContext = interfaceMembers.Select(member => member.Context).FirstOrDefault(c => c == context.Parent.Parent); @@ -39,11 +39,11 @@ public override void Fix(IInspectionResult result) var interfaceParameterIndex = GetParameterIndex(context); var implementationMembers = - _state.DeclarationFinder.FindInterfaceImplementationMembers(interfaceMembers.First( + _declarationFinderProvider.DeclarationFinder.FindInterfaceImplementationMembers(interfaceMembers.First( member => member.Context == matchingInterfaceMemberContext)).ToHashSet(); var parameters = - _state.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) + _declarationFinderProvider.DeclarationFinder.UserDeclarations(DeclarationType.Parameter) .Where(p => implementationMembers.Contains(p.ParentDeclaration)) .Cast() .ToArray(); @@ -55,7 +55,7 @@ public override void Fix(IInspectionResult result) if (parameterIndex == interfaceParameterIndex) { - AddByRefIdentifier(_state.GetRewriter(parameter), parameterContext); + AddByRefIdentifier(rewriteSession.CheckOutModuleRewriter(parameter.QualifiedModuleName), parameterContext); } } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitPublicModifierQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitPublicModifierQuickFix.cs index 0192284930..5c95e0e80b 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitPublicModifierQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/SpecifyExplicitPublicModifierQuickFix.cs @@ -1,23 +1,19 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class SpecifyExplicitPublicModifierQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public SpecifyExplicitPublicModifierQuickFix(RubberduckParserState state) + public SpecifyExplicitPublicModifierQuickFix() : base(typeof(ImplicitPublicMemberInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); rewriter.InsertBefore(result.Context.Start.TokenIndex, "Public "); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/SplitMultipleDeclarationsQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/SplitMultipleDeclarationsQuickFix.cs index ee6a27909b..fbd2796e6e 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/SplitMultipleDeclarationsQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/SplitMultipleDeclarationsQuickFix.cs @@ -1,31 +1,40 @@ +using System; using System.Text; +using Antlr4.Runtime; using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class SplitMultipleDeclarationsQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public SplitMultipleDeclarationsQuickFix(RubberduckParserState state) + public SplitMultipleDeclarationsQuickFix() : base(typeof(MultipleDeclarationsInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - dynamic context = result.Context is VBAParser.ConstStmtContext + var context = result.Context is VBAParser.ConstStmtContext ? result.Context - : result.Context.Parent; + : (ParserRuleContext)result.Context.Parent; - var declarationsText = GetDeclarationsText(context); + string declarationsText; + switch (context) + { + case VBAParser.ConstStmtContext consts: + declarationsText = GetDeclarationsText(consts); + break; + case VBAParser.VariableStmtContext variables: + declarationsText = GetDeclarationsText(variables); + break; + default: + throw new NotSupportedException(); + } - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.Replace(context, declarationsText); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/UntypedFunctionUsageQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/UntypedFunctionUsageQuickFix.cs index 35f113ef81..5a2da9f884 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/UntypedFunctionUsageQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/UntypedFunctionUsageQuickFix.cs @@ -5,23 +5,19 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class UntypedFunctionUsageQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public UntypedFunctionUsageQuickFix(RubberduckParserState state) + public UntypedFunctionUsageQuickFix() : base(typeof(UntypedFunctionUsageInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.InsertAfter(result.Context.Stop.TokenIndex, "$"); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/UseSetKeywordForObjectAssignmentQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/UseSetKeywordForObjectAssignmentQuickFix.cs index 541d6b361f..fa50da1c06 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/UseSetKeywordForObjectAssignmentQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/UseSetKeywordForObjectAssignmentQuickFix.cs @@ -1,23 +1,19 @@ using Rubberduck.Inspections.Abstract; using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Inspections.Abstract; -using Rubberduck.Parsing.VBA; +using Rubberduck.Parsing.Rewriter; namespace Rubberduck.Inspections.QuickFixes { public sealed class UseSetKeywordForObjectAssignmentQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public UseSetKeywordForObjectAssignmentQuickFix(RubberduckParserState state) + public UseSetKeywordForObjectAssignmentQuickFix() : base(typeof(ObjectVariableNotSetInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var rewriter = _state.GetRewriter(result.QualifiedSelection.QualifiedName); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName); rewriter.InsertBefore(result.Context.Start.TokenIndex, "Set "); } diff --git a/Rubberduck.CodeAnalysis/QuickFixes/WriteOnlyPropertyQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/WriteOnlyPropertyQuickFix.cs index 00966ef0d6..05bd4916c6 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/WriteOnlyPropertyQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/WriteOnlyPropertyQuickFix.cs @@ -4,24 +4,20 @@ using Rubberduck.Inspections.Concrete; using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.Inspections.Abstract; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; -using Rubberduck.Parsing.VBA; namespace Rubberduck.Inspections.QuickFixes { public sealed class WriteOnlyPropertyQuickFix : QuickFixBase { - private readonly RubberduckParserState _state; - - public WriteOnlyPropertyQuickFix(RubberduckParserState state) + public WriteOnlyPropertyQuickFix() : base(typeof(WriteOnlyPropertyInspection)) - { - _state = state; - } + {} - public override void Fix(IInspectionResult result) + public override void Fix(IInspectionResult result, IRewriteSession rewriteSession) { - var parameters = ((IParameterizedDeclaration) result.Target).Parameters.Cast().ToList(); + var parameters = ((IParameterizedDeclaration) result.Target).Parameters.ToList(); var signatureParams = parameters.Except(new[] {parameters.Last()}).Select(GetParamText); @@ -31,7 +27,7 @@ public override void Fix(IInspectionResult result) parameters.Last().AsTypeName, Environment.NewLine); - var rewriter = _state.GetRewriter(result.Target); + var rewriter = rewriteSession.CheckOutModuleRewriter(result.Target.QualifiedModuleName); rewriter.InsertBefore(result.Target.Context.Start.TokenIndex, propertyGet); } diff --git a/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj b/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj index 710227885b..08f91a0755 100644 --- a/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj +++ b/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.csproj @@ -1,5 +1,5 @@  - + Rubberduck.CodeAnalysis Assembly Containing the Code Analysis features exposed by Rubberduck diff --git a/Rubberduck.Core/AutoComplete/AutoCompleteHandlerBase.cs b/Rubberduck.Core/AutoComplete/AutoCompleteHandlerBase.cs index 7dd5eabfcb..2eb2da1fec 100644 --- a/Rubberduck.Core/AutoComplete/AutoCompleteHandlerBase.cs +++ b/Rubberduck.Core/AutoComplete/AutoCompleteHandlerBase.cs @@ -1,7 +1,4 @@ -using System; -using System.Linq; -using Rubberduck.Parsing.VBA.Extensions; -using Rubberduck.Settings; +using Rubberduck.Settings; using Rubberduck.VBEditor; using Rubberduck.VBEditor.Events; using Rubberduck.VBEditor.SourceCodeHandling; @@ -17,6 +14,6 @@ protected AutoCompleteHandlerBase(ICodePaneHandler pane) protected ICodePaneHandler CodePaneHandler { get; } - public abstract CodeString Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings); + public abstract bool Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings, out CodeString result); } } \ No newline at end of file diff --git a/Rubberduck.Core/AutoComplete/Service/AutoCompleteService.cs b/Rubberduck.Core/AutoComplete/Service/AutoCompleteService.cs index a45c93944c..251cd628e3 100644 --- a/Rubberduck.Core/AutoComplete/Service/AutoCompleteService.cs +++ b/Rubberduck.Core/AutoComplete/Service/AutoCompleteService.cs @@ -57,8 +57,8 @@ private void Enable() if (!_enabled) { - VBENativeServices.KeyDown += HandleKeyDown; - VBENativeServices.IntelliSenseChanged += HandleIntelliSenseChanged; + VbeNativeServices.KeyDown += HandleKeyDown; + VbeNativeServices.IntelliSenseChanged += HandleIntelliSenseChanged; _enabled = true; } } @@ -67,8 +67,8 @@ private void Disable() { if (_enabled && _initialized) { - VBENativeServices.KeyDown -= HandleKeyDown; - VBENativeServices.IntelliSenseChanged -= HandleIntelliSenseChanged; + VbeNativeServices.KeyDown -= HandleKeyDown; + VbeNativeServices.IntelliSenseChanged -= HandleIntelliSenseChanged; _enabled = false; _popupShown = false; } @@ -135,11 +135,13 @@ private void HandleKeyDown(object sender, AutoCompleteEventArgs e) foreach (var handler in _handlers) { - var result = handler.Handle(e, _settings); - if (result != null && e.Handled) + if (!handler.Handle(e, _settings, out _)) { - return; + continue; } + + e.Handled = true; + return; } } diff --git a/Rubberduck.Core/AutoComplete/Service/SelfClosingPair.cs b/Rubberduck.Core/AutoComplete/Service/SelfClosingPair.cs index e2157d98f3..1266439f2b 100644 --- a/Rubberduck.Core/AutoComplete/Service/SelfClosingPair.cs +++ b/Rubberduck.Core/AutoComplete/Service/SelfClosingPair.cs @@ -1,6 +1,9 @@ -namespace Rubberduck.AutoComplete.Service +using Rubberduck.VBEditor; +using System; + +namespace Rubberduck.AutoComplete.Service { - public class SelfClosingPair + public class SelfClosingPair : IEquatable { public SelfClosingPair(char opening, char closing) { @@ -15,5 +18,15 @@ public SelfClosingPair(char opening, char closing) /// True if is the same as . /// public bool IsSymetric => OpeningChar == ClosingChar; + + public bool Equals(SelfClosingPair other) => other?.OpeningChar == OpeningChar && + other.ClosingChar == ClosingChar; + + public override bool Equals(object obj) + { + return obj is SelfClosingPair scp && Equals(scp); + } + + public override int GetHashCode() => HashCode.Compute(OpeningChar, ClosingChar); } } \ No newline at end of file diff --git a/Rubberduck.Core/AutoComplete/Service/SelfClosingPairCompletionService.cs b/Rubberduck.Core/AutoComplete/Service/SelfClosingPairCompletionService.cs index 24b0fff2ee..fbe81b7f65 100644 --- a/Rubberduck.Core/AutoComplete/Service/SelfClosingPairCompletionService.cs +++ b/Rubberduck.Core/AutoComplete/Service/SelfClosingPairCompletionService.cs @@ -12,18 +12,25 @@ namespace Rubberduck.AutoComplete.Service { public class SelfClosingPairCompletionService { + /* + // note: this works... but the VBE makes an annoying DING! when the command isn't available. + // todo: implement our own intellisense, then uncomment this code. private readonly IShowIntelliSenseCommand _showIntelliSense; public SelfClosingPairCompletionService(IShowIntelliSenseCommand showIntelliSense) { _showIntelliSense = showIntelliSense; } + */ - public CodeString Execute(SelfClosingPair pair, CodeString original, char input) + public bool Execute(SelfClosingPair pair, CodeString original, char input, out CodeString result) { + result = null; + var previousCharIsClosingChar = original.CaretPosition.StartColumn > 0 && original.CaretLine[original.CaretPosition.StartColumn - 1] == pair.ClosingChar; + var nextCharIsClosingChar = original.CaretPosition.StartColumn < original.CaretLine.Length && original.CaretLine[original.CaretPosition.StartColumn] == pair.ClosingChar; @@ -33,49 +40,45 @@ public CodeString Execute(SelfClosingPair pair, CodeString original, char input) previousCharIsClosingChar && !nextCharIsClosingChar || original.IsComment || (original.IsInsideStringLiteral && !nextCharIsClosingChar)) { - return null; + return false; } if (input == pair.OpeningChar) { - var result = HandleOpeningChar(pair, original); - return result; + return HandleOpeningChar(pair, original, out result); } - + if (input == pair.ClosingChar) { - return HandleClosingChar(pair, original); + return HandleClosingChar(pair, original, out result); } if (input == '\b') { - return Execute(pair, original, Keys.Back); + return Execute(pair, original, Keys.Back, out result); } - return null; + return false; } - public CodeString Execute(SelfClosingPair pair, CodeString original, Keys input) + public bool Execute(SelfClosingPair pair, CodeString original, Keys input, out CodeString result) { + result = null; if (original.IsComment) { - return null; + // not handling backspace in comments + return false; } - if (input == Keys.Back) - { - return HandleBackspace(pair, original); - } - - return null; + return input == Keys.Back && HandleBackspace(pair, original, out result); } - private CodeString HandleOpeningChar(SelfClosingPair pair, CodeString original) + private bool HandleOpeningChar(SelfClosingPair pair, CodeString original, out CodeString result) { var nextPosition = original.CaretPosition.ShiftRight(); var autoCode = new string(new[] { pair.OpeningChar, pair.ClosingChar }); var lines = original.Lines; - var line = lines[original.CaretPosition.StartLine]; + var line = original.CaretLine; string newCode; if (string.IsNullOrEmpty(line)) @@ -94,14 +97,17 @@ private CodeString HandleOpeningChar(SelfClosingPair pair, CodeString original) } lines[original.CaretPosition.StartLine] = newCode; - return new CodeString(string.Join("\r\n", lines), nextPosition, new Selection(original.SnippetPosition.StartLine, 1, original.SnippetPosition.EndLine, 1)); + result = new CodeString(string.Join("\r\n", lines), nextPosition, new Selection(original.SnippetPosition.StartLine, 1, original.SnippetPosition.EndLine, 1)); + return true; } - private CodeString HandleClosingChar(SelfClosingPair pair, CodeString original) + private bool HandleClosingChar(SelfClosingPair pair, CodeString original, out CodeString result) { + result = null; if (pair.IsSymetric) { - return null; + // a symetric pair would have already been handled with the opening character. + return false; } var nextIsClosingChar = original.CaretLine.Length > original.CaretCharIndex && @@ -111,18 +117,16 @@ private CodeString HandleClosingChar(SelfClosingPair pair, CodeString original) var nextPosition = original.CaretPosition.ShiftRight(); var newCode = original.Code; - return new CodeString(newCode, nextPosition, new Selection(original.SnippetPosition.StartLine, 1, original.SnippetPosition.EndLine, 1)); + result = new CodeString(newCode, nextPosition, new Selection(original.SnippetPosition.StartLine, 1, original.SnippetPosition.EndLine, 1)); + return true; } - return null; - } - private CodeString HandleBackspace(SelfClosingPair pair, CodeString original) - { - return DeleteMatchingTokens(pair, original); + return false; } - private CodeString DeleteMatchingTokens(SelfClosingPair pair, CodeString original) + private bool HandleBackspace(SelfClosingPair pair, CodeString original, out CodeString result) { + result = null; var position = original.CaretPosition; var lines = original.Lines; @@ -130,7 +134,7 @@ private CodeString DeleteMatchingTokens(SelfClosingPair pair, CodeString origina if (line.Length == 0) { // nothing to delete at caret position... bail out. - return null; + return false; } var previous = Math.Max(0, position.StartColumn - 1); @@ -146,24 +150,25 @@ private CodeString DeleteMatchingTokens(SelfClosingPair pair, CodeString origina if (line.Length == 2) { // entire line consists in the self-closing pair itself. - return new CodeString(string.Empty, default, Selection.Empty.ShiftRight()); + result = new CodeString(string.Empty, default, Selection.Empty.ShiftRight()); } // simple case; caret is between the opening and closing chars - remove both. lines[original.CaretPosition.StartLine] = line.Remove(previous, 2); - return new CodeString(string.Join("\r\n", lines), original.CaretPosition.ShiftLeft(), original.SnippetPosition); + result = new CodeString(string.Join("\r\n", lines), original.CaretPosition.ShiftLeft(), original.SnippetPosition); } if (previous < line.Length - 1 && previousChar == pair.OpeningChar) { - return DeleteMatchingTokensMultiline(pair, original); + return DeleteMatchingTokensMultiline(pair, original, out result); } - return null; + return result != null; } - private CodeString DeleteMatchingTokensMultiline(SelfClosingPair pair, CodeString original) + private bool DeleteMatchingTokensMultiline(SelfClosingPair pair, CodeString original, out CodeString result) { + result = null; var position = original.CaretPosition; var lines = original.Lines; var line = lines[original.CaretPosition.StartLine]; @@ -177,7 +182,7 @@ private CodeString DeleteMatchingTokensMultiline(SelfClosingPair pair, CodeStrin if (closingTokenPosition == default) { // could not locate the closing token... bail out. - return null; + return false; } var closingLine = lines[closingTokenPosition.EndLine].Remove(closingTokenPosition.StartColumn, 1); @@ -243,8 +248,9 @@ private CodeString DeleteMatchingTokensMultiline(SelfClosingPair pair, CodeStrin // remove any dangling empty lines... lines = lines.Where((x, i) => i <= position.StartLine || !string.IsNullOrWhiteSpace(x)).ToArray(); - return new CodeString(string.Join("\r\n", lines), finalCaretPosition, + result = new CodeString(string.Join("\r\n", lines), finalCaretPosition, new Selection(original.SnippetPosition.StartLine, 1, original.SnippetPosition.EndLine, 1)); + return true; } private static Selection HandleBackspaceContinuations(string[] nonEmptyLines, Selection finalCaretPosition) diff --git a/Rubberduck.Core/AutoComplete/Service/SelfClosingPairHandler.cs b/Rubberduck.Core/AutoComplete/Service/SelfClosingPairHandler.cs index f50212287f..253ca22e45 100644 --- a/Rubberduck.Core/AutoComplete/Service/SelfClosingPairHandler.cs +++ b/Rubberduck.Core/AutoComplete/Service/SelfClosingPairHandler.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Windows.Forms; +using System.Linq; using Rubberduck.Settings; using Rubberduck.VBEditor; using Rubberduck.VBEditor.Events; @@ -10,86 +10,126 @@ namespace Rubberduck.AutoComplete.Service { public class SelfClosingPairHandler : AutoCompleteHandlerBase { - private static readonly IEnumerable SelfClosingPairs = new List - { - new SelfClosingPair('(', ')'), - new SelfClosingPair('"', '"'), - new SelfClosingPair('[', ']'), - new SelfClosingPair('{', '}'), - }; + private const int MaximumLines = 25; + private readonly IReadOnlyList _selfClosingPairs; + private readonly IDictionary _scpInputLookup; private readonly SelfClosingPairCompletionService _scpService; public SelfClosingPairHandler(ICodePaneHandler pane, SelfClosingPairCompletionService scpService) : base(pane) { + _selfClosingPairs = new[] + { + new SelfClosingPair('(', ')'), + new SelfClosingPair('"', '"'), + new SelfClosingPair('[', ']'), + new SelfClosingPair('{', '}'), + }; + _scpInputLookup = _selfClosingPairs + .Select(p => new {Key = p.OpeningChar, Pair = p}) + .Union(_selfClosingPairs.Where(p => !p.IsSymetric).Select(p => new {Key = p.ClosingChar, Pair = p})) + .ToDictionary(p => p.Key, p => p.Pair); + _scpService = scpService; } - public override CodeString Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings) + public override bool Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings, out CodeString result) { + result = null; + if (!_scpInputLookup.TryGetValue(e.Character, out var pair) && e.Character != '\b') + { + return false; + } + var original = CodePaneHandler.GetCurrentLogicalLine(e.Module); - foreach (var pair in SelfClosingPairs) + if (original == null || original.Lines.Length == MaximumLines) { - var isPresent = original.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}"); + // selection spans more than a single logical line, or + // logical line somehow spans more than the maximum number of physical lines in a logical line of code (25). + return false; + } - var result = ExecuteSelfClosingPair(e, original, pair); - if (result == null) + if (pair != null) + { + if (!HandleInternal(e, original, pair, out result)) { - continue; + return false; } - - var prettified = CodePaneHandler.Prettify(e.Module, original); - if (!isPresent && original.CaretLine.Length + 2 == prettified.CaretLine.Length && - prettified.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}")) + } + else if (e.Character == '\b') + { + foreach (var scp in _selfClosingPairs) { - // prettifier just added the pair for us; likely a Sub or Function statement. - prettified = original; // pretend this didn't happen. note: probably breaks if original has extra whitespace. + if (HandleInternal(e, original, scp, out result)) + { + break; + } } - result = ExecuteSelfClosingPair(e, prettified, pair); if (result == null) { - continue; + return false; } + } - result = CodePaneHandler.Prettify(e.Module, result); + var snippetPosition = new Selection(result.SnippetPosition.StartLine, 1, result.SnippetPosition.EndLine, 1); + result = new CodeString(result.Code, result.CaretPosition, snippetPosition); - var currentLine = result.Lines[result.CaretPosition.StartLine]; - if (!string.IsNullOrWhiteSpace(currentLine) && - currentLine.EndsWith(" ") && - result.CaretPosition.StartColumn == currentLine.Length) - { - result = result.ReplaceLine(result.CaretPosition.StartLine, currentLine.TrimEnd()); - } + e.Handled = true; + return true; + } - if (pair.OpeningChar == '(' && e.Character != '\b' && !result.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}")) - { - // VBE eats it. just bail out. - return null; - } + private bool HandleInternal(AutoCompleteEventArgs e, CodeString original, SelfClosingPair pair, out CodeString result) + { + if (!original.CaretPosition.IsSingleCharacter) + { + // todo: WrapSelection? + result = null; + return false; + } - e.Handled = true; - result = new CodeString(result.Code, result.CaretPosition, new Selection(result.SnippetPosition.StartLine, 1, result.SnippetPosition.EndLine, 1)); - return result; + var isPresent = original.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}"); + + if (!_scpService.Execute(pair, original, e.Character, out result)) + { + return false; } - return null; - } + var prettified = CodePaneHandler.Prettify(e.Module, original); + if (!isPresent && original.CaretLine.Length + 2 == prettified.CaretLine.Length && + prettified.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}")) + { + // prettifier just added the pair for us; likely a Sub or Function statement. + prettified = original; // pretend this didn't happen. note: probably breaks if original has extra whitespace. + } - private CodeString ExecuteSelfClosingPair(AutoCompleteEventArgs e, CodeString original, SelfClosingPair pair) - { - CodeString result; - if (e.Character == '\b' && original.CaretPosition.StartColumn > 1) + if (!_scpService.Execute(pair, prettified, e.Character, out result)) + { + return false; + } + + result = CodePaneHandler.Prettify(e.Module, result); + + var currentLine = result.Lines[result.CaretPosition.StartLine]; + if (!string.IsNullOrWhiteSpace(currentLine) && + currentLine.EndsWith(" ") && + result.CaretPosition.StartColumn == currentLine.Length) { - result = _scpService.Execute(pair, original, Keys.Back); + result = result.ReplaceLine(result.CaretPosition.StartLine, currentLine.TrimEnd()); } - else + + if (pair.OpeningChar == '(' && + e.Character == pair.OpeningChar && + !result.CaretLine.EndsWith($"{pair.OpeningChar}{pair.ClosingChar}")) { - result = _scpService.Execute(pair, original, e.Character); + // VBE eats it. bail out but still swallow the keypress, since we've already re-prettified. + e.Handled = true; + result = null; + return false; } - return result; + return true; } } } \ No newline at end of file diff --git a/Rubberduck.Core/AutoComplete/Service/ShowIntelliSenseCommand.cs b/Rubberduck.Core/AutoComplete/Service/ShowIntelliSenseCommand.cs index 4663c29b39..63b7d057ad 100644 --- a/Rubberduck.Core/AutoComplete/Service/ShowIntelliSenseCommand.cs +++ b/Rubberduck.Core/AutoComplete/Service/ShowIntelliSenseCommand.cs @@ -7,6 +7,9 @@ namespace Rubberduck.AutoComplete.Service { public interface IShowIntelliSenseCommand { + /// + /// WARNING! Makes an utterly annoying DING! in the VBE if the "QuickInfo" command is unavailable. + /// void Execute(); } diff --git a/Rubberduck.Core/AutoComplete/Service/SmartConcatenationHandler.cs b/Rubberduck.Core/AutoComplete/Service/SmartConcatenationHandler.cs index b52ddb4d13..042438adaf 100644 --- a/Rubberduck.Core/AutoComplete/Service/SmartConcatenationHandler.cs +++ b/Rubberduck.Core/AutoComplete/Service/SmartConcatenationHandler.cs @@ -16,17 +16,21 @@ public SmartConcatenationHandler(ICodePaneHandler pane) { } - public override CodeString Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings) + public override bool Handle(AutoCompleteEventArgs e, AutoCompleteSettings settings, out CodeString result) { + result = null; if (e.Character != '\r' || (!settings?.SmartConcat.IsEnabled ?? true)) { - return null; + return false; } var currentContent = CodePaneHandler.GetCurrentLogicalLine(e.Module); - if (!currentContent.IsInsideStringLiteral) + if ((!currentContent?.IsInsideStringLiteral ?? true) + || currentContent.Lines.Length >= settings.SmartConcat.ConcatMaxLines) { - return null; + // selection spans more than a single logical line, or spans too many lines to be legal; + // too many line continuations throws COMException if we attempt to modify. + return false; } var lastIndexLeftOfCaret = currentContent.CaretLine.Length > 2 ? currentContent.CaretLine.Substring(0, currentContent.CaretPosition.StartColumn).LastIndexOf('"') : 0; @@ -51,16 +55,16 @@ public override CodeString Handle(AutoCompleteEventArgs e, AutoCompleteSettings var newPosition = new Selection(newContent.CaretPosition.StartLine + 1, indent + 1); e.Handled = true; - var result = new CodeString(newContent.Code, newPosition, + result = new CodeString(newContent.Code, newPosition, new Selection(newContent.SnippetPosition.StartLine, 1, newContent.SnippetPosition.EndLine, 1)); CodePaneHandler.SubstituteCode(e.Module, result); var finalSelection = new Selection(result.SnippetPosition.StartLine, 1).Offset(result.CaretPosition); CodePaneHandler.SetSelection(e.Module, finalSelection); - return result; + return true; } - return null; + return false; } } } \ No newline at end of file diff --git a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerComponentViewModel.cs b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerComponentViewModel.cs index 1513beb767..21316d0a82 100644 --- a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerComponentViewModel.cs +++ b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerComponentViewModel.cs @@ -4,12 +4,14 @@ using System.Linq; using System.Runtime.InteropServices; using System.Windows.Media.Imaging; +using NLog; using Rubberduck.Parsing.Symbols; using Rubberduck.VBEditor; using Rubberduck.Parsing.Annotations; using Rubberduck.VBEditor.ComManagement; using Rubberduck.VBEditor.SafeComWrappers; using Rubberduck.Resources.CodeExplorer; +using Rubberduck.VBEditor.SafeComWrappers.Abstract; namespace Rubberduck.Navigation.CodeExplorer { @@ -36,13 +38,15 @@ public class CodeExplorerComponentViewModel : CodeExplorerItemViewModel, ICodeEx }; private readonly IProjectsProvider _projectsProvider; + private readonly IVBE _vbe; - public CodeExplorerComponentViewModel(CodeExplorerItemViewModel parent, Declaration declaration, IEnumerable declarations, IProjectsProvider projectsProvider) + public CodeExplorerComponentViewModel(CodeExplorerItemViewModel parent, Declaration declaration, IEnumerable declarations, IProjectsProvider projectsProvider, IVBE vbe) { Parent = parent; Declaration = declaration; _projectsProvider = projectsProvider; - + _vbe = vbe; + _icon = Icons.ContainsKey(DeclarationType) ? Icons[DeclarationType] : GetImageSource(CodeExplorerUI.status_offline); @@ -65,15 +69,19 @@ public CodeExplorerComponentViewModel(CodeExplorerItemViewModel parent, Declarat switch (qualifiedModuleName.ComponentType) { case ComponentType.Document: - var component = _projectsProvider.Component(qualifiedModuleName); - string parenthesizedName; - using (var properties = component.Properties) - using (var nameProperty = properties["Name"]) + var parenthesizedName = string.Empty; + var state = DocumentState.Inaccessible; + using (var app = _vbe.HostApplication()) { - parenthesizedName = nameProperty.Value.ToString() ?? string.Empty; + if (app != null) + { + var document = app.GetDocument(qualifiedModuleName); + parenthesizedName = document?.DocumentName ?? string.Empty; + state = document?.State ?? DocumentState.Inaccessible; + } } - - if (ContainsBuiltinDocumentPropertiesProperty()) + + if (state == DocumentState.DesignView && ContainsBuiltinDocumentPropertiesProperty()) { CodeExplorerItemViewModel node = this; while (node.Parent != null) @@ -85,7 +93,10 @@ public CodeExplorerComponentViewModel(CodeExplorerItemViewModel parent, Declarat } else { - _name += " (" + parenthesizedName + ")"; + if (!string.IsNullOrWhiteSpace(parenthesizedName)) + { + _name += " (" + parenthesizedName + ")"; + } } break; diff --git a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs index 05e3479681..fc6333c915 100644 --- a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs +++ b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerCustomFolderViewModel.cs @@ -5,6 +5,7 @@ using Rubberduck.Parsing.Symbols; using Rubberduck.VBEditor; using Rubberduck.VBEditor.ComManagement; +using Rubberduck.VBEditor.SafeComWrappers.Abstract; namespace Rubberduck.Navigation.CodeExplorer { @@ -19,11 +20,14 @@ public class CodeExplorerCustomFolderViewModel : CodeExplorerItemViewModel }; private readonly IProjectsProvider _projectsProvider; + private readonly IVBE _vbe; - public CodeExplorerCustomFolderViewModel(CodeExplorerItemViewModel parent, string name, string fullPath, IProjectsProvider projectsProvider) + public CodeExplorerCustomFolderViewModel(CodeExplorerItemViewModel parent, string name, string fullPath, IProjectsProvider projectsProvider, IVBE vbe) { _parent = parent; _projectsProvider = projectsProvider; + _vbe = vbe; + FullPath = fullPath; Name = name.Replace("\"", string.Empty); FolderAttribute = string.Format("@Folder(\"{0}\")", fullPath.Replace("\"", string.Empty)); @@ -45,7 +49,7 @@ public void AddNodes(List declarations) var members = declarations.Where(item => !ComponentTypes.Contains(item.DeclarationType) && item.ComponentName == moduleName); - AddChild(new CodeExplorerComponentViewModel(this, parent, members, _projectsProvider)); + AddChild(new CodeExplorerComponentViewModel(this, parent, members, _projectsProvider, _vbe)); } catch (InvalidOperationException exception) { diff --git a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs index 3ada509a02..cb7c0b8ca2 100644 --- a/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs +++ b/Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs @@ -382,13 +382,13 @@ private void ParserState_ModuleStateChanged(object sender, ParseProgressEventArg { if (folderNode == null) { - folderNode = new CodeExplorerCustomFolderViewModel(projectNode, projectName, projectName, _state.ProjectsProvider); + folderNode = new CodeExplorerCustomFolderViewModel(projectNode, projectName, projectName, _state.ProjectsProvider, _vbe); projectNode.AddChild(folderNode); } var declaration = CreateDeclaration(e.Module); var newNode = - new CodeExplorerComponentViewModel(folderNode, declaration, new List(), _state.ProjectsProvider) + new CodeExplorerComponentViewModel(folderNode, declaration, new List(), _state.ProjectsProvider, _vbe) { IsErrorState = true }; diff --git a/Rubberduck.Core/Navigation/Folders/FolderHelper.cs b/Rubberduck.Core/Navigation/Folders/FolderHelper.cs index b58fcc5c64..65231df4e9 100644 --- a/Rubberduck.Core/Navigation/Folders/FolderHelper.cs +++ b/Rubberduck.Core/Navigation/Folders/FolderHelper.cs @@ -2,12 +2,14 @@ using Rubberduck.Navigation.CodeExplorer; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; +using Rubberduck.VBEditor.SafeComWrappers.Abstract; namespace Rubberduck.Navigation.Folders { public class FolderHelper { private readonly RubberduckParserState _state; + private readonly IVBE _vbe; private static readonly DeclarationType[] ComponentTypes = { @@ -17,13 +19,17 @@ public class FolderHelper DeclarationType.UserForm, }; - public FolderHelper(RubberduckParserState state) => _state = state; + public FolderHelper(RubberduckParserState state, IVBE vbe) + { + _state = state; + _vbe = vbe; + } public CodeExplorerCustomFolderViewModel GetFolderTree(Declaration declaration = null) { var delimiter = GetDelimiter(); - var root = new CodeExplorerCustomFolderViewModel(null, string.Empty, string.Empty, _state.ProjectsProvider); + var root = new CodeExplorerCustomFolderViewModel(null, string.Empty, string.Empty, _state.ProjectsProvider, _vbe); var items = declaration == null ? _state.AllUserDeclarations.ToList() @@ -46,7 +52,7 @@ public CodeExplorerCustomFolderViewModel GetFolderTree(Declaration declaration = var node = currentNode.Items.FirstOrDefault(i => i.Name == section); if (node == null) { - node = new CodeExplorerCustomFolderViewModel(currentNode, section, fullPath, _state.ProjectsProvider); + node = new CodeExplorerCustomFolderViewModel(currentNode, section, fullPath, _state.ProjectsProvider, _vbe); currentNode.AddChild(node); } diff --git a/Rubberduck.Core/Properties/Settings.Designer.cs b/Rubberduck.Core/Properties/Settings.Designer.cs index b91735e4f8..505d1657b9 100644 --- a/Rubberduck.Core/Properties/Settings.Designer.cs +++ b/Rubberduck.Core/Properties/Settings.Designer.cs @@ -25,15 +25,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - R - true - true - false - true - CodePaneRefactorRenameCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + R + true + true + false + true + CodePaneRefactorRenameCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_CodePaneRefactorRenameCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_CodePaneRefactorRenameCommand"])); @@ -42,15 +43,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - F - true - true - false - true - RefactorEncapsulateFieldCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + F + true + true + false + true + RefactorEncapsulateFieldCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_RefactorEncapsulateFieldCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_RefactorEncapsulateFieldCommand"])); @@ -59,15 +61,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - M - true - true - false - true - RefactorExtractMethodCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + M + true + true + false + true + RefactorExtractMethodCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_RefactorExtractMethodCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_RefactorExtractMethodCommand"])); @@ -76,15 +79,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - C - true - true - false - true - RefactorMoveCloserToUsageCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + C + true + true + false + true + RefactorMoveCloserToUsageCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_RefactorMoveCloserToUsageCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_RefactorMoveCloserToUsageCommand"])); @@ -93,15 +97,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - R - true - false - false - true - CodeExplorerCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + R + true + false + false + true + CodeExplorerCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_CodeExplorerCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_CodeExplorerCommand"])); @@ -110,15 +115,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - E - true - true - false - true - ExportAllCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + E + true + true + false + true + ExportAllCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_ExportAllCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_ExportAllCommand"])); @@ -127,15 +133,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - T - true - false - false - true - FindSymbolCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + T + true + false + false + true + FindSymbolCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_FindSymbolCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_FindSymbolCommand"])); @@ -144,15 +151,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - M - true - false - false - true - IndentCurrentModuleCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + M + true + false + false + true + IndentCurrentModuleCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_IndentCurrentModuleCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_IndentCurrentModuleCommand"])); @@ -161,15 +169,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - P - true - false - false - true - IndentCurrentProcedureCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + P + true + false + false + true + IndentCurrentProcedureCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_IndentCurrentProcedureCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_IndentCurrentProcedureCommand"])); @@ -178,15 +187,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - I - true - true - false - true - InspectionResultsCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + I + true + true + false + true + InspectionResultsCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_InspectionResultsCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_InspectionResultsCommand"])); @@ -195,15 +205,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - ` - true - false - false - true - ReparseCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + ` + true + false + false + true + ReparseCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_ReparseCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_ReparseCommand"])); @@ -212,15 +223,16 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - T - true - true - false - true - TestExplorerCommand -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + T + true + true + false + true + TestExplorerCommand + + ")] public global::Rubberduck.Settings.HotkeySetting DefaultHotkey_TestExplorerCommand { get { return ((global::Rubberduck.Settings.HotkeySetting)(this["DefaultHotkey_TestExplorerCommand"])); @@ -229,9 +241,8 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("\r\n")] + [global::System.Configuration.DefaultSettingValueAttribute("\r\n \r\n ")] public global::Rubberduck.Settings.ToDoMarker ToDoMarker_ToDo { get { return ((global::Rubberduck.Settings.ToDoMarker)(this["ToDoMarker_ToDo"])); @@ -240,9 +251,8 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("\r\n")] + [global::System.Configuration.DefaultSettingValueAttribute("\r\n \r\n ")] public global::Rubberduck.Settings.ToDoMarker ToDoMarker_Note { get { return ((global::Rubberduck.Settings.ToDoMarker)(this["ToDoMarker_Note"])); @@ -251,9 +261,8 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("\r\n")] + [global::System.Configuration.DefaultSettingValueAttribute("\r\n \r\n ")] public global::Rubberduck.Settings.ToDoMarker ToDoMarker_Bug { get { return ((global::Rubberduck.Settings.ToDoMarker)(this["ToDoMarker_Bug"])); @@ -262,16 +271,17 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - false - false - false - false - true - false - false -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + false + false + false + false + true + false + false + + ")] public global::Rubberduck.Settings.WindowSettings WindowSettings { get { return ((global::Rubberduck.Settings.WindowSettings)(this["WindowSettings"])); @@ -280,14 +290,15 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - LateBinding - StrictAssert - true - true - false -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + LateBinding + StrictAssert + true + true + false + + ")] public global::Rubberduck.Settings.UnitTestSettings UnitTestSettings { get { return ((global::Rubberduck.Settings.UnitTestSettings)(this["UnitTestSettings"])); @@ -296,18 +307,20 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute(@" - - - true - true - true - false - false - 10 - 6 - -")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + + true + true + true + false + false + 10 + false + 0 + + + ")] public global::Rubberduck.Settings.GeneralSettings GeneralSettings { get { return ((global::Rubberduck.Settings.GeneralSettings)(this["GeneralSettings"])); @@ -316,124 +329,137 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("\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=\"EmptyForEachBlockInspection\" Severity=\"Warning\" InspectionT" + + "ype=\"MaintainabilityAndReadabilityIssues\" />\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 <" + - "CodeInspection Name=\"ObjectVariableNotSetInspection\" Severity=\"Error\" 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 true\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 " + + " true\r\n " + + " \r\n ")] public global::Rubberduck.Settings.CodeInspectionSettings CodeInspectionSettings { get { return ((global::Rubberduck.Settings.CodeInspectionSettings)(this["CodeInspectionSettings"])); @@ -442,29 +468,20 @@ public static Settings Default { [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("\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")] + [global::System.Configuration.DefaultSettingValueAttribute(@" + + + None + 25 + + + + + ")] public global::Rubberduck.Settings.AutoCompleteSettings AutoCompleteSettings { get { return ((global::Rubberduck.Settings.AutoCompleteSettings)(this["AutoCompleteSettings"])); - } -} + } + } } } diff --git a/Rubberduck.Core/Properties/Settings.settings b/Rubberduck.Core/Properties/Settings.settings index d061c65c55..3f2db75448 100644 --- a/Rubberduck.Core/Properties/Settings.settings +++ b/Rubberduck.Core/Properties/Settings.settings @@ -202,7 +202,8 @@ - <CodeInspectionSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + + <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="ObsoleteErrorSyntaxInspection" Severity="Suggestion" InspectionType="LanguageOpportunities" /> @@ -278,18 +279,20 @@ <CodeInspection Name="IsMissingOnInappropriateArgumentInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="IsMissingWithNonArgumentParameterInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="AssignmentNotUsedInspection" Severity="Suggestion" InspectionType="CodeQualityIssues" /> + <CodeInspection Name="UnderscoreInPublicClassModuleMemberInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> <CodeInspection Name="ExcelUdfNameIsValidCellReferenceInspection" Severity="Warning" InspectionType="CodeQualityIssues" /> </CodeInspections> <WhitelistedIdentifiers /> <RunInspectionsOnSuccessfulParse>true</RunInspectionsOnSuccessfulParse> - </CodeInspectionSettings> + </CodeInspectionSettings> + <AutoCompleteSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" IsEnabled="false"> - <SmartConcat> - <IsEnabled>false</IsEnabled> + <SmartConcat IsEnabled="false"> <ConcatVbNewLineModifier>None</ConcatVbNewLineModifier> + <ConcatMaxLines>25</ConcatMaxLines> </SmartConcat> <SelfClosingPairs IsEnabled="false" /> <BlockCompletion IsEnabled="false" CompleteOnEnter="false" CompleteOnTab="false" /> diff --git a/Rubberduck.Core/Rubberduck.Core.csproj b/Rubberduck.Core/Rubberduck.Core.csproj index 987baa2cbf..97cb371f49 100644 --- a/Rubberduck.Core/Rubberduck.Core.csproj +++ b/Rubberduck.Core/Rubberduck.Core.csproj @@ -1,5 +1,5 @@  - + Rubberduck Rubberduck.Core @@ -81,58 +81,17 @@ 2.0.20525 - - - - - - - - - $([System.String]::Copy('%(Filename)').Replace('.Designer', '')).cs - - - %(Filename).cs - - - - - - - - Designer - MSBuild:Compile - - - Code - %(Filename) - - - - - - Resources.resx - true - true - + True True - True Settings.settings - True - + SettingsSingleFileGenerator Settings.Designer.cs - - Resources.Designer.cs - ResXFileCodeGenerator - - - \ No newline at end of file diff --git a/Rubberduck.Core/Settings/AutoCompleteSettings.cs b/Rubberduck.Core/Settings/AutoCompleteSettings.cs index a8fc519e70..c95411069e 100644 --- a/Rubberduck.Core/Settings/AutoCompleteSettings.cs +++ b/Rubberduck.Core/Settings/AutoCompleteSettings.cs @@ -1,8 +1,5 @@ -using Rubberduck.AutoComplete; -using System; -using System.Collections.Generic; +using System; using System.Configuration; -using System.Linq; using System.Xml.Serialization; namespace Rubberduck.Settings @@ -27,6 +24,27 @@ public interface IAutoCompleteSettings [XmlType(AnonymousType = true)] public class AutoCompleteSettings : IAutoCompleteSettings, IEquatable { + /// + /// Less than that would be useless (wouldn't concat). + /// + public static readonly int ConcatMaxLinesMinValue = 2; + /// + /// /More than that would be illegal (wouldn't compile). + /// + public static readonly int ConcatMaxLinesMaxValue = 25; + + public static AutoCompleteSettings AllEnabled => + new AutoCompleteSettings + { + IsEnabled = true, + BlockCompletion = + new BlockCompletionSettings {IsEnabled = true, CompleteOnEnter = true, CompleteOnTab = true}, + SmartConcat = + new SmartConcatSettings {IsEnabled = true, ConcatVbNewLineModifier = ModifierKeySetting.CtrlKey}, + SelfClosingPairs = + new SelfClosingPairSettings {IsEnabled = true} + }; + public AutoCompleteSettings() { SmartConcat = new SmartConcatSettings(); @@ -45,13 +63,35 @@ public AutoCompleteSettings() public class SmartConcatSettings : IEquatable { + private int _concatMaxLines; + + [XmlAttribute] public bool IsEnabled { get; set; } public ModifierKeySetting ConcatVbNewLineModifier { get; set; } + public int ConcatMaxLines + { + get => _concatMaxLines; + set + { + if (value > ConcatMaxLinesMaxValue) + { + value = ConcatMaxLinesMaxValue; + } + else if (value < ConcatMaxLinesMinValue) + { + value = ConcatMaxLinesMinValue; + } + + _concatMaxLines = value; + } + } + public bool Equals(SmartConcatSettings other) => other != null && other.IsEnabled == IsEnabled && - other.ConcatVbNewLineModifier == ConcatVbNewLineModifier; + other.ConcatVbNewLineModifier == ConcatVbNewLineModifier && + other.ConcatMaxLines == ConcatMaxLines; } public class SelfClosingPairSettings : IEquatable diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs index 84c194b603..fdde7a567d 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/RenameCommand.cs @@ -2,6 +2,7 @@ using NLog; using Rubberduck.Interaction; using Rubberduck.Navigation.CodeExplorer; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.Rename; using Rubberduck.UI.Command; @@ -15,13 +16,15 @@ public class RenameCommand : CommandBase, IDisposable { private readonly IVBE _vbe; private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IRefactoringDialog _view; private readonly IMessageBox _msgBox; - public RenameCommand(IVBE vbe, IRefactoringDialog view, RubberduckParserState state, IMessageBox msgBox) : base(LogManager.GetCurrentClassLogger()) + public RenameCommand(IVBE vbe, IRefactoringDialog view, RubberduckParserState state, IMessageBox msgBox, IRewritingManager rewritingManager) : base(LogManager.GetCurrentClassLogger()) { _vbe = vbe; _state = state; + _rewritingManager = rewritingManager; _view = view; _msgBox = msgBox; } @@ -34,7 +37,7 @@ protected override bool EvaluateCanExecute(object parameter) protected override void OnExecute(object parameter) { var factory = new RenamePresenterFactory(_vbe, _view, _state); - var refactoring = new RenameRefactoring(_vbe, factory, _msgBox, _state); + var refactoring = new RenameRefactoring(_vbe, factory, _msgBox, _state, _state.ProjectsProvider, _rewritingManager); refactoring.Refactor(((ICodeExplorerDeclarationViewModel)parameter).Declaration); } diff --git a/Rubberduck.Core/UI/Command/Refactorings/CodePaneRefactorRenameCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/CodePaneRefactorRenameCommand.cs index 22272035d5..2ddc7c35d7 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/CodePaneRefactorRenameCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/CodePaneRefactorRenameCommand.cs @@ -1,5 +1,6 @@ using System.Runtime.InteropServices; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.Rename; @@ -12,12 +13,14 @@ namespace Rubberduck.UI.Command.Refactorings public class CodePaneRefactorRenameCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public CodePaneRefactorRenameCommand(IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public CodePaneRefactorRenameCommand(IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) : base (vbe) { _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } @@ -68,7 +71,7 @@ protected override void OnExecute(object parameter) using (var view = new RenameDialog(new RenameViewModel(_state))) { var factory = new RenamePresenterFactory(Vbe, view, _state); - var refactoring = new RenameRefactoring(Vbe, factory, _messageBox, _state); + var refactoring = new RenameRefactoring(Vbe, factory, _messageBox, _state, _state.ProjectsProvider, _rewritingManager); refactoring.Refactor(target); } diff --git a/Rubberduck.Core/UI/Command/Refactorings/FormDesignerRefactorRenameCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/FormDesignerRefactorRenameCommand.cs index 610d6fc7e5..d1d85813ce 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/FormDesignerRefactorRenameCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/FormDesignerRefactorRenameCommand.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Runtime.InteropServices; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.Rename; @@ -14,12 +15,14 @@ namespace Rubberduck.UI.Command.Refactorings public class FormDesignerRefactorRenameCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public FormDesignerRefactorRenameCommand(IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public FormDesignerRefactorRenameCommand(IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) : base (vbe) { _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } @@ -34,7 +37,7 @@ protected override void OnExecute(object parameter) using (var view = new RenameDialog(new RenameViewModel(_state))) { var factory = new RenamePresenterFactory(Vbe, view, _state); - var refactoring = new RenameRefactoring(Vbe, factory, _messageBox, _state); + var refactoring = new RenameRefactoring(Vbe, factory, _messageBox, _state, _state.ProjectsProvider, _rewritingManager); var target = GetTarget(); diff --git a/Rubberduck.Core/UI/Command/Refactorings/ProjectExplorerRefactorRenameCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/ProjectExplorerRefactorRenameCommand.cs index a752a38052..a9e183a414 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/ProjectExplorerRefactorRenameCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/ProjectExplorerRefactorRenameCommand.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Runtime.InteropServices; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.Rename; @@ -13,12 +14,14 @@ namespace Rubberduck.UI.Command.Refactorings public class ProjectExplorerRefactorRenameCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _msgBox; - public ProjectExplorerRefactorRenameCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgBox) + public ProjectExplorerRefactorRenameCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgBox, IRewritingManager rewritingManager) : base (vbe) { _state = state; + _rewritingManager = rewritingManager; _msgBox = msgBox; } @@ -32,7 +35,7 @@ protected override void OnExecute(object parameter) using (var view = new RenameDialog(new RenameViewModel(_state))) { var factory = new RenamePresenterFactory(Vbe, view, _state); - var refactoring = new RenameRefactoring(Vbe, factory, _msgBox, _state); + var refactoring = new RenameRefactoring(Vbe, factory, _msgBox, _state, _state.ProjectsProvider, _rewritingManager); var target = GetTarget(); diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorEncapsulateFieldCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorEncapsulateFieldCommand.cs index 84c90016d5..a5bda2f06a 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorEncapsulateFieldCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorEncapsulateFieldCommand.cs @@ -1,4 +1,5 @@ using System.Runtime.InteropServices; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.EncapsulateField; @@ -12,12 +13,14 @@ namespace Rubberduck.UI.Command.Refactorings public class RefactorEncapsulateFieldCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly Indenter _indenter; - public RefactorEncapsulateFieldCommand(IVBE vbe, RubberduckParserState state, Indenter indenter) + public RefactorEncapsulateFieldCommand(IVBE vbe, RubberduckParserState state, Indenter indenter, IRewritingManager rewritingManager) : base(vbe) { _state = state; + _rewritingManager = rewritingManager; _indenter = indenter; } @@ -52,7 +55,7 @@ protected override void OnExecute(object parameter) using (var view = new EncapsulateFieldDialog(new EncapsulateFieldViewModel(_state, _indenter))) { var factory = new EncapsulateFieldPresenterFactory(Vbe, _state, view); - var refactoring = new EncapsulateFieldRefactoring(Vbe, _indenter, factory); + var refactoring = new EncapsulateFieldRefactoring(Vbe, _indenter, factory, _rewritingManager); refactoring.Refactor(); } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs index 7412073304..0ff6b12a9c 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs @@ -5,6 +5,7 @@ using Rubberduck.Interaction; using Rubberduck.Parsing; using Rubberduck.Parsing.Grammar; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.ExtractInterface; @@ -18,12 +19,14 @@ namespace Rubberduck.UI.Command.Refactorings public class RefactorExtractInterfaceCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public RefactorExtractInterfaceCommand(IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public RefactorExtractInterfaceCommand(IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) :base(vbe) { _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } @@ -85,7 +88,7 @@ protected override void OnExecute(object parameter) using (var view = new ExtractInterfaceDialog(new ExtractInterfaceViewModel())) { var factory = new ExtractInterfacePresenterFactory(Vbe, _state, view); - var refactoring = new ExtractInterfaceRefactoring(Vbe, _messageBox, factory); + var refactoring = new ExtractInterfaceRefactoring(Vbe, _messageBox, factory, _rewritingManager); refactoring.Refactor(); } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorImplementInterfaceCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorImplementInterfaceCommand.cs index 3f62d4dbdb..7afa78e1bb 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorImplementInterfaceCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorImplementInterfaceCommand.cs @@ -1,6 +1,7 @@ using System.Linq; using System.Runtime.InteropServices; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.ImplementInterface; @@ -12,12 +13,14 @@ namespace Rubberduck.UI.Command.Refactorings public class RefactorImplementInterfaceCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _msgBox; - public RefactorImplementInterfaceCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgBox) + public RefactorImplementInterfaceCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgBox, IRewritingManager rewritingManager) : base(vbe) { _state = state; + _rewritingManager = rewritingManager; _msgBox = msgBox; } @@ -51,7 +54,7 @@ protected override void OnExecute(object parameter) return; } } - var refactoring = new ImplementInterfaceRefactoring(Vbe, _state, _msgBox); + var refactoring = new ImplementInterfaceRefactoring(Vbe, _state, _msgBox, _rewritingManager); refactoring.Refactor(); } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceFieldCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceFieldCommand.cs index 939ed3e429..a5dc9eacc0 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceFieldCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceFieldCommand.cs @@ -1,5 +1,6 @@ using Rubberduck.Common; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.IntroduceField; @@ -10,12 +11,14 @@ namespace Rubberduck.UI.Command.Refactorings public class RefactorIntroduceFieldCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public RefactorIntroduceFieldCommand (IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public RefactorIntroduceFieldCommand (IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) :base(vbe) { _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } @@ -49,7 +52,7 @@ protected override void OnExecute(object parameter) return; } - var refactoring = new IntroduceFieldRefactoring(Vbe, _state, _messageBox); + var refactoring = new IntroduceFieldRefactoring(Vbe, _state, _messageBox, _rewritingManager); refactoring.Refactor(selection.Value); } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceParameterCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceParameterCommand.cs index 941caa49b3..c7a334a0a3 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceParameterCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorIntroduceParameterCommand.cs @@ -1,5 +1,6 @@ using Rubberduck.Common; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.IntroduceParameter; @@ -10,12 +11,14 @@ namespace Rubberduck.UI.Command.Refactorings public class RefactorIntroduceParameterCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _messageBox; - public RefactorIntroduceParameterCommand (IVBE vbe, RubberduckParserState state, IMessageBox messageBox) + public RefactorIntroduceParameterCommand (IVBE vbe, RubberduckParserState state, IMessageBox messageBox, IRewritingManager rewritingManager) :base(vbe) { _state = state; + _rewritingManager = rewritingManager; _messageBox = messageBox; } @@ -49,7 +52,7 @@ protected override void OnExecute(object parameter) return; } - var refactoring = new IntroduceParameterRefactoring(Vbe, _state, _messageBox); + var refactoring = new IntroduceParameterRefactoring(Vbe, _state, _messageBox, _rewritingManager); refactoring.Refactor(selection.Value); } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorMoveCloserToUsageCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorMoveCloserToUsageCommand.cs index 335d2be99a..05bf350ce7 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorMoveCloserToUsageCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorMoveCloserToUsageCommand.cs @@ -1,5 +1,6 @@ using System.Linq; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.MoveCloserToUsage; @@ -10,12 +11,14 @@ namespace Rubberduck.UI.Command.Refactorings public class RefactorMoveCloserToUsageCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _msgbox; - public RefactorMoveCloserToUsageCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgbox) + public RefactorMoveCloserToUsageCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgbox, IRewritingManager rewritingManager) :base(vbe) { _state = state; + _rewritingManager = rewritingManager; _msgbox = msgbox; } @@ -43,7 +46,7 @@ protected override void OnExecute(object parameter) if (selection.HasValue) { - var refactoring = new MoveCloserToUsageRefactoring(Vbe, _state, _msgbox); + var refactoring = new MoveCloserToUsageRefactoring(Vbe, _state, _msgbox, _rewritingManager); refactoring.Refactor(selection.Value); } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorRemoveParametersCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorRemoveParametersCommand.cs index 5fc79a8236..20322bdeac 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorRemoveParametersCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorRemoveParametersCommand.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using Rubberduck.Common; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.RemoveParameters; @@ -16,12 +17,14 @@ public class RefactorRemoveParametersCommand : RefactorCommandBase { private readonly IMessageBox _msgbox; private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; - public RefactorRemoveParametersCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgbox) + public RefactorRemoveParametersCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgbox, IRewritingManager rewritingManager) : base (vbe) { _msgbox = msgbox; _state = state; + _rewritingManager = rewritingManager; } private static readonly DeclarationType[] ValidDeclarationTypes = @@ -75,7 +78,7 @@ protected override void OnExecute(object parameter) using (var view = new RemoveParametersDialog(new RemoveParametersViewModel(_state))) { var factory = new RemoveParametersPresenterFactory(Vbe, view, _state, _msgbox); - var refactoring = new RemoveParametersRefactoring(Vbe, factory); + var refactoring = new RemoveParametersRefactoring(Vbe, factory, _rewritingManager); refactoring.Refactor(selection.Value); } } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorReorderParametersCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorReorderParametersCommand.cs index 7d2c39cd63..d78f996956 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorReorderParametersCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorReorderParametersCommand.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using Rubberduck.Common; using Rubberduck.Interaction; +using Rubberduck.Parsing.Rewriter; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; using Rubberduck.Refactorings.ReorderParameters; @@ -14,12 +15,14 @@ namespace Rubberduck.UI.Command.Refactorings public class RefactorReorderParametersCommand : RefactorCommandBase { private readonly RubberduckParserState _state; + private readonly IRewritingManager _rewritingManager; private readonly IMessageBox _msgbox; - public RefactorReorderParametersCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgbox) + public RefactorReorderParametersCommand(IVBE vbe, RubberduckParserState state, IMessageBox msgbox, IRewritingManager rewritingManager) : base (vbe) { _state = state; + _rewritingManager = rewritingManager; _msgbox = msgbox; } @@ -75,7 +78,7 @@ protected override void OnExecute(object parameter) using (var view = new ReorderParametersDialog(new ReorderParametersViewModel(_state))) { var factory = new ReorderParametersPresenterFactory(Vbe, view, _state, _msgbox); - var refactoring = new ReorderParametersRefactoring(Vbe, factory, _msgbox, _state.ProjectsProvider); + var refactoring = new ReorderParametersRefactoring(Vbe, factory, _msgbox, _rewritingManager); refactoring.Refactor(selection.Value); } } diff --git a/Rubberduck.Core/UI/Command/ReparseCommand.cs b/Rubberduck.Core/UI/Command/ReparseCommand.cs index dc1244ecfe..82e74ae4fd 100644 --- a/Rubberduck.Core/UI/Command/ReparseCommand.cs +++ b/Rubberduck.Core/UI/Command/ReparseCommand.cs @@ -2,18 +2,16 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; -using System.Windows.Forms; using NLog; using Rubberduck.Interaction; using Rubberduck.Parsing.VBA; using Rubberduck.Settings; using Rubberduck.SettingsProvider; using Rubberduck.Resources; -using Rubberduck.UI.CodeExplorer.Commands; using Rubberduck.VBEditor.ComManagement.TypeLibsAPI; using Rubberduck.VBEditor.SafeComWrappers; using Rubberduck.VBEditor.SafeComWrappers.Abstract; -using Rubberduck.VBEditor.VBERuntime.Settings; +using Rubberduck.VBEditor.VbeRuntime.Settings; namespace Rubberduck.UI.Command { @@ -22,12 +20,12 @@ public class ReparseCommand : CommandBase { private readonly IVBE _vbe; private readonly IVBETypeLibsAPI _typeLibApi; - private readonly IVBESettings _vbeSettings; + private readonly IVbeSettings _vbeSettings; private readonly IMessageBox _messageBox; private readonly RubberduckParserState _state; private readonly GeneralSettings _settings; - public ReparseCommand(IVBE vbe, IConfigProvider settingsProvider, RubberduckParserState state, IVBETypeLibsAPI typeLibApi, IVBESettings vbeSettings, IMessageBox messageBox) : base(LogManager.GetCurrentClassLogger()) + public ReparseCommand(IVBE vbe, IConfigProvider settingsProvider, RubberduckParserState state, IVBETypeLibsAPI typeLibApi, IVbeSettings vbeSettings, IMessageBox messageBox) : base(LogManager.GetCurrentClassLogger()) { _vbe = vbe; _vbeSettings = vbeSettings; diff --git a/Rubberduck.Core/UI/Controls/NumberPicker.xaml.cs b/Rubberduck.Core/UI/Controls/NumberPicker.xaml.cs index 081d681d83..7af1a973d0 100644 --- a/Rubberduck.Core/UI/Controls/NumberPicker.xaml.cs +++ b/Rubberduck.Core/UI/Controls/NumberPicker.xaml.cs @@ -1,4 +1,5 @@ -using System.ComponentModel; +using System; +using System.ComponentModel; using System.Windows; // credit to http://stackoverflow.com/a/2752538 @@ -11,6 +12,10 @@ public partial class NumberPicker : IDataErrorInfo { public static readonly DependencyProperty NumValueProperty = DependencyProperty.Register("NumValue", typeof(int), typeof(NumberPicker), new UIPropertyMetadata(null)); + public static readonly DependencyProperty MinNumberProperty = + DependencyProperty.Register("MinNumber", typeof(int), typeof(NumberPicker), new UIPropertyMetadata(null)); + public static readonly DependencyProperty MaxNumberProperty = + DependencyProperty.Register("MaxNumber", typeof(int), typeof(NumberPicker), new UIPropertyMetadata(null)); public int NumValue { @@ -22,9 +27,27 @@ public int NumValue } } - public int MinNumber { get; set; } = int.MinValue; + public int MinNumber + { + get => (int)GetValue(MinNumberProperty); + set + { + var old = GetValue(MinNumberProperty); + SetValue(MinNumberProperty, value); + OnPropertyChanged(new DependencyPropertyChangedEventArgs(MinNumberProperty, old, value)); + } + } - public int MaxNumber { get; set; } = int.MaxValue; + public int MaxNumber + { + get => (int)GetValue(MaxNumberProperty); + set + { + var old = GetValue(MaxNumberProperty); + SetValue(MaxNumberProperty, value); + OnPropertyChanged(new DependencyPropertyChangedEventArgs(MaxNumberProperty, old, value)); + } + } public NumberPicker() { diff --git a/Rubberduck.Core/UI/Refactorings/ExtractInterface/ExtractInterfaceView.xaml b/Rubberduck.Core/UI/Refactorings/ExtractInterface/ExtractInterfaceView.xaml index c7b933b8d7..18bfea2733 100644 --- a/Rubberduck.Core/UI/Refactorings/ExtractInterface/ExtractInterfaceView.xaml +++ b/Rubberduck.Core/UI/Refactorings/ExtractInterface/ExtractInterfaceView.xaml @@ -59,35 +59,36 @@ - + + + - - - - - - + + + + + + + + + + Grid.Row="1" Margin="5" Padding="5"> @@ -146,7 +147,8 @@ - + + diff --git a/Rubberduck.Core/UI/Refactorings/ExtractInterface/InterfaceMemberViewModel.cs b/Rubberduck.Core/UI/Refactorings/ExtractInterface/InterfaceMemberViewModel.cs index f67315e644..9aa5f4e007 100644 --- a/Rubberduck.Core/UI/Refactorings/ExtractInterface/InterfaceMemberViewModel.cs +++ b/Rubberduck.Core/UI/Refactorings/ExtractInterface/InterfaceMemberViewModel.cs @@ -4,18 +4,14 @@ namespace Rubberduck.UI.Refactorings.ExtractInterface { internal class InterfaceMemberViewModel : ViewModelBase { - private readonly InterfaceMember _wrapped; - internal InterfaceMember Wrapped { get => _wrapped; } - - - private bool _isSelected; - private InterfaceMember model; - public InterfaceMemberViewModel(InterfaceMember model) { - this.model = model; + Wrapped = model; } + internal InterfaceMember Wrapped { get; } + + private bool _isSelected; public bool IsSelected { get => _isSelected; @@ -26,7 +22,7 @@ public bool IsSelected } } - public string FullMemberSignature { get => _wrapped.FullMemberSignature; } + public string FullMemberSignature => Wrapped?.FullMemberSignature; } internal static class ConversionExtensions diff --git a/Rubberduck.Core/UI/SelectionChangeService.cs b/Rubberduck.Core/UI/SelectionChangeService.cs index 88e39ef4e7..6919563c19 100644 --- a/Rubberduck.Core/UI/SelectionChangeService.cs +++ b/Rubberduck.Core/UI/SelectionChangeService.cs @@ -30,8 +30,8 @@ public SelectionChangeService(IVBE vbe, IParseCoordinator parser) { _parser = parser; _vbe = vbe; - VBENativeServices.SelectionChanged += OnVbeSelectionChanged; - VBENativeServices.WindowFocusChange += OnVbeFocusChanged; + VbeNativeServices.SelectionChanged += OnVbeSelectionChanged; + VbeNativeServices.WindowFocusChange += OnVbeFocusChanged; } private void OnVbeSelectionChanged(object sender, EventArgs e) @@ -69,7 +69,7 @@ private void OnVbeFocusChanged(object sender, WindowChangedEventArgs e) //Caret changed in a code pane. Task.Run(() => { - using (var pane = VBENativeServices.GetCodePaneFromHwnd(e.Hwnd)) + using (var pane = VbeNativeServices.GetCodePaneFromHwnd(e.Hwnd)) { DispatchSelectedDeclaration( new DeclarationChangedEventArgs(_vbe, _parser.State.FindSelectedDeclaration(pane))); @@ -186,8 +186,8 @@ private bool DeclarationChanged(Declaration current) public void Dispose() { - VBENativeServices.SelectionChanged -= OnVbeSelectionChanged; - VBENativeServices.WindowFocusChange -= OnVbeFocusChanged; + VbeNativeServices.SelectionChanged -= OnVbeSelectionChanged; + VbeNativeServices.WindowFocusChange -= OnVbeFocusChanged; } } diff --git a/Rubberduck.Core/UI/Settings/AutoCompleteSettings.xaml b/Rubberduck.Core/UI/Settings/AutoCompleteSettings.xaml index 8b22ed6052..6b73849bec 100644 --- a/Rubberduck.Core/UI/Settings/AutoCompleteSettings.xaml +++ b/Rubberduck.Core/UI/Settings/AutoCompleteSettings.xaml @@ -111,6 +111,12 @@ IsChecked="{Binding ConcatVbNewLine}" Content="{Resx ResxName=Rubberduck.Resources.Settings.AutoCompletesPage, Key=ConcatVbNewLine}" /> +