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

Rubberduck scans after MS Access Export #4494

Open FuSoftware opened 5 years ago

FuSoftware commented 5 years ago

Everytime I perform an export (Module, Report, Form...) on MS Access 2016, after having opened VBA at least once (so, once RD has been initialized), everytime I export an object, the VBE seems to open/close all VB objects, and RD performs a full scan is if I had pressed the blue arrows.

This happens even when the VBA project cannot compile, and heavily increases RAM usage. Here, after 1 export (which produced 3-4 scans), I reached 738MB. Exporting now is either extremely slow, or crashes MS Access due to a "low memory" error.

The project contains approximately 100-150 objects in the VBE.

OS : Windows 10 64 bits MS Access 2016 Rubberduck 2.2.0.3762

MDoerner commented 5 years ago

Correct me if I am wrong, with export you mean an export into another Access database, right?

In my testing I could only reproduce a reparse for this specific export variant; export to text file or in the VBE itself does not trigger a reparse.

FuSoftware commented 5 years ago

When exporting to another Access Database it does trigger another reparse. I'm going to install the latest release and try again.

Edit: Reproduced on RD 2.2.0.4070 when exporting from an Access DB to another Access DB. It does not trigger with PDF, Text, RTF and HTML exports.

My guess is that the DB->DB export requires to open the inner VBA to generate whatever temporary data Access uses for that type of export, or the temporary opening of the second database somehow triggers the parsing, since both of these actions only happen on a DB->DB export

bclothier commented 5 years ago

AIUI, RD tries to make its best guess when it can automatically parse the project and does based on events from the VBProjects or VBComponents. In Excel, you will see it automatically parsing when you load a small or blank project. In Access, this almost never happens when you initially load the project. But you will see it automatically parsing when you load a 2nd database. The reason for that inconsistent behavior is due to the fact that when RD initializes, VBE isn't fully initialized so it can be difficult to accurately detect whether there's a project loaded and ready to parse. In fact, if you load a large enough Excel spreadsheet, you run in same problem as observed in Access.

That said, I just confirmed that the export (using Access UI) of an object with code will cause VBE to temporarily load a 2nd VB project and then unload it at end of export. That is what is triggering the automatic parse that we normally would see on the initial loading.

What we do need here is:

1) A user setting to indicate whether automatic parse on load is desired. 2) A conditional check on the status. If it's Pending, then don't attempt to parse.

Vogel612 commented 5 years ago

Is there any way to consistently tell what name the temporary project will have? If there is, we should probably also disable automatic parsing for that as well.

That name might be different between hosts, which suggests there should be a user-configurable list of projects rd should not parse, prefilled with known temporary names. That would also allow users to basically ignore external projects.

The drawback of that solution is obvious: we make the job of the resolver partly impossible. AIUI we can sidestep that with the TypeLibAPI though. Is that correct?

bclothier commented 5 years ago

I don't think there'll be a temporary name in this case. It's basically just loading the 2nd database as-is, so whatever name it has, it'll be that. In my test, it was Default but the file I never renamed that VBA project. Normally an Access VBA project gets the same name as the file as it was originally at the creation of the VB project. That complicates the analysis because that means if I create a file Foo.accdb, then create a code module, then later rename that file to Bar.accdb, then the VB project will be still named Foo. Therefore, if I did an export from Flub.accdb to Bar.accdb, we would see that a Foo VB project got loaded.

All things considered - there are differences in what we really want out of this feature:

1) automatic parsing when we load RD initially 2) automatic parsing whenever we add/remove a project 3) suppress parsing when quickly loading & unloading a project

For the 1) tie-in to the ProjectAdded is obviously inappropriate but that is the best thing besides some kind of timed delay. For the 2), it makes sense to tie into the events so no problems there. But for the 3) that means we need some timed delay on the 2) to ensure that parsing isn't triggered unnecessarily.

Obviously, this makes things a bit more complicated.

MDoerner commented 5 years ago

A few thoughts from my side:

  1. The list of projects to exclude is already in the planning pipeline for the typelib integration. (I have to get around to integrate loading the typelib into the parsing process.)
  2. If we make parsing on adding or removing a new project or component (RD probably triggers multiple parses in the scenario described above because the addition of the exported components also triggers a reparse.), then we should instead change the state to 'Pending` whenever such an event occurs. Otherwise, RD functionality was available although RD might be out of sync.
  3. As long as parsing on the addition of projects and components is enabled, we are at the mercy of the VBE whether an initial parse happens or not.