diff --git a/Rubberduck.CodeAnalysis/Inspections/Abstract/MemberAccessMayReturnNothingInspectionBase.cs b/Rubberduck.CodeAnalysis/Inspections/Abstract/MemberAccessMayReturnNothingInspectionBase.cs
index b0defd534a..e4e2389ca8 100644
--- a/Rubberduck.CodeAnalysis/Inspections/Abstract/MemberAccessMayReturnNothingInspectionBase.cs
+++ b/Rubberduck.CodeAnalysis/Inspections/Abstract/MemberAccessMayReturnNothingInspectionBase.cs
@@ -19,12 +19,20 @@ protected MemberAccessMayReturnNothingInspectionBase(IDeclarationFinderProvider
: base(declarationFinderProvider)
{}
+ ///
+ /// Members that might return Nothing
+ ///
+ ///
+ /// It must not be legal to call the members unqualified. In particular, user-defined members will not be considered.
+ /// Moreover, this disqualifies all members on global objects.
+ ///
public abstract IEnumerable MembersUnderTest(DeclarationFinder finder);
public abstract string ResultTemplate { get; }
protected override IEnumerable ObjectionableDeclarations(DeclarationFinder finder)
{
- return MembersUnderTest(finder);
+ //This restriction is in place because the inspection currently cannot handle unqualified accesses.
+ return MembersUnderTest(finder).Where(member => !member.IsUserDefined);
}
protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder)
@@ -46,7 +54,7 @@ protected override bool IsResultReference(IdentifierReference reference, Declara
{
return usageContext is VBAParser.MemberAccessExprContext
|| !(usageContext is VBAParser.CallStmtContext)
- && !ContextIsNothingTest(usageContext);
+ && !ContextIsNothing(usageContext);
}
var assignedTo = AssignmentTarget(reference, finder, setter);
@@ -65,14 +73,21 @@ private static IdentifierReference AssignmentTarget(IdentifierReference referenc
private static RuleContext UsageContext(IdentifierReference reference)
{
- var access = reference.Context.GetAncestor();
- var usageContext = access.Parent is VBAParser.IndexExprContext indexExpr
+ //We prefer the with member access over the member access, because the accesses are resolved right to left.
+ var access = reference.Context.GetAncestor() as VBAParser.LExpressionContext
+ ?? reference.Context.GetAncestor();
+
+ if (access == null)
+ {
+ return null;
+ }
+
+ return access.Parent is VBAParser.IndexExprContext indexExpr
? indexExpr.Parent
: access.Parent;
- return usageContext;
}
- private static bool ContextIsNothingTest(IParseTree context)
+ private static bool ContextIsNothing(IParseTree context)
{
return context is VBAParser.LExprContext
&& context.Parent is VBAParser.RelationalOpContext comparison
@@ -86,7 +101,7 @@ private static bool IsUsedBeforeCheckingForNothing(IdentifierReference assignedT
var firstUse = GetReferenceNodes(tree).FirstOrDefault();
return !(firstUse is null)
- && !ContextIsNothingTest(firstUse.Reference.Context.Parent);
+ && !ContextIsNothing(firstUse.Reference.Context.Parent);
}
private static IEnumerable GetReferenceNodes(INode node)
diff --git a/Rubberduck.Core/UI/Inspections/InspectionResultsControl.xaml b/Rubberduck.Core/UI/Inspections/InspectionResultsControl.xaml
index 53fd28924f..6e5313a0af 100644
--- a/Rubberduck.Core/UI/Inspections/InspectionResultsControl.xaml
+++ b/Rubberduck.Core/UI/Inspections/InspectionResultsControl.xaml
@@ -200,7 +200,6 @@
SelectedItem="{Binding SelectedItem}"
SelectionUnit="FullRow"
ItemsSource="{Binding Results, NotifyOnSourceUpdated=True}"
- RequestBringIntoView="InspectionResultsGrid_RequestBringIntoView"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
diff --git a/Rubberduck.Core/UI/Refactorings/EncapsulateField/EncapsulateFieldView.xaml b/Rubberduck.Core/UI/Refactorings/EncapsulateField/EncapsulateFieldView.xaml
index 7174477f0f..518d258469 100644
--- a/Rubberduck.Core/UI/Refactorings/EncapsulateField/EncapsulateFieldView.xaml
+++ b/Rubberduck.Core/UI/Refactorings/EncapsulateField/EncapsulateFieldView.xaml
@@ -144,6 +144,7 @@
Text="{Binding Path=PropertyName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
TabIndex="1" Margin="10,5"
VerticalAlignment="Center"
+ VerticalContentAlignment="Center"
Height="22" />
diff --git a/Rubberduck.Core/UI/UnitTesting/TestExplorerViewModel.cs b/Rubberduck.Core/UI/UnitTesting/TestExplorerViewModel.cs
index b8b14f5d63..97fffd92c5 100644
--- a/Rubberduck.Core/UI/UnitTesting/TestExplorerViewModel.cs
+++ b/Rubberduck.Core/UI/UnitTesting/TestExplorerViewModel.cs
@@ -256,6 +256,7 @@ public bool CanExecuteIgnoreSelectedTests(object obj)
return false;
}
+
public bool CanExecuteUnignoreSelectedTests(object obj)
{
if (!Model.IsBusy && obj is IList viewModels && viewModels.Count > 0)
@@ -273,12 +274,14 @@ public bool CanExecuteIgnoreGroupCommand(object obj)
return groupItems.Cast().Count(test => test.Method.IsIgnored) != groupItems.Count;
}
+
public bool CanExecuteUnignoreGroupCommand(object obj)
{
var groupItems = MouseOverGroup?.Items
- ?? GroupContainingSelectedTest(MouseOverTest).Items;
-
- return groupItems.Cast().Any(test => test.Method.IsIgnored);
+ ?? GroupContainingSelectedTest(MouseOverTest)?.Items;
+
+ return groupItems != null
+ && groupItems.Cast().Any(test => test.Method.IsIgnored);
}
#region Commands
diff --git a/Rubberduck.Resources/Inspections/InspectionResults.de.resx b/Rubberduck.Resources/Inspections/InspectionResults.de.resx
index 1ace9a322a..e6936ac846 100644
--- a/Rubberduck.Resources/Inspections/InspectionResults.de.resx
+++ b/Rubberduck.Resources/Inspections/InspectionResults.de.resx
@@ -183,7 +183,7 @@
Der Variable '{0}' wird kein Wert zugewiesen.
- vbNullString' sollte statt einem leeren String-Literal verwendet werden.
+ 'vbNullString' sollte statt einem leeren String-Literal verwendet werden.
Objektvariable '{0}' wird ohne das 'Set'-Schlüsselwort zugewiesen.
@@ -467,4 +467,4 @@ In Memoriam, 1972-2018
Die Annotation '{0}' erwartet weniger Argumente.
-
\ No newline at end of file
+
diff --git a/RubberduckTests/Inspections/ExcelMemberMayReturnNothingInspectionTests.cs b/RubberduckTests/Inspections/ExcelMemberMayReturnNothingInspectionTests.cs
index 89925a4948..72a5843a82 100644
--- a/RubberduckTests/Inspections/ExcelMemberMayReturnNothingInspectionTests.cs
+++ b/RubberduckTests/Inspections/ExcelMemberMayReturnNothingInspectionTests.cs
@@ -26,6 +26,22 @@ End Sub
Assert.AreEqual(1, InspectionResults(inputCode).Count());
}
+ [Test]
+ [Category("Inspections")]
+ public void ExcelMemberMayReturnNothing_ReturnsResult_WithMemberAccessOnFind()
+ {
+ const string inputCode =
+ @"Sub UnderTest()
+ Dim ws As Worksheet
+ Set ws = Sheet1
+ With ws.UsedRange
+ foo = .Find(""foo"").Row
+ End With
+End Sub
+";
+ Assert.AreEqual(1, InspectionResults(inputCode).Count());
+ }
+
[Test]
[Category("Inspections")]
public void ExcelMemberMayReturnNothing_Ignored_DoesNotReturnResult()
@@ -111,6 +127,25 @@ End Sub
Assert.AreEqual(1, InspectionResults(inputCode).Count());
}
+ [Test]
+ [Category("Inspections")]
+ public void ExcelMemberMayReturnNothing_ReturnsResult_AssignedAndNotTested_FromWithMemberAccess()
+ {
+ const string inputCode =
+ @"Sub UnderTest()
+ Dim ws As Worksheet
+ Set ws = Sheet1
+ Dim result As Range
+ With ws.UsedRange
+ Set result = .Find(""foo"")
+ End With
+ result.Value = ""bar""
+End Sub
+";
+
+ Assert.AreEqual(1, InspectionResults(inputCode).Count());
+ }
+
[Test]
[Category("Inspections")]
public void ExcelMemberMayReturnNothing_ReturnsResult_ResultIsSomethingElse()