Skip to content

Commit e3b158d

Browse files
committed
Introduce ProcedureRequiredInspection
This inspection reports all places in which an unparameterized procedure call is required but an object variable has been provided.
1 parent 5a733e9 commit e3b158d

File tree

11 files changed

+630
-0
lines changed

11 files changed

+630
-0
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Rubberduck.Inspections.Abstract;
4+
using Rubberduck.Inspections.Inspections.Extensions;
5+
using Rubberduck.Inspections.Results;
6+
using Rubberduck.Parsing.Inspections;
7+
using Rubberduck.Parsing.Inspections.Abstract;
8+
using Rubberduck.Parsing.Symbols;
9+
using Rubberduck.Parsing.VBA;
10+
using Rubberduck.Resources.Inspections;
11+
12+
namespace Rubberduck.CodeAnalysis.Inspections.Concrete
13+
{
14+
/// <summary>
15+
/// Locates places in which a procedure needs to be called but an object variables has been provided that does not have a suitable default member.
16+
/// </summary>
17+
/// <why>
18+
/// 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.
19+
/// </why>
20+
/// <example hasResult="true">
21+
/// <![CDATA[
22+
/// Class1:
23+
///
24+
/// Public Sub Foo()
25+
/// 'No default member attribute
26+
/// End Sub
27+
///
28+
/// ------------------------------
29+
/// Module1:
30+
///
31+
/// Public Sub DoIt()
32+
/// Dim cls As Class1
33+
/// Set cls = New Class1
34+
/// cls
35+
/// End Sub
36+
/// ]]>
37+
/// </example>
38+
/// <example hasResult="false">
39+
/// <![CDATA[
40+
/// Class1:
41+
///
42+
/// Public Sub Foo()
43+
/// Attribute Foo.UserMemId = 0
44+
/// End Sub
45+
///
46+
/// ------------------------------
47+
/// Module1:
48+
///
49+
/// Public Sub DoIt()
50+
/// Dim cls As Class1
51+
/// Set cls = New Class1
52+
/// cls
53+
/// End Sub
54+
/// ]]>
55+
/// </example>
56+
public class ProcedureRequiredInspection : InspectionBase
57+
{
58+
private readonly IDeclarationFinderProvider _declarationFinderProvider;
59+
60+
public ProcedureRequiredInspection(RubberduckParserState state)
61+
: base(state)
62+
{
63+
_declarationFinderProvider = state;
64+
65+
//This will most likely cause a runtime error. The exceptions are rare and should be refactored or made explicit with an @Ignore annotation.
66+
Severity = CodeInspectionSeverity.Error;
67+
}
68+
69+
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
70+
{
71+
var finder = _declarationFinderProvider.DeclarationFinder;
72+
73+
var failedProcedureCoercions = finder.FailedProcedureCoercions();
74+
return failedProcedureCoercions
75+
.Where(failedCoercion => !IsIgnored(failedCoercion))
76+
.Select(failedCoercion => InspectionResult(failedCoercion, _declarationFinderProvider));
77+
}
78+
79+
private bool IsIgnored(IdentifierReference assignment)
80+
{
81+
return assignment.IsIgnoringInspectionResultFor(AnnotationName);
82+
}
83+
84+
private IInspectionResult InspectionResult(IdentifierReference failedCoercion, IDeclarationFinderProvider declarationFinderProvider)
85+
{
86+
return new IdentifierReferenceInspectionResult(this,
87+
ResultDescription(failedCoercion),
88+
declarationFinderProvider,
89+
failedCoercion);
90+
}
91+
92+
private string ResultDescription(IdentifierReference failedCoercion)
93+
{
94+
var expression = failedCoercion.IdentifierName;
95+
var typeName = failedCoercion.Declaration?.FullAsTypeName;
96+
return string.Format(InspectionResults.ProcedureRequiredInspection, expression, typeName);
97+
}
98+
}
99+
}

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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,7 @@ Falls der Parameter 'null' sein kann, bitte dieses Auftreten ignorieren. 'null'
397397
<data name="ValueRequiredInspection" xml:space="preserve">
398398
<value>Der VBA-Compiler gibt keinen Fehler aus, wenn ein Objekt an einer Stelle verwendet wird, die einen Wert verlangt, und der deklarierte Type des Objekts keinen passenden Standardmember hat. In fast allen Fällen führt dies zu einem Laufzeitfehler, der schwerer zu entdecken ist und auf einen Programmierfehler hinweist.</value>
399399
</data>
400+
<data name="ProcedureRequiredInspection" xml:space="preserve">
401+
<value>Der VBA-Compiler gibt keinen Fehler aus, wenn eine Objektvariable an einer Stelle verwendet wird, die eine Prozedur erfordert, und der deklarierte Type des Objekts keinen passenden Standardmember hat. In fast allen Fällen führt dies zu einem Laufzeitfehler, der schwerer zu entdecken ist und auf einen Programmierfehler hinweist.</value>
402+
</data>
400403
</root>

Rubberduck.Resources/Inspections/InspectionInfo.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,7 @@ If the parameter can be null, ignore this inspection result; passing a null valu
397397
<data name="ValueRequiredInspection" xml:space="preserve">
398398
<value>The VBA compiler does not raise an error if an object is used in a place that requires a value type and the object's declared type does not have a suitable default member. Under almost all circumstances, this leads to a run-time error, which is harder to detect and indicates a bug.</value>
399399
</data>
400+
<data name="ProcedureRequiredInspection" xml:space="preserve">
401+
<value>The VBA compiler does not raise an error if an object variable is used in a place that requires a procedure and the object's declared type does not have a suitable default member. Under almost all circumstances, this leads to a run-time error, which is harder to detect and indicates a bug.</value>
402+
</data>
400403
</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
@@ -381,4 +381,7 @@
381381
<data name="ValueRequiredInspection" xml:space="preserve">
382382
<value>Objekt statt Wert verwendet</value>
383383
</data>
384+
<data name="ProcedureRequiredInspection" xml:space="preserve">
385+
<value>Objekt statt Prozedur verwendet</value>
386+
</data>
384387
</root>

Rubberduck.Resources/Inspections/InspectionNames.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,4 +401,7 @@
401401
<data name="ValueRequiredInspection" xml:space="preserve">
402402
<value>Object used where a value is required</value>
403403
</data>
404+
<data name="ProcedureRequiredInspection" xml:space="preserve">
405+
<value>Object used where a procedure is required</value>
406+
</data>
404407
</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
@@ -422,4 +422,7 @@ In Memoriam, 1972-2018</value>
422422
<data name="ValueRequiredInspection" xml:space="preserve">
423423
<value>An einer Stelle, die einen Wert verlangt, wird der Ausdruck '{0}' vom Objekttyp '{1}' verwendet, der keinen passendes Standardmember hat.</value>
424424
</data>
425+
<data name="ProcedureRequiredInspection" xml:space="preserve">
426+
<value>An einer Stelle, die eine Prozedur erfordert, wird der Ausdruck '{0}' vom Objekttyp '{1}' verwendet, der keinen passendes Standardmember hat.</value>
427+
</data>
425428
</root>

Rubberduck.Resources/Inspections/InspectionResults.resx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,8 @@ In memoriam, 1972-2018</value>
450450
<value>In a context that requires a value type, the expression '{0}' of object type '{1}' is used that does not have a suitable default member.</value>
451451
<comment>{0} expression; {1} type</comment>
452452
</data>
453+
<data name="ProcedureRequiredInspection" xml:space="preserve">
454+
<value>In a context that requires a procedure, the expression '{0}' of object type '{1}' is used that does not have a suitable default member.</value>
455+
<comment>{0} expression; {1} type</comment>
456+
</data>
453457
</root>

0 commit comments

Comments
 (0)