Skip to content

Commit 8bd09db

Browse files
committed
Add UseOfRecursiveBangNotationInspection
1 parent 96e159d commit 8bd09db

11 files changed

+459
-1
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using Rubberduck.Inspections.Abstract;
2+
using Rubberduck.Resources.Inspections;
3+
using Rubberduck.Parsing.Symbols;
4+
using Rubberduck.Parsing.VBA;
5+
using Rubberduck.Inspections.Inspections.Extensions;
6+
using Rubberduck.Parsing.Grammar;
7+
using Rubberduck.Parsing.Inspections;
8+
9+
namespace Rubberduck.Inspections.Concrete
10+
{
11+
/// <summary>
12+
/// Identifies the use of bang notation, formally known as dictionary access expression, for which a recursive default member resolution is necessary.
13+
/// </summary>
14+
/// <why>
15+
/// A dictionary access expression looks like a strongly typed call, but it actually is a stringly typed access to the parameterized default member of the object.
16+
/// This is especially misleading if the parameterized default member is not on the object itself and can only be reached by calling the parameterless default member first.
17+
/// </why>
18+
/// <example hasResult="true">
19+
/// <![CDATA[
20+
/// Public Function MyName(ByVal rst As ADODB.Recordset) As Variant
21+
/// MyName = rst!Name.Value
22+
/// End Function
23+
/// ]]>
24+
/// </example>
25+
/// <example hasResult="true">
26+
/// <![CDATA[
27+
/// Public Function MyName(ByVal rst As ADODB.Recordset) As Variant
28+
/// With rst
29+
/// !Name.Value
30+
/// End With
31+
/// End Function
32+
/// ]]>
33+
/// </example>
34+
/// <example hasResult="false">
35+
/// <![CDATA[
36+
/// Public Function MyName(ByVal rst As ADODB.Recordset) As Variant
37+
/// MyName = rst.Fields.Item("Name").Value
38+
/// End Function
39+
/// ]]>
40+
/// </example>
41+
/// <example hasResult="false">
42+
/// <![CDATA[
43+
/// Public Function MyName(ByVal rst As ADODB.Recordset) As Variant
44+
/// MyName = rst("Name").Value
45+
/// End Function
46+
/// ]]>
47+
/// </example>
48+
/// <example hasResult="false">
49+
/// <![CDATA[
50+
/// Public Function MyName(ByVal rst As ADODB.Recordset) As Variant
51+
/// MyName = rst.Fields!Name.Value
52+
/// End Function
53+
/// ]]>
54+
/// </example>
55+
/// <example hasResult="false">
56+
/// <![CDATA[
57+
/// Public Function MyName(ByVal rst As ADODB.Recordset) As Variant
58+
/// With rst
59+
/// MyName = .Fields.Item("Name").Value
60+
/// End With
61+
/// End Function
62+
/// ]]>
63+
/// </example>
64+
public sealed class UseOfRecursiveBangNotationInspection : IdentifierReferenceInspectionBase
65+
{
66+
public UseOfRecursiveBangNotationInspection(RubberduckParserState state)
67+
: base(state)
68+
{
69+
Severity = CodeInspectionSeverity.Suggestion;
70+
}
71+
72+
protected override bool IsResultReference(IdentifierReference reference)
73+
{
74+
return reference.IsIndexedDefaultMemberAccess
75+
&& reference.DefaultMemberRecursionDepth > 1
76+
&& reference.Context is VBAParser.DictionaryAccessContext
77+
&& !reference.IsIgnoringInspectionResultFor(AnnotationName);
78+
}
79+
80+
protected override string ResultDescription(IdentifierReference reference)
81+
{
82+
var expression = reference.IdentifierName;
83+
return string.Format(InspectionResults.UseOfRecursiveBangNotationInspection, expression);
84+
}
85+
}
86+
}

Rubberduck.Resources/Inspections/InspectionInfo.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rubberduck.Resources/Inspections/InspectionInfo.de.resx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ Falls der Parameter 'null' sein kann, bitte dieses Auftreten ignorieren. 'null'
404404
<value>Der VBA-Compiler gibt keinen Fehler aus, wenn ein Standardmemberzugriff nötig ist, aber der der deklarierte Type des Objekts keinen passenden Standardmember hat. In fast allen Fällen führt dies zu einem Laufzeitfehler91 'Objektvariable oder With-Blockvariable nicht festgelegt' oder 438 'Objekt unterstützt diese Eigenschaft oder Methode nicht' abhängig davon, ob die Variable den Wert 'Nothing' hat oder nicht, der schwerer zu entdecken ist und auf einen Programmierfehler hinweist.</value>
405405
</data>
406406
<data name="UseOfBangNotationInspection" xml:space="preserve">
407-
<value>Die Ausrufezeichennotation erweckt den Eindruck, dass es sich um einen Zugriff handelt, der Typchecks unterliegt. Allerdings handelt es sich lediglich um einen Zugriff auf den Standardmember des Objekts, auf das sie angewendent wird, bei dem das Argument als Zeichenkette übergeben wird.</value>
407+
<value>Die Ausrufezeichennotation erweckt den Eindruck, dass es sich um einen Zugriff handelt, der Typchecks unterliegt. Allerdings handelt es sich lediglich um einen Zugriff auf den Standardmember des Objekts, auf das sie angewendet wird, bei dem das Argument als Zeichenkette übergeben wird.</value>
408+
</data>
409+
<data name="UseOfRecursiveBangNotationInspection" xml:space="preserve">
410+
<value>Die Ausrufezeichennotation erweckt den Eindruck, dass es sich um einen Zugriff handelt, der Typchecks unterliegt. Allerdings handelt es sich lediglich um einen Zugriff auf den Standardmember des Objekts, auf das sie angewendet wird, bei dem das Argument als Zeichenkette übergeben wird. Dies ist besonders verwirrend, wenn der Standardmember des Objekts selber keine Zeichenkette akzeptiert und deshalb ein rekursiver Zugriff auf den parameterlosen Standardmember erfolgen muss.</value>
408411
</data>
409412
</root>

Rubberduck.Resources/Inspections/InspectionInfo.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,7 @@ If the parameter can be null, ignore this inspection result; passing a null valu
406406
<data name="UseOfBangNotationInspection" xml:space="preserve">
407407
<value>Bang notation, formally known as dictionary access expression, looks like it is strongly typed. However, it is actually a stringly typed access to the paramterized default member of the object it is used on.</value>
408408
</data>
409+
<data name="UseOfRecursiveBangNotationInspection" xml:space="preserve">
410+
<value>Bang notation, formally known as dictionary access expression, looks like it is strongly typed. However, it is actually a stringly typed access to the paramterized default member of the object it is used on. This is especially misleading if the parameterized default member is not on the object itself and can only be reached by calling the parameterless default member first. </value>
411+
</data>
409412
</root>

Rubberduck.Resources/Inspections/InspectionNames.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rubberduck.Resources/Inspections/InspectionNames.de.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,4 +390,7 @@
390390
<data name="UseOfBangNotationInspection" xml:space="preserve">
391391
<value>Verwendung der Ausrufezeichennotation</value>
392392
</data>
393+
<data name="UseOfRecursiveBangNotationInspection" xml:space="preserve">
394+
<value>Verwendung rekursiver Ausrufezeichennotation</value>
395+
</data>
393396
</root>

Rubberduck.Resources/Inspections/InspectionNames.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,4 +410,7 @@
410410
<data name="UseOfBangNotationInspection" xml:space="preserve">
411411
<value>Use of bang notation</value>
412412
</data>
413+
<data name="UseOfRecursiveBangNotationInspection" xml:space="preserve">
414+
<value>Use of recursive bang notation</value>
415+
</data>
413416
</root>

Rubberduck.Resources/Inspections/InspectionResults.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rubberduck.Resources/Inspections/InspectionResults.de.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,4 +431,7 @@ In Memoriam, 1972-2018</value>
431431
<data name="UseOfBangNotationInspection" xml:space="preserve">
432432
<value>Der Ausdruck '{0}' verwendet Ausrufezeichennotation.</value>
433433
</data>
434+
<data name="UseOfRecursiveBangNotationInspection" xml:space="preserve">
435+
<value>Der Ausdruck '{0}' verwendet rekursive Ausrufezeichennotation.</value>
436+
</data>
434437
</root>

Rubberduck.Resources/Inspections/InspectionResults.resx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,4 +462,8 @@ In memoriam, 1972-2018</value>
462462
<value>The expression '{0}' contains a use of bang notation.</value>
463463
<comment>{0} expression</comment>
464464
</data>
465+
<data name="UseOfRecursiveBangNotationInspection" xml:space="preserve">
466+
<value>The expression '{0}' contains a use of recursive bang notation.</value>
467+
<comment>{0} expression</comment>
468+
</data>
465469
</root>

0 commit comments

Comments
 (0)