Skip to content

Commit 70cce4a

Browse files
committed
Merge branch 'next' into FailedLetCoercionOnObjectInspection
# Conflicts: # Rubberduck.Parsing/VBA/RubberduckParserState.cs # RubberduckTests/Inspections/InspectionResultTests.cs
2 parents 4520cb5 + 225b09b commit 70cce4a

File tree

141 files changed

+1199
-1344
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+1199
-1344
lines changed

Rubberduck.API/VBA/Parser.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
using Rubberduck.Root;
2626
using Rubberduck.VBEditor.ComManagement.TypeLibs;
2727
using Rubberduck.VBEditor.SourceCodeHandling;
28+
using Rubberduck.Parsing.Annotations;
2829

2930
namespace Rubberduck.API.VBA
3031
{
@@ -106,6 +107,8 @@ internal Parser(object vbe) : this()
106107
var preprocessorErrorListenerFactory = new PreprocessingParseErrorListenerFactory();
107108
var preprocessorParser = new VBAPreprocessorParser(preprocessorErrorListenerFactory, preprocessorErrorListenerFactory);
108109
var preprocessor = new VBAPreprocessor(preprocessorParser, compilationsArgumentsCache);
110+
// FIXME inject annotations to allow Rubberduck api users to access Annotations from VBA code
111+
var annotationProcessor = new VBAParserAnnotationFactory(new List<IAnnotation>());
109112
var mainParseErrorListenerFactory = new MainParseErrorListenerFactory();
110113
var mainTokenStreamParser = new VBATokenStreamParser(mainParseErrorListenerFactory, mainParseErrorListenerFactory);
111114
var tokenStreamProvider = new SimpleVBAModuleTokenStreamProvider();
@@ -139,7 +142,8 @@ internal Parser(object vbe) : this()
139142
var moduleParser = new ModuleParser(
140143
codePaneSourceCodeHandler,
141144
attributesSourceCodeHandler,
142-
stringParser);
145+
stringParser,
146+
annotationProcessor);
143147
var parseRunner = new ParseRunner(
144148
_state,
145149
parserStateManager,

Rubberduck.CodeAnalysis/Inspections/Concrete/AttributeValueOutOfSyncInspection.cs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,27 @@ public AttributeValueOutOfSyncInspection(RubberduckParserState state)
4949
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
5050
{
5151
var declarationsWithAttributeAnnotations = State.DeclarationFinder.AllUserDeclarations
52-
.Where(declaration => declaration.Annotations.Any(annotation => annotation.AnnotationType.HasFlag(AnnotationType.Attribute)));
52+
.Where(declaration => declaration.Annotations.Any(pta => pta.Annotation is IAttributeAnnotation));
5353
var results = new List<DeclarationInspectionResult>();
5454
foreach (var declaration in declarationsWithAttributeAnnotations.Where(decl => decl.QualifiedModuleName.ComponentType != ComponentType.Document))
5555
{
56-
foreach (var annotation in declaration.Annotations.OfType<IAttributeAnnotation>())
56+
foreach (var annotationInstance in declaration.Annotations.Where(pta => pta.Annotation is IAttributeAnnotation))
5757
{
58-
if (HasDifferingAttributeValues(declaration, annotation, out var attributeValues))
58+
// cast is safe given the predicate in the foreach
59+
var annotation = (IAttributeAnnotation)annotationInstance.Annotation;
60+
if (HasDifferingAttributeValues(declaration, annotationInstance, out var attributeValues))
5961
{
62+
var attributeName = annotation.Attribute(annotationInstance);
63+
6064
var description = string.Format(InspectionResults.AttributeValueOutOfSyncInspection,
61-
annotation.Attribute,
65+
attributeName,
6266
string.Join(", ", attributeValues),
63-
annotation.AnnotationType);
67+
annotation.Name);
6468

6569
var result = new DeclarationInspectionResult(this, description, declaration,
66-
new QualifiedContext(declaration.QualifiedModuleName, annotation.Context));
67-
result.Properties.Annotation = annotation;
68-
result.Properties.AttributeName = annotation.Attribute;
70+
new QualifiedContext(declaration.QualifiedModuleName, annotationInstance.Context));
71+
result.Properties.Annotation = annotationInstance;
72+
result.Properties.AttributeName = attributeName;
6973
result.Properties.AttributeValues = attributeValues;
7074

7175
results.Add(result);
@@ -76,16 +80,22 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
7680
return results;
7781
}
7882

79-
private static bool HasDifferingAttributeValues(Declaration declaration, IAttributeAnnotation annotation, out IReadOnlyList<string> attributeValues)
83+
private static bool HasDifferingAttributeValues(Declaration declaration, IParseTreeAnnotation annotationInstance, out IReadOnlyList<string> attributeValues)
8084
{
85+
if (!(annotationInstance.Annotation is IAttributeAnnotation annotation))
86+
{
87+
attributeValues = new List<string>();
88+
return false;
89+
}
90+
var attribute = annotation.Attribute(annotationInstance);
8191
var attributeNodes = declaration.DeclarationType.HasFlag(DeclarationType.Module)
82-
? declaration.Attributes.AttributeNodesFor(annotation)
83-
: declaration.Attributes.AttributeNodesFor(annotation, declaration.IdentifierName);
92+
? declaration.Attributes.AttributeNodesFor(annotationInstance)
93+
: declaration.Attributes.AttributeNodesFor(annotationInstance, declaration.IdentifierName);
8494

8595
foreach (var attributeNode in attributeNodes)
8696
{
8797
var values = attributeNode.Values;
88-
if (!annotation.AttributeValues.SequenceEqual(values))
98+
if (!annotation.AttributeValues(annotationInstance).SequenceEqual(values))
8999
{
90100
attributeValues = values;
91101
return true;

Rubberduck.CodeAnalysis/Inspections/Concrete/DuplicatedAnnotationInspection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
4646
foreach (var declaration in State.AllUserDeclarations)
4747
{
4848
var duplicateAnnotations = declaration.Annotations
49-
.GroupBy(annotation => annotation.AnnotationType)
50-
.Where(group => !group.First().AllowMultiple && group.Count() > 1);
49+
.GroupBy(pta => pta.Annotation)
50+
.Where(group => !group.First().Annotation.AllowMultiple && group.Count() > 1);
5151

5252
issues.AddRange(duplicateAnnotations.Select(duplicate =>
5353
{
5454
var result = new DeclarationInspectionResult(
5555
this, string.Format(InspectionResults.DuplicatedAnnotationInspection, duplicate.Key.ToString()), declaration);
5656

57-
result.Properties.AnnotationType = duplicate.Key;
57+
result.Properties.Annotation = duplicate.Key;
5858
return result;
5959
}));
6060
}

Rubberduck.CodeAnalysis/Inspections/Concrete/IllegalAnnotationInspection.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
5252
var annotations = State.AllAnnotations;
5353

5454
var unboundAnnotations = UnboundAnnotations(annotations, userDeclarations, identifierReferences)
55-
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.GeneralAnnotation)
55+
.Where(annotation => !annotation.Annotation.Target.HasFlag(AnnotationTarget.General)
5656
|| annotation.AnnotatedLine == null);
5757
var attributeAnnotationsInDocuments = AttributeAnnotationsInDocuments(userDeclarations);
5858

@@ -65,7 +65,7 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
6565
new QualifiedContext(annotation.QualifiedSelection.QualifiedName, annotation.Context)));
6666
}
6767

68-
private static IEnumerable<IAnnotation> UnboundAnnotations(IEnumerable<IAnnotation> annotations, IEnumerable<Declaration> userDeclarations, IEnumerable<IdentifierReference> identifierReferences)
68+
private static IEnumerable<IParseTreeAnnotation> UnboundAnnotations(IEnumerable<IParseTreeAnnotation> annotations, IEnumerable<Declaration> userDeclarations, IEnumerable<IdentifierReference> identifierReferences)
6969
{
7070
var boundAnnotationsSelections = userDeclarations
7171
.SelectMany(declaration => declaration.Annotations)
@@ -76,11 +76,11 @@ private static IEnumerable<IAnnotation> UnboundAnnotations(IEnumerable<IAnnotati
7676
return annotations.Where(annotation => !boundAnnotationsSelections.Contains(annotation.QualifiedSelection)).ToList();
7777
}
7878

79-
private static IEnumerable<IAnnotation> AttributeAnnotationsInDocuments(IEnumerable<Declaration> userDeclarations)
79+
private static IEnumerable<IParseTreeAnnotation> AttributeAnnotationsInDocuments(IEnumerable<Declaration> userDeclarations)
8080
{
8181
var declarationsInDocuments = userDeclarations
8282
.Where(declaration => declaration.QualifiedModuleName.ComponentType == ComponentType.Document);
83-
return declarationsInDocuments.SelectMany(doc => doc.Annotations).OfType<IAttributeAnnotation>();
83+
return declarationsInDocuments.SelectMany(doc => doc.Annotations).Where(pta => pta.Annotation is IAttributeAnnotation);
8484
}
8585
}
8686
}

Rubberduck.CodeAnalysis/Inspections/Concrete/MissingAnnotationArgumentInspection.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ public MissingAnnotationArgumentInspection(RubberduckParserState state)
4848

4949
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
5050
{
51+
// FIXME don't actually use listeners here, iterate the Annotations instead
52+
// FIXME don't maintain a separate list for annotations that require arguments, instead use AnnotationAttribute to store that information
5153
return (from result in Listener.Contexts
5254
let context = (VBAParser.AnnotationContext)result.Context
53-
where context.annotationName().GetText() == AnnotationType.Ignore.ToString()
54-
|| context.annotationName().GetText() == AnnotationType.Folder.ToString()
55+
where context.annotationName().GetText() == "Ignore"
56+
|| context.annotationName().GetText() == "Folder"
5557
where context.annotationArgList() == null
5658
select new QualifiedContextInspectionResult(this,
5759
string.Format(InspectionResults.MissingAnnotationArgumentInspection,

Rubberduck.CodeAnalysis/Inspections/Concrete/MissingAttributeInspection.cs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,21 @@ public MissingAttributeInspection(RubberduckParserState state)
4848
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
4949
{
5050
var declarationsWithAttributeAnnotations = State.DeclarationFinder.AllUserDeclarations
51-
.Where(declaration => declaration.Annotations.Any(annotation => annotation.AnnotationType.HasFlag(AnnotationType.Attribute)));
51+
.Where(declaration => declaration.Annotations.Any(pta => pta.Annotation is IAttributeAnnotation));
5252
var results = new List<DeclarationInspectionResult>();
5353
foreach (var declaration in declarationsWithAttributeAnnotations.Where(decl => decl.QualifiedModuleName.ComponentType != ComponentType.Document
5454
&& !decl.IsIgnoringInspectionResultFor(AnnotationName)))
5555
{
56-
foreach(var annotation in declaration.Annotations.OfType<IAttributeAnnotation>())
56+
foreach (var annotationInstance in declaration.Annotations.Where(pta => pta.Annotation is IAttributeAnnotation))
5757
{
58-
if (MissesCorrespondingAttribute(declaration, annotation))
58+
var annotation = (IAttributeAnnotation)annotationInstance.Annotation;
59+
if (MissesCorrespondingAttribute(declaration, annotationInstance))
5960
{
60-
var description = string.Format(InspectionResults.MissingAttributeInspection, declaration.IdentifierName,
61-
annotation.AnnotationType.ToString());
61+
var description = string.Format(InspectionResults.MissingAttributeInspection, declaration.IdentifierName, annotation.Name);
6262

6363
var result = new DeclarationInspectionResult(this, description, declaration,
64-
new QualifiedContext(declaration.QualifiedModuleName, annotation.Context));
65-
result.Properties.Annotation = annotation;
64+
new QualifiedContext(declaration.QualifiedModuleName, annotationInstance.Context));
65+
result.Properties.Annotation = annotationInstance;
6666

6767
results.Add(result);
6868
}
@@ -72,15 +72,20 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
7272
return results;
7373
}
7474

75-
private static bool MissesCorrespondingAttribute(Declaration declaration, IAttributeAnnotation annotation)
75+
private static bool MissesCorrespondingAttribute(Declaration declaration, IParseTreeAnnotation annotationInstance)
7676
{
77-
if (string.IsNullOrEmpty(annotation.Attribute))
77+
if (!(annotationInstance.Annotation is IAttributeAnnotation annotation))
78+
{
79+
return false;
80+
}
81+
var attribute = annotation.Attribute(annotationInstance);
82+
if (string.IsNullOrEmpty(attribute))
7883
{
7984
return false;
8085
}
8186
return declaration.DeclarationType.HasFlag(DeclarationType.Module)
82-
? !declaration.Attributes.HasAttributeFor(annotation)
83-
: !declaration.Attributes.HasAttributeFor(annotation, declaration.IdentifierName);
87+
? !declaration.Attributes.HasAttributeFor(annotationInstance)
88+
: !declaration.Attributes.HasAttributeFor(annotationInstance, declaration.IdentifierName);
8489
}
8590
}
8691
}

Rubberduck.CodeAnalysis/Inspections/Concrete/MissingMemberAnnotationInspection.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,16 +88,18 @@ private static bool MissesCorrespondingMemberAnnotation(Declaration declaration,
8888
}
8989

9090
var attributeBaseName = AttributeBaseName(declaration, attribute);
91-
92-
//VB_Ext_Key attributes are special in that identity also depends on the first value, the key.
91+
// VB_Ext_Key attributes are special in that identity also depends on the first value, the key.
9392
if (attributeBaseName == "VB_Ext_Key")
9493
{
95-
return !declaration.Annotations.OfType<IAttributeAnnotation>()
96-
.Any(annotation => annotation.Attribute.Equals("VB_Ext_Key") && attribute.Values[0].Equals(annotation.AttributeValues[0]));
94+
return !declaration.Annotations.Where(pta => pta.Annotation is IAttributeAnnotation)
95+
.Any(pta => {
96+
var annotation = (IAttributeAnnotation)pta.Annotation;
97+
return annotation.Attribute(pta).Equals("VB_Ext_Key") && attribute.Values[0].Equals(annotation.AttributeValues(pta)[0]);
98+
});
9799
}
98100

99-
return !declaration.Annotations.OfType<IAttributeAnnotation>()
100-
.Any(annotation => annotation.Attribute.Equals(attributeBaseName));
101+
return !declaration.Annotations.Where(pta => pta.Annotation is IAttributeAnnotation)
102+
.Any(pta => ((IAttributeAnnotation)pta.Annotation).Attribute(pta).Equals(attributeBaseName));
101103
}
102104

103105
private static string AttributeBaseName(Declaration declaration, AttributeNode attribute)

Rubberduck.CodeAnalysis/Inspections/Concrete/MissingModuleAnnotationInspection.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,18 @@ private static bool MissesCorrespondingModuleAnnotation(Declaration declaration,
9393
{
9494
return false;
9595
}
96-
9796
//VB_Ext_Key attributes are special in that identity also depends on the first value, the key.
9897
if (attribute.Name == "VB_Ext_Key")
9998
{
100-
return !declaration.Annotations.OfType<IAttributeAnnotation>()
101-
.Any(annotation => annotation.Attribute.Equals("VB_Ext_Key") && attribute.Values[0].Equals(annotation.AttributeValues[0]));
99+
return !declaration.Annotations.Where(pta => pta.Annotation is IAttributeAnnotation)
100+
.Any(pta => {
101+
var annotation = (IAttributeAnnotation)pta.Annotation;
102+
return annotation.Attribute(pta).Equals("VB_Ext_Key") && attribute.Values[0].Equals(annotation.AttributeValues(pta)[0]);
103+
});
102104
}
103105

104-
return !declaration.Annotations.OfType<IAttributeAnnotation>()
105-
.Any(annotation => annotation.Attribute.Equals(attribute.Name));
106+
return !declaration.Annotations.Where(pta => pta.Annotation is IAttributeAnnotation)
107+
.Any(pta => ((IAttributeAnnotation)pta.Annotation).Attribute(pta).Equals(attribute.Name));
106108
}
107109
}
108110
}

Rubberduck.CodeAnalysis/Inspections/Concrete/ModuleWithoutFolderInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public ModuleWithoutFolderInspection(RubberduckParserState state)
3939
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
4040
{
4141
var modulesWithoutFolderAnnotation = State.DeclarationFinder.UserDeclarations(Parsing.Symbols.DeclarationType.Module)
42-
.Where(w => w.Annotations.All(a => a.AnnotationType != AnnotationType.Folder))
42+
.Where(w => !w.Annotations.Any(pta => pta.Annotation is FolderAnnotation))
4343
.ToList();
4444

4545
return modulesWithoutFolderAnnotation

Rubberduck.CodeAnalysis/Inspections/Concrete/ObsoleteMemberUsageInspection.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
5858
{
5959
var declarations = State.AllUserDeclarations
6060
.Where(declaration => declaration.DeclarationType.HasFlag(DeclarationType.Member) &&
61-
declaration.Annotations.Any(annotation =>annotation.AnnotationType == AnnotationType.Obsolete));
61+
declaration.Annotations.Any(pta => pta.Annotation is ObsoleteAnnotation));
6262

6363
var issues = new List<IdentifierReferenceInspectionResult>();
6464

6565
foreach (var declaration in declarations)
6666
{
67-
var replacementDocumentation =
68-
((ObsoleteAnnotation) declaration.Annotations.First(annotation =>
69-
annotation.AnnotationType == AnnotationType.Obsolete)).ReplacementDocumentation;
67+
var replacementDocumentation = declaration.Annotations
68+
.First(pta => pta.Annotation is ObsoleteAnnotation)
69+
.AnnotationArguments
70+
.FirstOrDefault() ?? string.Empty;
7071

7172
issues.AddRange(declaration.References.Select(reference =>
7273
new IdentifierReferenceInspectionResult(this,

0 commit comments

Comments
 (0)