-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Redesign Annotation Processing #5107
Redesign Annotation Processing #5107
Conversation
This redesigns annotation processing to no longer rely on the AnnotationTypes enum to identify an annotation, allowing us to separate the scoping of an annotation from it's type. Additionally this explicitly stores metainformation on annotations in Attributes on the specific annotation type. This metainformation is used to automatically register annotations for the code pane parsing process. These changes have far-reaching implications for how annotations are used, most of them addressed in this commit. The parsing of annotations through the VBA API is not correctly dealt with.
This moves static information on annotations into implementations of IAnnotation and introduces a ParseTreeAnnotation class to correlate parser contexts to annotations. With that change we get a clearer separation between the annotation and it's use. For workability, a handful of extension methods have been added, some have been adapted. Additionally a large number of predicates and filterings have been adjusted to the new API.
c24e63e
to
5ac876e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all: good work!
I have looked at everything except the tests so far and I have to say that I like the new design, with a few exceptions:
- I do not really like extension methods for
ParseTreeAnnotation
. They hide the implementation away, but still provide the impression that all such annotations might have attributes. I would prefer, if the check whether the contained annotation is an attribute annotation remained a responsibility of the caller. - I am not really happy about constructor on
ParseTreeAnnotation
only for tests. As @bclothier mentioned, this can be avoided by extracting an interface and mocking that in the tests. - The IoC setup seems to be not in sync with the implementation. (Have you loaded the current version in some host?) With the new constructor setup, two simple conventions could replace the explicit reflection.
Rubberduck.CodeAnalysis/Inspections/Concrete/ObsoleteMemberUsageInspection.cs
Outdated
Show resolved
Hide resolved
Rubberduck.CodeAnalysis/Inspections/Concrete/DuplicatedAnnotationInspection.cs
Show resolved
Hide resolved
Rubberduck.CodeAnalysis/QuickFixes/RemoveDuplicatedAnnotationQuickFix.cs
Outdated
Show resolved
Hide resolved
{ | ||
public static class AttributeAnnotationExtensions | ||
{ | ||
public static string Attribute(this ParseTreeAnnotation annotationInstance) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not really like this extension method. For one, since there is only one ParseTreeAnnotation
, it might as well be right on the interface.
Moreover, with this extension method we say that every ParseTreeAnnotation
has an attribute, but it might be null
, instead of saying that you can get an attribute from the annotation, if it implements the correct interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, it feels dirty... Rewritten to be an extension of IAttributeAnnotation
Rubberduck.Parsing/Annotations/Implementations/FlexibleAttributeValueAnnotationBase.cs
Outdated
Show resolved
Hide resolved
Rubberduck.Parsing/VBA/ReferenceManagement/IdentifierReferenceResolver.cs
Outdated
Show resolved
Hide resolved
|
||
Assert.IsInstanceOf<MemberAttributeAnnotation>(inspectionResult.Properties.Annotation.Annotation); | ||
Assert.AreEqual("VB_UserMemId", inspectionResult.Properties.AttributeName); | ||
Assert.AreEqual("-4", ((ParseTreeAnnotation)inspectionResult.Properties.Annotation).AttributeValues()[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for this PR, would it make sense to add specific subtypes for the different inspection result types for those cases in which additional information needs to be transferred to the user of the result?
@@ -153,7 +156,9 @@ public void KnownMemberAttributeWithoutAnnotationWhileOtherAttributeWithAnnotati | |||
|
|||
protected override IQuickFix QuickFix(RubberduckParserState state) | |||
{ | |||
return new AddAttributeAnnotationQuickFix(new AnnotationUpdater(), new AttributeAnnotationProvider()); | |||
// FIXME actually inject the annotations here... | |||
return new AddAttributeAnnotationQuickFix(new AnnotationUpdater(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have this on its own line as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not quite sure what you mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually have the first argument also on a new line, IIRC.
This means an interface IParseTreeAnnotation has been extracted. Additionally the CW registration has been adjusted, multiple minor fixes and tweaks to usage sites have been done. IAnnotation now exposes a method to allow dealing with annotation arguments as they are added to the ParseTreeAnnotation itself. By default that just passes the arguments through.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM; I'm fine with merging them as-is.
711e3fc
to
4a7b243
Compare
I've split the current
IAnnotation
into anIAnnotation
for dealing with the static information and aParseTreeAnnotation
combining anIAnnotation
and the non-static information.This cleanly separates what kinds of annotations there are and what an annotation usage is. In addition this removes the special casing for the ExcelHotKeyAnnotation in the AnnotationAttributeProvider