> There were talks of using xml-docs in the source code to generate the user documentation contents. I think that's the best way to do it. Needs quite a bit of work on the RD-Web repo then, and proper & complete xml-doc on all inspections, quickfixes, refactorings,... And basically all commands.
@M.Doerner / @Mat'sMug Until/unless we find a way to find the type of a document module, what do you think about an annotation like: '@Me: Workbook As Excel.Workbook? RD could then know what Me is, and that Workbook_Open is an event procedure, and usages of Name are references to `Workbook.Name'.
@ThunderFrame I don't understand. ?TypeName(Sheet1) and ?TypeName(ThisWorkbook) returns correct type. So what's stopping us exactly from assigning the correct type to the document module?
I'm working with the VBIDE API, and can't assume that the host application is Excel, or any Office app either.
So all I know is that I'm looking at a VBComponent, and that its Type is vbext_ct_document.
In the VBE's immediate pane I can get this output:
?TypeName(Application.VBE.ActiveVBProjec...
closest we came up with, IIRC, is: If VBProject.VBComponents("thisworkbook").Properties("Parent").Value("Name").Value = "Microsoft Excel" Then ProgID = "Excel.Workbook"
since predeclared has to be allocated, outside the VBA code, it's different.
If you try this with a UserForm or anything else that's predeclared, I suspect you'll see the same behavior.
I do have to admit, it's very weird to see the Is operator returning true even though the pointers don't agree. I always thought the Is operator was basically checking the pointer's value. Obviously it's doing a bit more than just that.
Regarding identifying document modules, the solution proposed in the SO answer is implemented hallways at the moment. The problem is that the way the COM collector currently exposes the CoClass we cannot identify the methods. Thus we are comparing the properties against the properties plus the methods, which cannot work.
If we could separate the methods, that might already do the trick for some document types. Unfortunately, I have no idea how the COM reflection part of the code base works.
@M.Doerner IKR, I looked at adding the legacy property types, and quickly got lost in a rabbit hole.
There's also the memory structures behind the Project Explorer's Treeview Item's UserData/lparam pointers. Those pointers give me 23 further pointers, which in turn lead to more pointers. And some of those pointers lead to things like a GUID for the project, and the offset into VBRuntime library. I'm hopeful that somewhere in the mix, I can find a GUID for the document modules, and maybe other useful stuff.
But it's hard reverse engineering all that, so I'm building a tool to assist.
And re parsing the FRM files, it seems the MSDN documentation only covers about 25% of the syntax that is actually possible.
@NelsonVides Currently, we are on Antlr 4.3, which cannot be built in VS2017. However, it can be built in VS2015, which cannot build the solution. So any grammar changes have to be done in VS2015 atm and then one has to switch back to VS2017 to actually build the solution.
Somehow, our grammar does not build correctly with version 4.6 of Sam Harwell's antlr version. So we will switch to the official version, which exists since 4.5.
We use C#7, which the VS2015 compiler does not understand.
No worries. just wanted to be sure I got it right, or if I could do better. One thing I do have to do is to see if I can come up with interfaces but I'm not at the point to define interaces so for now the For() and ImplementedBy() uses the same concrete types.
It does not really skip the tests, well except the about 50 ignored tests. They return in the state inconclusive because the actaul functionality could not be tested due to a parser error.
@this Since the implementing type in the first registration is not generic, it does makes sense. In the second, you can drop the IimplementedBy; without it it binds to itself. In the third one, I guess you wnat a transient auto-magic factory, because that is what you get with this registration.
Different question for anyone who can answer... I see that IRefactoring does not have a validation method, forcing the commands to answer the CanExecute. Does anyone else think it really should be the refactoring class's responsibility to determine if it can be executed or not? I'm in another passing-the-buck situation due to the need to share validation results to the refactoring.
Thanks Thunder. R# suggested Query syntax and I'm not familiar with LINQ to convert it to Method on my own. I'll do some reading and make the attempt later today.
The only reason to make it transient would be that you plan on disposing the factory after some work has been done in order to release all objects created by it.
Well, you can emulate a let with a select and an anonymous type.
huh, you can override the event object for Sheet1 and break the event handlers - once we work out what the event object is, we might need an inspection for that:
Private WithEvents Worksheet As StatusBar
Private Sub Worksheet_Change(ByVal Target As Range)
'Just a normal procedure, as statusbar doesn't have Change event
End Sub
return block != null && block.children != null && ContainsExecutableStatements(block); is suggested to replace with return block?.children != null && ContainsExecutableStatements(block); This may cause problems because of the short circuiting of block != null?
If the changed were to be done then ContainsExecutableStatements(block) could be supplied with a null? Is my understanding correct?
Also, I'm going to work on RD this vacation, but then I think I'll step back.
I've got other technologies I'd like to/need to learn, and they don't lend themselves to RD that well (unless you guys don't mind if I heavily extend the website).
And work's environment doesn't really lend itself to experimenting because my whole VS instance is tied up with TFS.
Even when I don't have any TFS repo open...
I suppose I could disconnect and reconnect, but I'd probably have to re-download the solution every time then, because it would forget the mapping...
as you might seen above, I'm trying to clean up the mess that was the old method and finding it's not very compatible with how we usually do with other refactoring.
for example, other refactorings don't have any validation -- most of their CanExecute implementation is simply a hard-coded true
but we have a validation process (which is working BTW)
but to make it complicated, it already has the metadata that is useful for the model
so I need to take the metadata to help popuplate the model
Right now, I'm doing this all "wrong" --- using public fields on the Refactoring class to get what I need
once I have a working process I will circle back and refactor it out
for the moment, i just need to get model correctly populated with all the metadata I have from the validation.
can someone please remind me the best way to get declarations out of a context or a selection? I'm looking at the DeclarationFinder but it doesn't seem to do what I need to get
sorry but where would one get Declarations from? I have the RubberDuckState which gives me a DeclarationFinder but not a Declarations, and AllUserDeclarations doesn't seem to have a References either?
FWIW, this is the expression i ended up, thanks to Vogel's help... var references = _state.AllDeclarations.SelectMany(d => d.References.Where(r => r.IsSelected(selection)));