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

Allow @Description and @ModuleDescription in Excel Workbook and Worksheet modules #5010

Closed
ChrisBrackett opened this issue Jun 14, 2019 · 10 comments
Assignees
Labels
difficulty-02-ducky Resolving these involves the internal API, but with relatively easy problems to solve. enhancement Feature requests, or enhancements to existing features. Ideas. Anything within the project's scope. feature-annotations up-for-grabs Use this label in conjunction with a difficulty level label, e.g. difficulty-02-ducky

Comments

@ChrisBrackett
Copy link

Justification
Most of the VBA I code is in locked down Excel Workbook projects designed to take user input and external data and output summary information, reports or files for import into another program. In this use, individual Excel Worksheets play unique rolls in the process that need to be documented.

Description
I would love to extend Rubberduck's indispensable @ModuleDescription and @Description annotations to include Workbook and Worksheet modules and event the overall Project (Excel or other MS Office file).

Worksheets themselves are often intended for specific purposes, such as data entry, syncing data from external sources or summary reporting and a back-end description and I think that documenting that along with the purpose of VBA in those Worksheets is just as helpful here as it is in code and class modules.

In addition to regular procedures, Worksheets can also have Event procedures that need to be documented (I currently document them using my pre-Rubberduck method as a comment inside the procedure). Here's an example description for a Workbook_AfterSave() event:

' DESCRIPTION: Recalculates the -FileNameError- named Range which compares the period in the file name to the period on the Worksheet.

Worksheets can have Form Controls that point to procedures on the sheet and ActiveX Controls with procedures directly linked to the procedure name such as Private Sub MyActiveXButton_Click().

@ProjectDescription annotations would also be useful – entered in the Workbook module and displayed when the project is selected in the Code Explorer.

@ChrisBrackett ChrisBrackett added the enhancement Feature requests, or enhancements to existing features. Ideas. Anything within the project's scope. label Jun 14, 2019
@retailcoder
Copy link
Member

The reason document modules can't have attribute annotations is because we can't export them, add the attributes, and re-import them back in.

Best we could do is let these modules have the annotation without treating it as illegal, and have the context/selection toolbar and Code Explorer use the annotations to display descriptions.

@ChrisBrackett
Copy link
Author

Wouldn't your suggested workaround work for description annotations in general? Do you prefer to store annotations as module attributes?

@retailcoder
Copy link
Member

Module/member VB_Description attributes show up in the Object Browser, so yeah whenever possible it's best to have them there.

@ChrisBrackett
Copy link
Author

Makes sense. Still, it would be nice to have all my descriptions in RD regardless of the mechanism.

@retailcoder
Copy link
Member

Looking at the RubberduckCommandBar code...

private void OnSelectionChange(object sender, DeclarationChangedEventArgs e)
{
var caption = _formatter.Format(e.Declaration, e.MultipleControlsSelected);
if (string.IsNullOrEmpty(caption))
{
//Fallback caption for selections in the Project window.
caption = e.FallbackCaption;
}
var refCount = e.Declaration?.References.Count() ?? 0;
var description = e.Declaration?.DescriptionString ?? string.Empty;
//& renders the next character as if it was an accelerator.
SetContextSelectionCaption(caption?.Replace("&", "&&"), refCount, description);
EvaluateCanExecute(_parser.State, e.Declaration);
}

...as well as the CodeExplorerItemViewModel code:

public virtual string Description => Declaration?.DescriptionString ?? string.Empty;

Looks like all we need to do is amend how the Declaration.DescriptionString is put together:

/// <summary>
/// Gets an attribute value that contains the docstring for a member.
/// </summary>
public string DescriptionString
{
get
{
string literalDescription;
var memberAttribute = _attributes.SingleOrDefault(a => a.Name == $"{IdentifierName}.VB_Description");
if (memberAttribute != null)
{
literalDescription = memberAttribute.Values.SingleOrDefault() ?? string.Empty;
return CorrectlyFormatedDescription(literalDescription);
}
var moduleAttribute = _attributes.SingleOrDefault(a => a.Name == "VB_Description");
if (moduleAttribute != null)
{
literalDescription = moduleAttribute.Values.SingleOrDefault() ?? string.Empty;
return CorrectlyFormatedDescription(literalDescription);
}
return string.Empty;
}
}

And that looks fairly easy: simply query the _annotations collection (.OfType<DescriptionAnnotation>() for member-level, .OfType<ModuleDescriptionAnnotation>() for module-level) when there's no description attribute, instead of returning an empty string.

@retailcoder retailcoder added difficulty-02-ducky Resolving these involves the internal API, but with relatively easy problems to solve. up-for-grabs Use this label in conjunction with a difficulty level label, e.g. difficulty-02-ducky labels Jun 14, 2019
@retailcoder
Copy link
Member

retailcoder commented Jun 14, 2019

A side-effect of this, is that annotated descriptions will start showing up in the Code Explorer and the context/selection toolbar even when there's no corresponding VB_Description attribute - for all module types, not just document modules.

@retailcoder
Copy link
Member

oh, I forgot a thing: the IllegalAnnotationInspection needs a little tweak here, to explicitly allow (i.e. exclude from this LINQ query) ModuleDescriptionAnnotation and DescriptionAnnotation (other annotations are still illegal in document modules):

private static IEnumerable<IAnnotation> AttributeAnnotationsInDocuments(IEnumerable<Declaration> userDeclarations)
{
var declarationsInDocuments = userDeclarations
.Where(declaration => declaration.QualifiedModuleName.ComponentType == ComponentType.Document);
return declarationsInDocuments.SelectMany(doc => doc.Annotations).OfType<IAttributeAnnotation>();
}

@IvenBach IvenBach self-assigned this Jun 15, 2019
@ChrisBrackett
Copy link
Author

A side-effect of this, is that annotated descriptions will start showing up in the Code Explorer and the context/selection toolbar even when there's no corresponding VB_Description attribute - for all module types, not just document modules.

To me that sounds more like a feature than a bug. Is there any reason this behavior would be undesirable?

@retailcoder
Copy link
Member

Not all side-effects are undesirable! 😃

@retailcoder
Copy link
Member

yep that's a worksheet document

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
difficulty-02-ducky Resolving these involves the internal API, but with relatively easy problems to solve. enhancement Feature requests, or enhancements to existing features. Ideas. Anything within the project's scope. feature-annotations up-for-grabs Use this label in conjunction with a difficulty level label, e.g. difficulty-02-ducky
Projects
None yet
Development

No branches or pull requests

3 participants