Skip to content

Commit a905663

Browse files
committed
add MissingAttributeAnnotation back in, disabled by default
1 parent 086a608 commit a905663

File tree

4 files changed

+729
-667
lines changed

4 files changed

+729
-667
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Antlr4.Runtime;
4+
using Rubberduck.Inspections.Abstract;
5+
using Rubberduck.Inspections.Results;
6+
using Rubberduck.Parsing;
7+
using Rubberduck.Parsing.Annotations;
8+
using Rubberduck.Parsing.Grammar;
9+
using Rubberduck.Parsing.Inspections;
10+
using Rubberduck.Parsing.Inspections.Abstract;
11+
using Rubberduck.Parsing.Symbols;
12+
using Rubberduck.Parsing.VBA;
13+
using Rubberduck.Parsing.VBA.Parsing;
14+
using Rubberduck.Resources.Inspections;
15+
16+
namespace Rubberduck.Inspections.Concrete
17+
{
18+
[CannotAnnotate]
19+
public sealed class MissingAttributeInspection : ParseTreeInspectionBase
20+
{
21+
public MissingAttributeInspection(RubberduckParserState state)
22+
: base(state)
23+
{
24+
Listener = new MissingMemberAttributeListener(state);
25+
}
26+
27+
public override CodeKind TargetKindOfCode => CodeKind.AttributesCode;
28+
29+
public override IInspectionListener Listener { get; }
30+
31+
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
32+
{
33+
return Listener.Contexts.Select(context =>
34+
{
35+
var name = string.Format(InspectionResults.MissingAttributeInspection, context.MemberName.MemberName,
36+
((VBAParser.AnnotationContext)context.Context).annotationName().GetText());
37+
return new QualifiedContextInspectionResult(this, name, context);
38+
});
39+
}
40+
41+
public class MissingMemberAttributeListener : ParseTreeListeners.AttributeAnnotationListener
42+
{
43+
public MissingMemberAttributeListener(RubberduckParserState state) : base(state) { }
44+
45+
public override void ExitAnnotation(VBAParser.AnnotationContext context)
46+
{
47+
var annotationType = context.AnnotationType;
48+
49+
if (!annotationType.HasFlag(AnnotationType.Attribute))
50+
{
51+
return;
52+
}
53+
54+
var isMemberAnnotation = annotationType.HasFlag(AnnotationType.MemberAnnotation);
55+
var isModuleScope = CurrentScopeDeclaration.DeclarationType.HasFlag(DeclarationType.Module);
56+
57+
if (isModuleScope && !isMemberAnnotation)
58+
{
59+
// module-level annotation
60+
var module = State.DeclarationFinder.UserDeclarations(DeclarationType.Module).Single(m => m.QualifiedName.QualifiedModuleName.Equals(CurrentModuleName));
61+
if (!module.Attributes.HasAttributeFor(context.AnnotationType))
62+
{
63+
AddContext(new QualifiedContext<ParserRuleContext>(CurrentModuleName, context));
64+
}
65+
}
66+
else if (isMemberAnnotation)
67+
{
68+
// member-level annotation is above the context for the first member in the module..
69+
if (isModuleScope)
70+
{
71+
CurrentScopeDeclaration = FirstMember;
72+
}
73+
74+
var member = Members.Value.Single(m => m.Key.Equals(CurrentScopeDeclaration.QualifiedName.MemberName));
75+
if (!member.Value.Attributes.HasAttributeFor(context.AnnotationType, member.Key))
76+
{
77+
AddContext(new QualifiedContext<ParserRuleContext>(CurrentModuleName, context));
78+
}
79+
}
80+
else
81+
{
82+
// annotation is illegal. ignore.
83+
}
84+
}
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)