Skip to content

Commit

Permalink
Merge pull request #5561 from rubberduck-vba/next
Browse files Browse the repository at this point in the history
2.5.1 release
  • Loading branch information
retailcoder committed Aug 22, 2020
2 parents 6027378 + a110623 commit 333bfa0
Show file tree
Hide file tree
Showing 1,021 changed files with 46,378 additions and 17,250 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ CodeGraphData/

# Generated Artifacts
Rubberduck.CodeAnalysis.xml
Rubberduck.Parsing.xml

#Gradle
/.gradle/
/Rubberduck.CodeAnalysis/Rubberduck.CodeAnalysis.xml
/Rubberduck.Parsing/Rubberduck.Parsing.xml
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
<img alt="Rubberduck Open-Source VBE Add-In - VBA6 | VBA7 x86/x64 | VB6" src="https://user-images.githubusercontent.com/5751684/48656196-a507af80-e9ef-11e8-9c09-1ce3c619c019.png" />

<!-- campaign is no longer accepting donations
### Donate!

If you like this project and would like to thank its contributors, you are welcome to support our GoFundMe campaign to finance Rubberduck swag and international shipping - contributors will be getting t-shirts, mugs, and other cool things.
[![GoFundMe campaign](https://user-images.githubusercontent.com/5751684/29191799-e3d20b72-7dec-11e7-8ec6-0c69da4a3135.png)](https://www.gofundme.com/rubberduckvba)
-->
---

|Branch | Description | Build Status | Download link |
|------------|---|--------------|-|
Expand All @@ -20,9 +14,15 @@ If you like this project and would like to thank its contributors, you are welco
[![Chat on stackexchange](https://img.shields.io/badge/chat-on%20stackexchange-blue.svg)](https://chat.stackexchange.com/rooms/14929/vba-rubberducking)
[![License](https://img.shields.io/github/license/rubberduck-vba/Rubberduck.svg)](https://github.com/rubberduck-vba/Rubberduck/blob/next/LICENSE)

> **[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

> **[rubberduckvba.com](http://rubberduckvba.com)** | **[Rubberduck News](https://rubberduckvba.wordpress.com/)**
| **[Twitter (@rubberduckvba)](https://twitter.com/rubberduckvba)** | **[Wiki](https://github.com/rubberduck-vba/Rubberduck/wiki)**

Rubberduck is free, but keeping it visible online isn't. Donate to help us pay for hosting and keep the blog free of ads!

|Donate|Note |
|:------:|-|
|<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=UY5K5X36B7T2S&currency_code=CAD&source=url"><img alt="Donate via PayPal" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif"></a><p><sub>via PayPal</sub></p>|Donations in excess of what's needed to cover our fees will be donated to the <a href="https://mssociety.ca/">Multiple Sclerosis Society of Canada</a>.|

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Parsing.Symbols;

namespace Rubberduck.Inspections.CodePathAnalysis.Extensions
{
public static class NodeExtensions
{
public static IEnumerable<INode> GetFlattenedNodes(this INode node, IEnumerable<Type> excludedTypes)
public static IEnumerable<INode> FlattenedNodes(this INode node, IEnumerable<Type> excludedTypes)
{
foreach (var child in node.Children)
{
Expand All @@ -18,15 +17,15 @@ public static IEnumerable<INode> GetFlattenedNodes(this INode node, IEnumerable<
}
else
{
foreach (var nextChild in GetFlattenedNodes(child, excludedTypes))
foreach (var nextChild in FlattenedNodes(child, excludedTypes))
{
yield return nextChild;
}
}
}
}

public static IEnumerable<INode> GetNodes(this INode node, IEnumerable<Type> types)
public static IEnumerable<INode> Nodes(this INode node, ICollection<Type> types)
{
if (types.Contains(node.GetType()))
{
Expand All @@ -35,50 +34,42 @@ public static IEnumerable<INode> GetNodes(this INode node, IEnumerable<Type> typ

foreach (var child in node.Children)
{
foreach (var childNode in GetNodes(child, types))
foreach (var childNode in Nodes(child, types))
{
yield return childNode;
}
}
}

public static INode GetFirstNode(this INode node, IEnumerable<Type> excludedTypes)
public static INode GetFirstNode(this INode node, ICollection<Type> excludedTypes)
{
if (!excludedTypes.Contains(node.GetType()))
{
return node;
}

if (!node.Children.Any())
{
return null;
}

return GetFirstNode(node.Children[0], excludedTypes);
}

public static List<IdentifierReference> GetIdentifierReferences(this INode node)
public static bool TryGetAncestorNode<T>(this INode node, out T ancestor) where T: INode
{
var nodes = new List<IdentifierReference>();

var blockNodes = node.GetNodes(new[] { typeof(BlockNode) });
foreach (var block in blockNodes)
ancestor = default;
if (node.Parent is null)
{
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 false;
}

return nodes;
if (node.Parent is T result)
{
ancestor = result;
return true;
}
return TryGetAncestorNode(node.Parent, out ancestor);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Antlr4.Runtime.Tree;

namespace Rubberduck.Inspections.CodePathAnalysis.Nodes
{
public class AssignmentExpressionNode : NodeBase
{
public AssignmentExpressionNode(IParseTree tree) : base(tree) { }
}
}
4 changes: 4 additions & 0 deletions Rubberduck.CodeAnalysis/CodePathAnalysis/Walker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public INode GenerateTree(IParseTree tree, Declaration declaration)
case VBAParser.BlockContext _:
node = new BlockNode(tree);
break;
case VBAParser.LetStmtContext _:
case VBAParser.SetStmtContext _:
node = new AssignmentExpressionNode(tree);
break;
}

if (declaration.Context == tree)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.Parsing.VBA.DeclarationCaching;

namespace Rubberduck.CodeAnalysis.Inspections.Abstract
{
internal abstract class ArgumentReferenceInspectionFromDeclarationsBase : IdentifierReferenceInspectionFromDeclarationsBase
{
protected ArgumentReferenceInspectionFromDeclarationsBase(RubberduckParserState state)
: base(state) { }

protected abstract bool IsUnsuitableArgument(ArgumentReference reference, DeclarationFinder finder);

protected override IEnumerable<IdentifierReference> ObjectionableReferences(DeclarationFinder finder)
{
return ObjectionableDeclarations(finder)
.OfType<ParameterDeclaration>()
.SelectMany(parameter => parameter.ArgumentReferences);
}

protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder)
{
if (!(reference is ArgumentReference argumentReference))
{
return false;
}

return IsUnsuitableArgument(argumentReference, finder);
}
}

internal abstract class ArgumentReferenceInspectionFromDeclarationsBase<T> : IdentifierReferenceInspectionFromDeclarationsBase<T>
{
protected ArgumentReferenceInspectionFromDeclarationsBase(IDeclarationFinderProvider declarationFinderProvider)
: base(declarationFinderProvider)
{}

protected abstract (bool isResult, T properties) IsUnsuitableArgumentWithAdditionalProperties(ArgumentReference reference, DeclarationFinder finder);

protected override IEnumerable<IdentifierReference> ObjectionableReferences(DeclarationFinder finder)
{
return ObjectionableDeclarations(finder)
.OfType<ParameterDeclaration>()
.SelectMany(parameter => parameter.ArgumentReferences);
}

protected override (bool isResult, T properties) IsResultReferenceWithAdditionalProperties(IdentifierReference reference, DeclarationFinder finder)
{
if (!(reference is ArgumentReference argumentReference))
{
return (false, default);
}

return IsUnsuitableArgumentWithAdditionalProperties(argumentReference, finder);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
using System.Collections.Generic;
using System.Linq;
using Rubberduck.CodeAnalysis.Inspections.Results;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.Parsing.VBA.DeclarationCaching;
using Rubberduck.VBEditor;

namespace Rubberduck.CodeAnalysis.Inspections.Abstract
{
internal abstract class DeclarationInspectionBase : DeclarationInspectionBaseBase
{
protected DeclarationInspectionBase(IDeclarationFinderProvider declarationFinderProvider, params DeclarationType[] relevantDeclarationTypes)
: base(declarationFinderProvider, relevantDeclarationTypes)
{}

protected DeclarationInspectionBase(IDeclarationFinderProvider declarationFinderProvider, DeclarationType[] relevantDeclarationTypes, DeclarationType[] excludeDeclarationTypes)
: base(declarationFinderProvider, relevantDeclarationTypes, excludeDeclarationTypes)
{}

protected abstract bool IsResultDeclaration(Declaration declaration, DeclarationFinder finder);
protected abstract string ResultDescription(Declaration declaration);

protected virtual ICollection<string> DisabledQuickFixes(Declaration declaration) => new List<string>();

protected override IEnumerable<IInspectionResult> DoGetInspectionResults(QualifiedModuleName module, DeclarationFinder finder)
{
var objectionableDeclarations = RelevantDeclarationsInModule(module, finder)
.Where(declaration => IsResultDeclaration(declaration, finder));

return objectionableDeclarations
.Select(InspectionResult)
.ToList();
}

protected virtual IInspectionResult InspectionResult(Declaration declaration)
{
return new DeclarationInspectionResult(
this,
ResultDescription(declaration),
declaration,
disabledQuickFixes: DisabledQuickFixes(declaration));
}
}

internal abstract class DeclarationInspectionBase<T> : DeclarationInspectionBaseBase
{
protected DeclarationInspectionBase(IDeclarationFinderProvider declarationFinderProvider, params DeclarationType[] relevantDeclarationTypes)
: base(declarationFinderProvider, relevantDeclarationTypes)
{}

protected DeclarationInspectionBase(IDeclarationFinderProvider declarationFinderProvider , DeclarationType[] relevantDeclarationTypes, DeclarationType[] excludeDeclarationTypes)
: base(declarationFinderProvider, relevantDeclarationTypes, excludeDeclarationTypes)
{}

protected abstract (bool isResult, T properties) IsResultDeclarationWithAdditionalProperties(Declaration declaration, DeclarationFinder finder);
protected abstract string ResultDescription(Declaration declaration, T properties);

protected virtual ICollection<string> DisabledQuickFixes(Declaration declaration, T properties) => new List<string>();

protected override IEnumerable<IInspectionResult> DoGetInspectionResults(QualifiedModuleName module, DeclarationFinder finder)
{
var objectionableDeclarationsWithAdditionalProperties = RelevantDeclarationsInModule(module, finder)
.Select(declaration => DeclarationWithResultProperties(declaration, finder))
.Where(result => result.HasValue)
.Select(result => result.Value);

return objectionableDeclarationsWithAdditionalProperties
.Select(tpl => InspectionResult(tpl.declaration, tpl.properties))
.ToList();
}

private (Declaration declaration, T properties)? DeclarationWithResultProperties(Declaration declaration, DeclarationFinder finder)
{
var (isResult, properties) = IsResultDeclarationWithAdditionalProperties(declaration, finder);
return isResult
? (declaration, properties)
: ((Declaration declaration, T properties)?) null;
}

protected virtual IInspectionResult InspectionResult(Declaration declaration, T properties)
{
return new DeclarationInspectionResult<T>(
this,
ResultDescription(declaration, properties),
declaration,
properties: properties,
disabledQuickFixes: DisabledQuickFixes(declaration, properties));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.Parsing.VBA.DeclarationCaching;
using Rubberduck.VBEditor;

namespace Rubberduck.CodeAnalysis.Inspections.Abstract
{
/// <summary>
/// This is a base class for the other declaration inspection base classes. It should not be implemented directly by concrete inspections.
/// </summary>
internal abstract class DeclarationInspectionBaseBase : InspectionBase
{
private readonly DeclarationType[] _relevantDeclarationTypes;
private readonly DeclarationType[] _excludeDeclarationTypes;

protected DeclarationInspectionBaseBase(IDeclarationFinderProvider declarationFinderProvider, params DeclarationType[] relevantDeclarationTypes)
: base(declarationFinderProvider)
{
_relevantDeclarationTypes = relevantDeclarationTypes;
_excludeDeclarationTypes = new DeclarationType[0];
}

protected DeclarationInspectionBaseBase(IDeclarationFinderProvider declarationFinderProvider, DeclarationType[] relevantDeclarationTypes, DeclarationType[] excludeDeclarationTypes)
: base(declarationFinderProvider)
{
_relevantDeclarationTypes = relevantDeclarationTypes;
_excludeDeclarationTypes = excludeDeclarationTypes;
}

protected override IEnumerable<IInspectionResult> DoGetInspectionResults(DeclarationFinder finder)
{
return finder.UserDeclarations(DeclarationType.Module)
.Concat(finder.UserDeclarations(DeclarationType.Project))
.Where(declaration => declaration != null)
.SelectMany(declaration => DoGetInspectionResults(declaration.QualifiedModuleName, finder))
.ToList();
}

protected virtual IEnumerable<Declaration> RelevantDeclarationsInModule(QualifiedModuleName module, DeclarationFinder finder)
{
var potentiallyRelevantDeclarations = _relevantDeclarationTypes.Length == 0
? finder.Members(module)
: _relevantDeclarationTypes
.SelectMany(declarationType => finder.Members(module, declarationType))
.Distinct();
return potentiallyRelevantDeclarations
.Where(declaration => !_excludeDeclarationTypes.Contains(declaration.DeclarationType));
}
}
}
Loading

0 comments on commit 333bfa0

Please sign in to comment.