Skip to content
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

Merged

Conversation

Vogel612
Copy link
Member

@Vogel612 Vogel612 commented Aug 26, 2019

I've split the current IAnnotation into an IAnnotation for dealing with the static information and a ParseTreeAnnotation combining an IAnnotation 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

@Vogel612 Vogel612 marked this pull request as ready for review August 30, 2019 21:33
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.
@Vogel612 Vogel612 force-pushed the refactor/annotation-processing branch from c24e63e to 5ac876e Compare August 30, 2019 21:46
@Vogel612 Vogel612 requested a review from MDoerner August 30, 2019 22:02
Copy link
Contributor

@MDoerner MDoerner left a 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:

  1. 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.
  2. 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.
  3. 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.Main/Root/RubberduckIoCInstaller.cs Outdated Show resolved Hide resolved
{
public static class AttributeAnnotationExtensions
{
public static string Attribute(this ParseTreeAnnotation annotationInstance)
Copy link
Contributor

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.

Copy link
Member Author

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.Main/Root/RubberduckIoCInstaller.cs Outdated Show resolved Hide resolved
Rubberduck.UnitTesting/UnitTesting/TestMethod.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]);
Copy link
Contributor

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(),
Copy link
Contributor

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?

Copy link
Member Author

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?

Copy link
Contributor

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.

RubberduckTests/Grammar/AnnotationTests.cs Show resolved Hide resolved
RubberduckTests/Mocks/MockParser.cs Outdated Show resolved Hide resolved
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.
Copy link
Contributor

@bclothier bclothier left a 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.

@Vogel612 Vogel612 force-pushed the refactor/annotation-processing branch from 711e3fc to 4a7b243 Compare September 6, 2019 20:48
@retailcoder retailcoder merged commit 225b09b into rubberduck-vba:next Sep 7, 2019
@Vogel612 Vogel612 deleted the refactor/annotation-processing branch September 7, 2019 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants