Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganizing Rewriting #4465

Merged
merged 34 commits into from Nov 14, 2018
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
668f46f
Extract Rewrite out of the IModuleRewriter
MDoerner Oct 24, 2018
41d327e
Introduce the IRewriteSession and IRewritingManager
MDoerner Oct 27, 2018
31c4bb0
Wire up the IRewritingManager
MDoerner Oct 27, 2018
52be1e0
Expose the IRewritingManager on the RubberduckParserState
MDoerner Oct 27, 2018
e28fadd
Optionally pass a IRewriteSession to quickfixes
MDoerner Oct 27, 2018
ee12ff5
Provide IRewriteSessions to quickfixes in QuickFixProvider
MDoerner Oct 27, 2018
0eb245d
Make the quickfixes use the IRewritesession (DOES NOT COMPILE)
MDoerner Oct 30, 2018
76426be
Adjust the quickfix tests to the new setup of rewriting
MDoerner Nov 1, 2018
13f7f41
Remove RewriteAllModules from RubberduckParserState
MDoerner Nov 1, 2018
3deccdb
Move creating ModuleRewriters out of the parser
MDoerner Nov 1, 2018
e28d67c
Rewire and streamline the ModuleRewriter tests
MDoerner Nov 2, 2018
a297eab
Remove _projectsProvider from ReorderParameter refactoring
MDoerner Nov 2, 2018
fa74ea3
Add some comment to quickfixes not using the IRewriteSession handed t…
MDoerner Nov 2, 2018
e927aa8
Make the RenameRefactoring use a QualifiedSelection? to store the ini…
MDoerner Nov 2, 2018
fa2dd3b
Rewire the RenameRefactoring and its tests
MDoerner Nov 2, 2018
3d55d22
Rewire the ReorderParametersRefactoring and its tests
MDoerner Nov 2, 2018
df91612
Rewire the MoveCloserToUsageRefactoring
MDoerner Nov 2, 2018
245e0fc
Rewire the EncapsulateFieldRefactoring
MDoerner Nov 2, 2018
15a9530
Rewire the IntroduceParameterRefactoring
MDoerner Nov 3, 2018
2ad16f6
Rewire the IntroduceFieldRefactoring
MDoerner Nov 3, 2018
d3267ce
Rewire the ImplementInterface- and ExtractInterfaceRefactoring
MDoerner Nov 3, 2018
5f5ffe7
Rewire the RemoveParameterRefactoring
MDoerner Nov 3, 2018
f22b5cc
Remove the rewriters from the ModuleStates and RubberduckParserState
MDoerner Nov 3, 2018
7a81d8f
Remove the RewriteManager from the RubberDuckParserState
MDoerner Nov 3, 2018
2c5bd70
Merge branch 'next' into ReorganizingRewriting2
MDoerner Nov 3, 2018
0ded26b
Add tests for IRewriteSession implementations
MDoerner Nov 5, 2018
16a5607
Add tests for the RewritingManager
MDoerner Nov 6, 2018
7450c58
Merge branch 'next' into ReorganizingRewriting2
MDoerner Nov 6, 2018
4494b8d
Change Rewrite to TryRewrite
MDoerner Nov 7, 2018
bd9c9c2
Amend doc-comments in IModuleRewriter
MDoerner Nov 7, 2018
57ebb43
Merge branch 'next' into ReorganizingRewriting2
MDoerner Nov 12, 2018
0c22259
Merge branch 'next' into ReorganizingRewriting2
MDoerner Nov 13, 2018
299e08a
Make some minor stylistic adjustments
MDoerner Nov 14, 2018
5986308
Merge branch 'next' into ReorganizingRewriting2
MDoerner Nov 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 3 additions & 10 deletions Rubberduck.API/VBA/Parser.cs
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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,
Expand Down
7 changes: 5 additions & 2 deletions Rubberduck.CodeAnalysis/Inspections/Abstract/QuickFixBase.cs
Expand Up @@ -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
{
Expand Down Expand Up @@ -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; }
Expand Down
Expand Up @@ -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.
/// </summary>
/// <param name="reference">The identifier reference to analyze</param>
/// <param name="state">The parser state</param>
public static bool RequiresSetAssignment(IdentifierReference reference, RubberduckParserState state)
/// <param name="declarationFinderProvider">The parser state</param>
public static bool RequiresSetAssignment(IdentifierReference reference, IDeclarationFinderProvider declarationFinderProvider)
{
if (!reference.IsAssignment)
{
Expand Down Expand Up @@ -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<VBAParser.LetStmtContext>() == letStmtContext);
if (lastRef?.Declaration.AsTypeDeclaration?.DeclarationType.HasFlag(DeclarationType.ClassModule) ?? false)
{
Expand All @@ -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));
}
Expand Down
Expand Up @@ -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<VBAParser.SetStmtContext>();
var isArgument = referenceResult.Context.GetAncestor<VBAParser.ArgumentContext>() != null;
Expand All @@ -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<VBAParser.ModuleBodyElementContext>();
Expand Down Expand Up @@ -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);
Expand Down
Expand Up @@ -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;

Expand All @@ -17,7 +18,8 @@ public AddIdentifierToWhiteListQuickFix(IPersistanceService<CodeInspectionSettin
_settings = settings;
}

public override void Fix(IInspectionResult result)
//The rewriteSession is optional since it is not used in this particular quickfix.
public override void Fix(IInspectionResult result, IRewriteSession rewriteSession = null)
{
var inspectionSettings = _settings.Load(new CodeInspectionSettings()) ?? new CodeInspectionSettings();
var whitelist = inspectionSettings.WhitelistedIdentifiers;
Expand Down
25 changes: 10 additions & 15 deletions Rubberduck.CodeAnalysis/QuickFixes/AddStepOneQuickFix.cs
Expand Up @@ -2,21 +2,16 @@
using Rubberduck.Inspections.Concrete;
using Rubberduck.Parsing.Inspections.Abstract;
using Rubberduck.Parsing.Rewriter;
using Rubberduck.Parsing.VBA;
using System;
using static Rubberduck.Parsing.Grammar.VBAParser;

namespace Rubberduck.Inspections.QuickFixes
{
public class AddStepOneQuickFix : QuickFixBase
public sealed class AddStepOneQuickFix : QuickFixBase
{
private readonly RubberduckParserState _state;

public AddStepOneQuickFix(RubberduckParserState state)
public AddStepOneQuickFix()
: base(typeof(StepIsNotSpecifiedInspection))
{
_state = state;
}
{}

public override bool CanFixInProcedure => true;

Expand All @@ -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)
{
Expand Down
@@ -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.");
}

Expand Down
Expand Up @@ -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<VBAParser.EndOfStatementContext>());
Expand All @@ -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);
}
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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}";
Expand Down
14 changes: 5 additions & 9 deletions Rubberduck.CodeAnalysis/QuickFixes/ChangeDimToPrivateQuickFix.cs
Expand Up @@ -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);
Expand Down