Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 110 additions & 1 deletion RetailCoder.VBE/Common/DeclarationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Rubberduck.Parsing.Grammar;
using Rubberduck.Parsing.Symbols;
using Rubberduck.VBEditor;
// ReSharper disable LocalizableElement

namespace Rubberduck.Common
{
Expand All @@ -20,6 +21,65 @@ public static BitmapImage BitmapImage(this Declaration declaration)
return Cache[declaration];
}

/// <summary>
/// Returns the Selection of a VariableStmtContext.
/// </summary>
/// <exception cref="ArgumentException">Throws when target's DeclarationType is not Variable.</exception>
/// <param name="target"></param>
/// <returns></returns>
public static Selection GetVariableStmtContextSelection(this Declaration target)
{
if (target.DeclarationType != DeclarationType.Variable)
{
throw new ArgumentException("Target DeclarationType is not Variable.", "target");
}

var statement = GetVariableStmtContext(target);

return new Selection(statement.Start.Line, statement.Start.Column,
statement.Stop.Line, statement.Stop.Column);
}

/// <summary>
/// Returns a VariableStmtContext.
/// </summary>
/// <exception cref="ArgumentException">Throws when target's DeclarationType is not Variable.</exception>
/// <param name="target"></param>
/// <returns></returns>
public static VBAParser.VariableStmtContext GetVariableStmtContext(this Declaration target)
{
if (target.DeclarationType != DeclarationType.Variable)
{
throw new ArgumentException("Target DeclarationType is not Variable.", "target");
}

var statement = target.Context.Parent.Parent as VBAParser.VariableStmtContext;
if (statement == null)
{
throw new MissingMemberException("Statement not found");
}

return statement;
}

/// <summary>
/// Returns whether a variable declaration statement contains multiple declarations in a single statement.
/// </summary>
/// <exception cref="ArgumentException">Throws when target's DeclarationType is not Variable.</exception>
/// <param name="target"></param>
/// <returns></returns>
public static bool HasMultipleDeclarationsInStatement(this Declaration target)
{
if (target.DeclarationType != DeclarationType.Variable)
{
throw new ArgumentException("Target DeclarationType is not Variable.", "target");
}

var statement = target.Context.Parent as VBAParser.VariableListStmtContext;

return statement != null && statement.children.Count(i => i is VBAParser.VariableSubStmtContext) > 1;
}

public static readonly DeclarationType[] ProcedureTypes =
{
DeclarationType.Procedure,
Expand Down Expand Up @@ -270,7 +330,15 @@ public static Declaration FindInterfaceMember(this IEnumerable<Declaration> decl
: matches.First();
}

public static Declaration FindSelection(this IEnumerable<Declaration> declarations, QualifiedSelection selection, DeclarationType[] validDeclarationTypes)
/// <summary>
/// Returns the declaration contained in a qualified selection.
/// To get the selection of a variable or field, use FindVariable(QualifiedSelection)
/// </summary>
/// <param name="declarations"></param>
/// <param name="selection"></param>
/// <param name="validDeclarationTypes"></param>
/// <returns></returns>
public static Declaration FindTarget(this IEnumerable<Declaration> declarations, QualifiedSelection selection, DeclarationType[] validDeclarationTypes)
{
var items = declarations.ToList();

Expand Down Expand Up @@ -332,5 +400,46 @@ public static Declaration FindSelection(this IEnumerable<Declaration> declaratio
}
return target;
}

/// <summary>
/// Returns the variable which contains the passed-in QualifiedSelection. Returns null if the selection is not on a variable.
/// </summary>
/// <param name="declarations"></param>
/// <param name="selection"></param>
/// <returns></returns>
public static Declaration FindVariable(this IEnumerable<Declaration> declarations, QualifiedSelection selection)
{
var items = declarations.Where(d => !d.IsBuiltIn && d.DeclarationType == DeclarationType.Variable).ToList();

var target = items
.FirstOrDefault(item => item.IsSelected(selection) || item.References.Any(r => r.IsSelected(selection)));

if (target != null) { return target; }

var targets = items.Where(item => item.ComponentName == selection.QualifiedName.ComponentName);

foreach (var declaration in targets)
{
var declarationSelection = new Selection(declaration.Context.Start.Line,
declaration.Context.Start.Column,
declaration.Context.Stop.Line,
declaration.Context.Stop.Column + declaration.Context.Stop.Text.Length);

if (declarationSelection.Contains(selection.Selection) ||
!HasMultipleDeclarationsInStatement(declaration) && GetVariableStmtContextSelection(declaration).Contains(selection.Selection))
{
return declaration;
}

var reference =
declaration.References.FirstOrDefault(r => r.Selection.Contains(selection.Selection));

if (reference != null)
{
return reference.Declaration;
}
}
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private List<RegexSearchResult> SearchCurrentBlock(string searchPattern)

var wrapper = _codePaneFactory.Create(_vbe.ActiveCodePane);
var qualifiedSelection = new QualifiedSelection(new QualifiedModuleName(wrapper.CodeModule.Parent), wrapper.Selection);
dynamic block = parseResult.AllDeclarations.FindSelection(qualifiedSelection, declarationTypes).Context.Parent;
dynamic block = parseResult.AllDeclarations.FindTarget(qualifiedSelection, declarationTypes).Context.Parent;
var selection = new Selection(block.Start.Line, block.Start.Column, block.Stop.Line, block.Stop.Column);
return results.Where(r => selection.Contains(r.Selection)).ToList();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Parsing.Grammar;
using Rubberduck.Common;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.VBEditor;
Expand All @@ -10,8 +9,6 @@ namespace Rubberduck.Refactorings.EncapsulateField
{
public class EncapsulateFieldModel
{
private readonly IList<Declaration> _declarations;

public Declaration TargetDeclaration { get; private set; }

public string PropertyName { get; set; }
Expand All @@ -21,68 +18,11 @@ public class EncapsulateFieldModel

public EncapsulateFieldModel(RubberduckParserState parseResult, QualifiedSelection selection)
{
_declarations = parseResult.AllDeclarations.Where(d => !d.IsBuiltIn && d.DeclarationType == DeclarationType.Variable).ToList();

TargetDeclaration = FindSelection(selection);
}

public Selection GetVariableStmtContextSelection(Declaration target)
{
var statement = GetVariableStmtContext(target);

return new Selection(statement.Start.Line, statement.Start.Column,
statement.Stop.Line, statement.Stop.Column);
}

public VBAParser.VariableStmtContext GetVariableStmtContext(Declaration target)
{
var statement = target.Context.Parent.Parent as VBAParser.VariableStmtContext;
if (statement == null)
{
throw new NullReferenceException("Statement not found");
}

return statement;
}

public bool HasMultipleDeclarationsInStatement(Declaration target)
{
var statement = target.Context.Parent as VBAParser.VariableListStmtContext;

return statement != null && statement.children.Count(i => i is VBAParser.VariableSubStmtContext) > 1;
}

private Declaration FindSelection(QualifiedSelection selection)
{
var target = _declarations
.FirstOrDefault(item => item.IsSelected(selection) || item.References.Any(r => r.IsSelected(selection)));

if (target != null) { return target; }

var targets = _declarations.Where(item => item.ComponentName == selection.QualifiedName.ComponentName);

foreach (var declaration in targets)
{
var declarationSelection = new Selection(declaration.Context.Start.Line,
declaration.Context.Start.Column,
declaration.Context.Stop.Line,
declaration.Context.Stop.Column + declaration.Context.Stop.Text.Length);

if (declarationSelection.Contains(selection.Selection) ||
!HasMultipleDeclarationsInStatement(declaration) && GetVariableStmtContextSelection(declaration).Contains(selection.Selection))
{
return declaration;
}

var reference =
declaration.References.FirstOrDefault(r => r.Selection.Contains(selection.Selection));
IList<Declaration> declarations = parseResult.AllDeclarations
.Where(d => !d.IsBuiltIn && d.DeclarationType == DeclarationType.Variable)
.ToList();

if (reference != null)
{
return reference.Declaration;
}
}
return null;
TargetDeclaration = declarations.FindVariable(selection);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using Microsoft.Vbe.Interop;
using Rubberduck.Common;
using Rubberduck.Parsing.Symbols;
using Rubberduck.VBEditor;

Expand Down Expand Up @@ -95,14 +96,14 @@ private void RemoveField(Declaration target)
{
Selection selection;
var declarationText = target.Context.GetText();
var multipleDeclarations = _model.HasMultipleDeclarationsInStatement(target);
var multipleDeclarations = target.HasMultipleDeclarationsInStatement();

var variableStmtContext = _model.GetVariableStmtContext(target);
var variableStmtContext = target.GetVariableStmtContext();

if (!multipleDeclarations)
{
declarationText = variableStmtContext.GetText();
selection = _model.GetVariableStmtContextSelection(target);
selection = target.GetVariableStmtContextSelection();
}
else
{
Expand All @@ -117,7 +118,7 @@ private void RemoveField(Declaration target)

if (multipleDeclarations)
{
selection = _model.GetVariableStmtContextSelection(target);
selection = target.GetVariableStmtContextSelection();
newLines = RemoveExtraComma(_editor.GetLines(selection).Replace(oldLines, newLines));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Parsing.Grammar;
using Rubberduck.Common;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.UI;
Expand Down Expand Up @@ -40,7 +40,7 @@ public void Refactor()

public void Refactor(QualifiedSelection selection)
{
var target = FindSelection(selection);
var target = _declarations.FindVariable(selection);

PromoteVariable(target);
}
Expand Down Expand Up @@ -71,14 +71,14 @@ private void RemoveVariable(Declaration target)
{
Selection selection;
var declarationText = target.Context.GetText();
var multipleDeclarations = HasMultipleDeclarationsInStatement(target);
var multipleDeclarations = target.HasMultipleDeclarationsInStatement();

var variableStmtContext = GetVariableStmtContext(target);
var variableStmtContext = target.GetVariableStmtContext();

if (!multipleDeclarations)
{
declarationText = variableStmtContext.GetText();
selection = GetVariableStmtContextSelection(target);
selection = target.GetVariableStmtContextSelection();
}
else
{
Expand All @@ -93,33 +93,14 @@ private void RemoveVariable(Declaration target)

if (multipleDeclarations)
{
selection = GetVariableStmtContextSelection(target);
selection = target.GetVariableStmtContextSelection();
newLines = RemoveExtraComma(_editor.GetLines(selection).Replace(oldLines, newLines));
}

_editor.DeleteLines(selection);
_editor.InsertLines(selection.StartLine, newLines);
}

private Selection GetVariableStmtContextSelection(Declaration target)
{
var statement = GetVariableStmtContext(target);

return new Selection(statement.Start.Line, statement.Start.Column,
statement.Stop.Line, statement.Stop.Column);
}

private VBAParser.VariableStmtContext GetVariableStmtContext(Declaration target)
{
var statement = target.Context.Parent.Parent as VBAParser.VariableStmtContext;
if (statement == null)
{
throw new NullReferenceException("Statement not found");
}

return statement;
}

private string RemoveExtraComma(string str)
{
if (str.Count(c => c == ',') == 1)
Expand Down Expand Up @@ -150,51 +131,11 @@ private string RemoveExtraComma(string str)
return str.Remove(str.LastIndexOf(','), 1);
}

private bool HasMultipleDeclarationsInStatement(Declaration target)
{
var statement = target.Context.Parent as VBAParser.VariableListStmtContext;

return statement != null && statement.children.Count(i => i is VBAParser.VariableSubStmtContext) > 1;
}

private string GetFieldDefinition(Declaration target)
{
if (target == null) { return null; }

return "Private " + target.IdentifierName + " As " + target.AsTypeName;
}

private Declaration FindSelection(QualifiedSelection selection)
{
var target = _declarations
.FirstOrDefault(item => item.IsSelected(selection) || item.References.Any(r => r.IsSelected(selection)));

if (target != null) { return target; }

var targets = _declarations.Where(item => item.ComponentName == selection.QualifiedName.ComponentName);

foreach (var declaration in targets)
{
var declarationSelection = new Selection(declaration.Context.Start.Line,
declaration.Context.Start.Column,
declaration.Context.Stop.Line,
declaration.Context.Stop.Column + declaration.Context.Stop.Text.Length);

if (declarationSelection.Contains(selection.Selection) ||
!HasMultipleDeclarationsInStatement(declaration) && GetVariableStmtContextSelection(declaration).Contains(selection.Selection))
{
return declaration;
}

var reference =
declaration.References.FirstOrDefault(r => r.Selection.Contains(selection.Selection));

if (reference != null)
{
return reference.Declaration;
}
}
return null;
}
}
}
Loading