rubberduck-vba / Rubberduck

Every programmer needs a rubberduck. COM add-in for the VBA & VB6 IDE (VBE).
https://rubberduckvba.com
GNU General Public License v3.0
1.91k stars 299 forks source link

Can we declare Attributes with rubber duck? #4134

Closed sancarn closed 6 years ago

sancarn commented 6 years ago

Can we declare attributes within the IDE similar to:

Attribute VB_Name = "Sheet1"

And if so, how?

I remember reading somewhere that this is one of the goals of rubberduck, but don't know if it has been implemented yet...

retailcoder commented 6 years ago

Rubberduck wouldn't have any problem parsing them, but the VBE wouldn't be able to compile it.

The idea was to leverage annotations (aka magic comments) to make otherwise invisible module & member attributes surface into the editor, for example:

'@PredeclaredId
Option Explicit

And then, when that module's attributes would be found to not have a corresponding VB_PredeclaredId = True attribute, Rubberduck would fire an inspection result and offer to "synchronize" attributes with annotations.

The feature was dropped (for now anyway) however, because - and this is still a major problem to this date - our module rewriters need to work off the code pane parse pass (for we need exact token positions as they appear in the code pane), but this required working off the attributes parse pass, which offsets all token positions. Basically when the quickfix "synchronized" the attributes/annotations, it worked, yeah.. but then the code pane rewriters would still drop the attributes, because they don't see them.

What we need, is a way to associate tokens from the "attributes pass" (the exported temp file) with tokens from the "code pane pass", make all module rewriters work off the "attributes pass" parse trees, and then figure out how to offset the positions so that when we GetSelection from the code pane, we can "translate" that into a position in the exported module - same for when we set the Selection on a module.

Until that's figured out, whenever we modify a module, that module loses its attributes.

One wild solution we're seriously considering, is to implement our own code panes (with all the perks that come with it - tear-tabs, code folding, custom themes, custom intellisense, brace matching, name it), and get the attributes themselves in there - so they'd be (optionally) visible, and when we "synchronize" our content with the VBE's code panes, we'd just take that content, dump it into a temp file, and import it into the VBE. And that would not only work, it would absolutely rock ...but it's a lot of work, and we're just not there yet.

retailcoder commented 6 years ago

Here is the blog article where I explain why attributes are a problem: https://rubberduckvba.wordpress.com/2017/12/18/about-attributes/

sancarn commented 6 years ago

One wild solution we're seriously considering, is to implement our own code panes (with all the perks that come with it - tear-tabs, code folding, custom themes, custom intellisense, brace matching, name it), and get the attributes themselves in there - so they'd be (optionally) visible, and when we "synchronize" our content with the VBE's code panes, we'd just take that content, dump it into a temp file, and import it into the VBE. And that would not only work, it would absolutely rock ...but it's a lot of work, and we're just not there yet.

Ironically this is exactly what I was thinking as you described the issue... xD These days, with all the open source libraries about, you could make some incredible improvements over the traditional VBE code panes, with little to no additional effort. The only complication would be namely integrating it into the rest of the code.

bclothier commented 6 years ago

@sancarn There are indeed many libraries -- we've been eyeing the AvalonEdit and one other for docking tabs (I can't remember the name off the cuff). The complicated thing wouldn't be integrating it into RD's codebase. The complicated thing will be making sure it works well w/ VBE which is very fussy host and also ensuring that we correctly maintain the VBA codebase.

We do need more contributors, though since this is a large project and we have so many things to do already. If you can, or know of anyone else, we'll appreciate any help we can get. :)

retailcoder commented 6 years ago

Yup. We're looking into AvalonEdit (which we already use for syntax-highlighted "preview" boxes in some dialogs) and Draggablz. But then, why stop there... once we have our own code panes, the inspection results toolwindow can die, and we can have ReSharper-like squiggles and pop-up dropdowns listing available quickfixes - and red squiggly lines for invalid syntax will require some serious tweaks to the parser (which currently bails out as soon as it encounters a parse error), for instance.

sancarn commented 6 years ago

I guess that makes a lot of sense given that this is a C# project you'd want to keep everything in C#. Personally I'd just use ace for the codepanes just because it's already a full IDE... But that's not efficient (or clean) of course... Just a dirty hack...

I had already considered forking the project to build support for VBA AST manipulation. But when I got to the source code I chickened out because I'm not particularly familiar with large codebases (being an engineer primarily i.e. dirty hacker). Even though I suspect that, as far as projects go, this is likely quite a "small" project...

retailcoder commented 6 years ago

@sancarn the project is somewhere around 220K lines of code, including ~40K generated by Antlr off the grammars. Everything parsing-related is located in the Rubberduck.Parsing project and its namespaces. Wrapping the Antlr parse trees was considered for a while, until we started using TokenStreamRewriter for editing the code (rather than using the VBIDE API and writing directly in the code modules.. that eliminated a TON of annoying string gymnastics) - now each module gets its rewriter, and we can make all the changes we need and rewrite all modified modules at once, which is nice because then we no longer clog up the undo stack. Anyway feel free to browse around (parsing process is explained in details in the wiki) and ask any questions about anything - dirty hackers welcome!

bclothier commented 6 years ago

Going to close the issue now that the question's been answered.