Skip to content

Commit

Permalink
Merge branch 'next' into 5237-CodeInspectionScrollbarFix
Browse files Browse the repository at this point in the history
  • Loading branch information
glowingrunes committed Oct 23, 2019
2 parents f1d3be4 + 347c603 commit 2b4a094
Show file tree
Hide file tree
Showing 151 changed files with 3,946 additions and 4,072 deletions.
20 changes: 16 additions & 4 deletions Rubberduck.CodeAnalysis/Inspections/Abstract/QuickFixBase.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using NLog;
using Rubberduck.Parsing.Inspections.Abstract;
Expand All @@ -24,17 +25,28 @@ public void RegisterInspections(params Type[] inspections)
{
if (!inspections.All(s => s.GetInterfaces().Any(a => a == typeof(IInspection))))
{
#if DEBUG
throw new ArgumentException($"Parameters must implement {nameof(IInspection)}", nameof(inspections));
#else
var dieNow = false;
MustThrowException(ref dieNow);
if (dieNow)
{
throw new ArgumentException($"Parameters must implement {nameof(IInspection)}",
nameof(inspections));
}

inspections.Where(s => s.GetInterfaces().All(i => i != typeof(IInspection))).ToList()
.ForEach(i => Logger.Error($"Type {i.Name} does not implement {nameof(IInspection)}"));
#endif
}

_supportedInspections = inspections.ToHashSet();
}

// ReSharper disable once RedundantAssignment : conditional must be void but we can use ref
[Conditional("DEBUG")]
private static void MustThrowException(ref bool dieNow)
{
dieNow = true;
}

public void RemoveInspections(params Type[] inspections)
{
_supportedInspections = _supportedInspections.Except(inspections).ToHashSet();
Expand Down
Expand Up @@ -21,7 +21,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// <why>
/// The VBA compiler does not check whether different object types are compatible. Instead there is a runtime error whenever the types are incompatible.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// IInterface:
///
Expand Down Expand Up @@ -49,7 +49,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// IInterface:
///
Expand Down
Expand Up @@ -15,7 +15,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// <why>
/// The VBA compiler does not check whether the necessary default member is present. Instead there is a runtime error whenever the runtime type fails to have the default member.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Class1:
///
Expand All @@ -34,7 +34,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Class1:
///
Expand Down
Expand Up @@ -6,8 +6,11 @@
using System.Collections.Generic;
using System.Linq;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Inspections.Inspections.Extensions;
using Rubberduck.Common;
using Rubberduck.Inspections.Inspections.Extensions;
using Rubberduck.Parsing.VBA.DeclarationCaching;
using Rubberduck.Parsing.VBA.Extensions;
using Rubberduck.VBEditor;

namespace Rubberduck.Inspections.Concrete
{
Expand Down Expand Up @@ -39,19 +42,48 @@ public EmptyMethodInspection(RubberduckParserState state)

protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
{
var allInterfaces = new HashSet<ClassModuleDeclaration>(State.DeclarationFinder.FindAllUserInterfaces());

return State.DeclarationFinder.UserDeclarations(DeclarationType.Member)
.Where(member => !allInterfaces.Any(userInterface => userInterface.QualifiedModuleName == member.QualifiedModuleName)
&& !((ModuleBodyElementDeclaration)member).Block.ContainsExecutableStatements())

.Select(result => new DeclarationInspectionResult(this,
string.Format(InspectionResults.EmptyMethodInspection,
Resources.RubberduckUI.ResourceManager
.GetString("DeclarationType_" + result.DeclarationType)
.Capitalize(),
result.IdentifierName),
result));
var finder = State.DeclarationFinder;

var userInterfaces = UserInterfaces(finder);
var emptyMethods = EmptyNonInterfaceMethods(finder, userInterfaces);

return emptyMethods.Select(Result);
}

private static ICollection<QualifiedModuleName> UserInterfaces(DeclarationFinder finder)
{
return finder
.FindAllUserInterfaces()
.Select(decl => decl.QualifiedModuleName)
.ToHashSet();
}

private static IEnumerable<Declaration> EmptyNonInterfaceMethods(DeclarationFinder finder, ICollection<QualifiedModuleName> userInterfaces)
{
return finder
.UserDeclarations(DeclarationType.Member)
.Where(member => !userInterfaces.Contains(member.QualifiedModuleName)
&& member is ModuleBodyElementDeclaration moduleBodyElement
&& !moduleBodyElement.Block.ContainsExecutableStatements());
}

private IInspectionResult Result(Declaration member)
{
return new DeclarationInspectionResult(
this,
ResultDescription(member),
member);
}

private static string ResultDescription(Declaration member)
{
var identifierName = member.IdentifierName;
var declarationType = member.DeclarationType.ToLocalizedString();

return string.Format(
InspectionResults.EmptyMethodInspection,
declarationType,
identifierName);
}
}
}
Expand Up @@ -40,8 +40,9 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
{
// we're creating a public field for every control on a form, needs to be ignored.
var fields = State.DeclarationFinder.UserDeclarations(DeclarationType.Variable)
.Where(item => item.Accessibility == Accessibility.Public
&& (item.DeclarationType != DeclarationType.Control))
.Where(item => item.DeclarationType != DeclarationType.Control
&& (item.Accessibility == Accessibility.Public ||
item.Accessibility == Accessibility.Global))
.ToList();

return fields
Expand Down
Expand Up @@ -14,31 +14,31 @@ namespace Rubberduck.Inspections.Concrete
/// Default member accesses hide away the actually called member. This is especially misleading if there is no indication in the expression that such a call is made
/// and can cause errors in which a member was forgotten to be called to go unnoticed.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As ADODB.Field)
/// Dim bar As Variant
/// bar = arg
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As ADODB.Connection)
/// Dim bar As String
/// arg = bar
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As ADODB.Field)
/// Dim bar As Variant
/// bar = arg.Value
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As ADODB.Connection)
/// Dim bar As String
Expand Down
Expand Up @@ -14,7 +14,7 @@ namespace Rubberduck.Inspections.Concrete
/// Default member accesses hide away the actually called member. This is especially misleading if there is no indication in the expression that such a call is made
/// and the final default member is not on the interface of the object itself. In particular, this can cause errors in which a member was forgotten to be called to go unnoticed.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <module name="Class1" type="Class Module">
/// <![CDATA[
/// Public Function Foo() As Class2
Expand All @@ -40,7 +40,7 @@ namespace Rubberduck.Inspections.Concrete
/// ]]>
/// </module>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <module name="Class1" type="Class Module">
/// <![CDATA[
/// Public Function Foo() As Class2
Expand Down
Expand Up @@ -17,29 +17,29 @@ namespace Rubberduck.Inspections.Concrete
/// and if the default member cannot be determined from the declared type of the object. As a consequence, errors in which a member was forgotten to be called can go unnoticed
/// and should there not be a suitable default member at runtime, an error 438 'Object doesn't support this property or method' will be raised.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As Object)
/// Dim bar As Variant
/// bar = arg
/// End Sub
/// ]]>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As Object)
/// Dim bar As Variant
/// arg = bar
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As Object)
/// Dim bar As Variant
/// bar = arg.SomeValueReturningMember
/// End Sub
/// ]]>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething(ByVal arg As Object)
/// Dim bar As Variant
Expand Down
Expand Up @@ -14,15 +14,15 @@ namespace Rubberduck.Inspections.Concrete
/// <why>
/// An indexed default member access hides away the actually called member.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething(ByVal coll As Collection)
/// Dim bar As Variant
/// bar = coll(23)
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething(ByVal coll As Collection)
/// Dim bar As Variant
Expand Down
Expand Up @@ -14,15 +14,15 @@ namespace Rubberduck.Inspections.Concrete
/// <why>
/// An indexed default member access hides away the actually called member. This is especially problematic if the corresponding parameterized default member is not on the interface of the object itself.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething(ByVal rst As ADODB.Recordset)
/// Dim bar As Variant
/// bar = rst("MyField")
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething(ByVal rst As ADODB.Recordset)
/// Dim bar As Variant
Expand Down
Expand Up @@ -17,15 +17,15 @@ namespace Rubberduck.Inspections.Concrete
/// An indexed default member access hides away the actually called member. This is especially problematic if the default member cannot be determined from the declared type of the object.
/// Should there not be a suitable default member at runtime, an error 438 'Object doesn't support this property or method' will be raised.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething(ByVal rst As Object)
/// Dim bar As Variant
/// bar = rst("MyField")
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething(ByVal rst As Object)
/// Dim bar As Variant
Expand Down
Expand Up @@ -20,7 +20,7 @@ namespace Rubberduck.Inspections.Concrete
/// Providing an object where a procedure is required leads to an implicit call to the object's default member.
/// This behavior is not obvious, and most likely unintended.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <module name="Class1" type="Class Module">
/// <![CDATA[
/// Public Function Foo() As Long
Expand All @@ -37,7 +37,7 @@ namespace Rubberduck.Inspections.Concrete
/// ]]>
/// </module>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <module name="Class1" type="Class Module">
/// <![CDATA[
/// Public Function Foo() As Long
Expand Down
Expand Up @@ -20,7 +20,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// 'While...Wend' loops were made obsolete when 'Do While...Loop' statements were introduced.
/// 'While...Wend' loops cannot be exited early without a GoTo jump; 'Do...Loop' statements can be conditionally exited with 'Exit Do'.
/// </why>
/// <example hasResults="true">
/// <example hasresult="true">
/// <![CDATA[
/// Public Sub DoSomething()
/// While True
Expand All @@ -29,7 +29,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// End Sub
/// ]]>
/// </example>
/// <example hasResults="false">
/// <example hasresult="false">
/// <![CDATA[
/// Public Sub DoSomething()
/// Do While True
Expand Down
Expand Up @@ -15,7 +15,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// <why>
/// The VBA compiler does not check whether the necessary default member is present. Instead there is a runtime error whenever the runtime type fails to have the default member.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// Class1:
///
Expand All @@ -33,7 +33,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// Class1:
///
Expand Down
Expand Up @@ -22,7 +22,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// <why>
/// The VBA compiler does not check whether different object types are compatible. Instead there is a runtime error whenever the types are incompatible.
/// </why>
/// <example hasResult="true">
/// <example hasresult="true">
/// <![CDATA[
/// IInterface:
///
Expand All @@ -49,7 +49,7 @@ namespace Rubberduck.CodeAnalysis.Inspections.Concrete
/// End Sub
/// ]]>
/// </example>
/// <example hasResult="false">
/// <example hasresult="false">
/// <![CDATA[
/// IInterface:
///
Expand Down

0 comments on commit 2b4a094

Please sign in to comment.