« first day (1831 days earlier)      last day (1349 days later) » 
00:00 - 17:0018:00 - 00:00

12:01 AM
RELOAD!
[rubberduck-vba/Rubberduck] 2 opened issues. 13 issue comments.
[Zomis/xploria-perms] 1 commit. 51 additions. 9 deletions.
[Minesweeper] Games Played: 139, Bombs Used: 100, Moves Performed: 19057, New Users: 16
 
12:59 AM
        private Declaration SupertypeForDocument(QualifiedModuleName module, RubberduckParserState state)
        {
            if(module.ComponentType != ComponentType.Document)
            {
                return null;
            }

            var component = _state.ProjectsProvider.Component(module);
            if (component == null || component.IsWrappingNullReference)
            {
                return null;
            }

            Declaration superType = null;
            // TODO: Replace with TypeLibAPI call, require a solution regarding thread synchronization or caching
guessing that's where the typelibs API stuff needs to go :)
 
@MathieuGuindon Not really - you want to read off the Com** objects from there
 
I do not think that the resolver should interact with the typelib API in any way.
 
at the end of the day we need the Workbook declaration in the Supertypes collection of the ThisWorkbook class, no?
 
Rather, the parser coordinator should cache all the Com** objects from TypeLib once, early in the process. That's what Max's PR did (though you need to enable the constant)
Oh, absolutely. Just indirectly. :)
 
1:12 AM
ok, got the constant. ...I don't want to go full-blown typelibs though... we don't want to do that before Wayne's PR is in...
 
maybe ping Wayne again.
I am hoping that I will have more time later this weekend to wrap up my stuff...
 
I'm seriously lost. not seeing how TypeLibWrapper is of any help for this.
I think whatever we cache from the typelibs api is going to live exactly as long as the corresponding DocumentModuleDeclaration
 
isn't that why you need to get ComProject first?
 
the method I ultimately need is in IVBETypeLibsAPI
..which is readily injected anywhere
 
but you're in resolver, no?
 
1:18 AM
I was. now I'm in UserProjectRepository, and lost
 
that can be run in several threads in parallel, no? You totally don't want to make typelib API access.
you want to get the cached ComProject instead.
 
but how does ComProject help me invoke IVBETypeLibsAPI.DetermineDocumentClassType?
oh. I still need IVBETypeLibsAPI ctor-injected there
and then I use the overload that takes an ITypeLibWrapper
 
you shouldn't invoke it from ComProject; it should already had that populated during its initialization
so the resolver simply just queries the ComProject's equivalent property and fill it in the Declaration
 
except it doesn't - the methods aren't used anywhere
wait what is "that"
 
that = the document class
e.g. DetermineDocumentClassType
that should be invoked as part of constructing the ComProject
 
1:23 AM
yeah, no that isn't invoked anywhere that I can see
 
(actually one of its children object)
that what should be happening because again, you really do not want to touch typelib once you're inside resolver
(more generally, anywhere within the TPL)
PTL? What was the acronym again... parallel task library?
 
TPL was right :)
 
whatever we use to parallelize the parsing.
Ok, "task parallel library" didn't make sense to me
 
ok the only place remotely near the needed functionality in ComProject is this:
    private void ApplySpecificLibraryTweaks()
    {
        if (!Name.ToUpper().Equals("EXCEL")) return;
        var application = _classes.SingleOrDefault(x => x.Guid.ToString().Equals("00024500-0000-0000-c000-000000000046"));
        var worksheetFunction = _interfaces.SingleOrDefault(i => i.Guid.ToString().Equals("00020845-0000-0000-c000-000000000046"));
        if (application != null && worksheetFunction != null)
        {
            application.AddInterface(worksheetFunction);
        }
    }
is that what's supposed to grab the document modules and AddInterface(workbook)/AddInterface(worksheet)??
 
that function feels like one big hack
 
1:26 AM
it is
in any case, telling RD ThisWorkbook is a Workbook is going to have to be a hack
 
i can't remember why ComIntern (?) had to do that
 
lol codelens says "0 authors", go figure
 
VS is funny sometimes
let me look at the code again, one sec
 
@this that's because Excel.Application doesn't implement WorksheetFunction... we just know that it does.
(I think)
 
yes i think that's right
I'm unsure how ThisWorkbook is represented
if it's a coclass, then we need to be tweaking the ComCoClass
otherwise, ComInterface
 
1:32 AM
I was going to completely bypass the COM stuff and handle that at Declaration level
 
using TypeLib API directly? And that means switching to UI thread in resolver.
 
I mean, we already have code to get the implemented COM interfaces
 
and besides, typelib API is COM
 
there's that
 
That's why you want to have a single point where you do all the COM stuff and do it quickly
then once you have it cached, you can parallelize all you want without worrying.
That's why I'd rather discover the document class inside ComCoClass? ComInterface?
and you already have the type lib so it's easy to ctor-inject the TypeLibWrapper in
 
1:39 AM
My current understanding is that I'm going to need both the TypeLibWrapperaprovider and the IVBETypeLibsAPI
 
at the ComProject level, you already have the ITypeLib
 
hmm. the provider doesn't take a ITypeLib
thinking that the ComProject might need a overloaded ctor that takes a IVbProject or something like that.
 
that doesn't feel right
 
why not? you get the ITypeLib from the IVbProject via the provider
 
1:47 AM
hm
 
Remember that ITypeLibWrapper can be cast into ITypeLib
I'd be looking at this for example
it does not use any special ctor for the ComProject but I am wondering that this might be necessary to signal to the ComProject that it's a VBA project and therefore, it needs to do additional querying from the TypeLib API to fill in the extra data.
we wouldn't want it to try and invoke TypeLib API on a non-VBA project ComProject.
 
ok, found where user com projects end up in the parser state
        private void LoadProjects(IEnumerable<string> projectIds)
        {
            foreach (var projectId in projectIds)
            {
                var comProject = _userComProjectProvider.UserProject(projectId);
                if (comProject == null)
                {
                    continue;
                }

                var declarations = _declarationsFromComProjectLoader.LoadDeclarations(comProject, projectId);
                foreach (var declaration in declarations)
                {
 
That's the cache, yeah
 
2:06 AM
thing is, I wasn't going to get the user COM project loading flipped on for this
that's lighting up a massive rabbit hole of an execution path right there.
 
I don't blame you. I just don't see how you can safely access TypeLib API inside resolver.
sicne you would have to switch to the UI thread
and then you have to go digging in the type lib to locate the class?interface? then determine if it's a document or not.
 
insert a "temporary" step before the resolver
oh damn
oh damn I'm .. oh damn
 
ok, but you'll still have to cycle through the entire type library
to find that class and thus know that it's the same thing and
which seems like redundant since the user com project would already have that information
 
yeah, just got the lightbulb moment about where in the process the declaration finder is able to find anything lol
 
goes to show how big the duck's underbelly is now, eh?
 
2:11 AM
yeah
 
sometime I think the duck screams for a good viz of the codebase's flow, if at least at the high level
 
hm, LoadProjects doesn't hit at all
@this YES
hm, TryLoadProject succeeds and I have a ComProject
...with no members
Exception thrown: 'System.IO.DirectoryNotFoundException' in Rubberduck.VBEditor.VBA.dll
now that's an interesting one
ok that's the unsaved project throwing
 
2:31 AM
need to guard against that, I guess.
 
it's all in TryXxxx methods, the exception wasn't unhandled, just output
nice, seeing the typeinfos for ThisWorkbook and Sheet1
ha, guess what the TYPEKIND is
TKIND_VBACLASS
the one that's //todo
in LoadModule
the good news is that it has no chance of interfering with COM libraries
so I need to make a ComVbaClass?
I think I can work with this
don't ask me how I'm going to test any of it, but I think I can work with this
 
reminder - in Wayne's PR, he intends to do away with TKIND_VBACLASS
(at least for the external consumers' purposes)
 
i think he wants to use .... `TKIND_DISPATCH?
> TKIND_VBACLASS now gets exposed as TKIND_DISPATCH, the most suitable match which supports both functions and fields in the same type infos.
 
2:39 AM
that is because the TKIND_VBACLASS is meaningless ot external consumers and they see it as TKIND_MAX which is technically an error
 
makes sense
 
so in order to make the VBA typelib/typeinfo compatible for external consumers (e.g. mocking framework), we have to play by the documentation
 
so... I'm stuck? or I write tech debt?
I'm good at tech debt
2
 
lol
I think tech debt is fine
it shoudl be small enough payment
famous last words
 
2:41 AM
just stick in a TODO
 
def
hm, the KnownTypes.TryGetValue call is superfluous for VBProject types
 
where's that called
 
ComProject.LoadModules
oh wait, nevermind
that's the cache facepalm
ok, so handle TKIND_VBACLASS and add it to KnownTypes. the lookup is redundant for TKIND_ALIAS though
[StructLayout(LayoutKind.Sequential)]
struct VBETypeLibObj
{
    IntPtr _vTable1;     // ITypeLib vtable
    IntPtr _vTable2;
    IntPtr _vTable3;
    public IntPtr Prev;
    public IntPtr Next;
}
there's things in that PR that make you go waaaah
 
2:58 AM
need to be comfortable with C/C++ to follow that.
it's basically pointer arithmetic without the unsafety of unsafe.
 
so uh, just copying the TKIND_INTERFACE stub over to TKIND_VBACLASS looks like it sees ThisWorkbook implements _Workbook
 
Cool.
that's tangential but I think you also need to copy... module stuff?
 
trick question..
I don't think so
    public ComModule(IComBase parent, ITypeLib typeLib, ITypeInfo info, TYPEATTR attrib, int index) : base(parent, typeLib, attrib, index)
    {
        Debug.Assert(attrib.cFuncs >= 0 && attrib.cVars >= 0);
        Type = DeclarationType.ProceduralModule;
        public ComInterface(IComBase parent, ITypeLib typeLib, ITypeInfo info, TYPEATTR attrib, int index) : base(parent, typeLib, attrib, index)
        {
            Type = DeclarationType.ClassModule;
 
because a VBA class can have both functions and fields
not referring to the declartion type but rather gathering all the fields and functions
 
sure but we don't want Type = DeclarationType.ProceduralModule
 
3:03 AM
Agreed.
note that in module we have Debug.Assert(attrib.cFuncs >= 0 && attrib.cVars >= 0)
VBA class modules violates that (and we removed a similar assert in the ComInterface as welll)
but I think just interfaces is fine. we can fill in the fields later if we need it.
 
it sure is fine as far as knowing that Sheet1 is a Worksheet that has Worksheet members
which is already a huge win
 
and have someone else who groks type lib is a win, too. ;-)
 
I'm well beyond completely overdue for a dip in that area of the code base
thinking I might need CoClass as well
...I think I'm starting to understand what TKIND_UNION might mean
(but not really)
feels like we'd want some kind of "aggregate" type for this
 
it says it's not supported in VBA, though....
 
3:15 AM
do you have an example of an union?
 
also, I'm starting to doubt we can cache the VBA types
 
why?
 
add a method, the cache needs to be invalidated
 
that's no different from having to reparse
when you reparse, the cache will be updated, no?
 
yeah, think so.
 
3:17 AM
and we can just use the same logic we currently use w/ determining if reparsing is needed
except that in the case of com projects, it'll be at project level (add member anywhere, the whole project needs to be refreshed)
 
hence why knee-jerk was "well then we don't need any caching"
 
AIUI, the extraction from typelib is very fast. ComIntern said it only takes milliseconds if that. However when it has to be on the UI thread....
Goodbye, TPL. Was nice knowing ya!
 
curious about these then:
    public static readonly ConcurrentDictionary<Guid, ComType> KnownTypes = new ConcurrentDictionary<Guid, ComType>();
    public static readonly ConcurrentDictionary<Guid, ComEnumeration> KnownEnumerations = new ConcurrentDictionary<Guid, ComEnumeration>();
    public static readonly ConcurrentDictionary<Guid, ComAlias> KnownAliases = new ConcurrentDictionary<Guid, ComAlias>();
also, this "unlikely" feels much less certain if user projects are involved:
    //Note - Enums and Types should enumerate *last*. That will prevent a duplicate module in the unlikely(?)
    //instance where the TypeLib defines a module named "Enums" or "Types".
oh, it crashed
NotImplementedException
...and "NotImplementedException" is nowhere to be found in Rubberduck.VBEditor.VBA... wth
 
4:04 AM
bleh. calling it a night.
 
4:24 AM
Night mug.
 
 
1 hour later…
5:46 AM
Iven-self-reminder: Make your open PR a priority to complete.
 
6:13 AM
@MathieuGuindon The cache invalidation is already implemented.
And regarding how the ComProject uses the type lib api, it doesn't. It used the type lib wrapper directly, like any other type lib.
This will get you the information that ThisWorkbook is a Workbook because it implements that interface.
 
7:07 AM
> Okay. I understand you all. The //todo would definitely resolve this thing. Will wait for the future. :-)
Is there any way to, as @daFreeMan mentioned, disable SCP for debug.print line?
Or to disable "some types of autocomplete"? If I'm not mistaken (maybe I am :-)), in the past, there were more options in Autocomplete Settings.
 
 
3 hours later…
10:34 AM
Hi folks.
Is this wanted? If I write
Debug.Print "Hi there|" and press enter, it will transform into
Debug.Print "Hi there" & _
            "|"
I don't think this is a bug. Just reassuring.
 
that's "smart concatenation"...
If you don't want it, you can turn it off :)
 
11:04 AM
@MathieuGuindon I would support this!
@SonGokussj4 You also get the smart concatenation if you have Debug.Print "Hi there| and hit <enter> (note the lack of trailing " vs your example).
I haven't written enough strings lately to really get used to it, but I'm looking forward to doing so! :)
 
11:33 AM
@SonGokussj4 you can configure the maximum number of line continuations it can do (default is 2 IIRC)
and if you hit backspace it takes you right where you expect to be =)
 
@M.Doerner yeah, saw that, and it works. The part I'm stuck at is getting it to collect not just the public interface, but also any fields and even more importantly, events. I'll give it another shot tonight. And then it's a matter of combining these with the parser-obtained declarations. Or does that "just work"?
 
@Duga Actually that presumes we can cleanly separate between the obvious cases and not-so obvious cases. IDK if that is reasonable/feasible.
@MathieuGuindon If you're going to collect everything there is to know about it, you probably need more than a copy'n'paste of the TKIND_INTERFACE case.
 
Yeah... but then that'll break when we get a TKIND_DISPATCH instead of a VBACLASS
 
do we handle it already?
(dispatch)
 
11:56 AM
it's the same case as interface
so, yeah
 
hmm. I think the ComInterface will only have methods collected but not fields.
 
kinda =)
 
no, i'm wrong. it does collect both, so that's good
 
@this yeah. I'll dig into the code providing the TKIND value to see whether there's another way to tell we're looking at a VBACLASS
@this still need the events
and IIUC these would be subclasses of the Workbook coclasd
bad wording. Not subclasses
 
@MathieuGuindon for reference - that should be doable since he says it's available already. We just can't see the Implements'd interfaces, but I think we aren't there yet so.
 
12:08 PM
Yeah no at this point I really only care about making ThisWorkbook:Workbook and Sheet1:Worksheet a thing in RD (and whatever perks come with that)
looks like it might fix the userform controls too
 
yeah
it should fix any host's evented document, really.
not just Excel. ;-)
 
12:38 PM
@MathieuGuindon U'r right :-D That's kind of awesome.
@Vogel612 Ah I see. I was thinking what is it... Within the settings :-) Thanks.
Too shame that I can't turn off the smart concatenation but have the CTRL+ENTER there for NewLines :-)
Anyway, I think this is almost certainly bug:
Have Smart Concatenation turned off.
Debug.Print "Hi there|"
hit ENTER
Debug.Print "Hi there"
|"
 
not sure that's smart concat bug. I think that's just VBIDE.
 
I know what is happening there. The original " is on the new line, the "Pair Completions" completes the "Hi there" text. But I don't suppose it's wanted?
 
I think that even if SCP was off, you'd still get the same behavior
 
@this Okay. You're right. My bad
I turned everything off and it's still doing the same thing. Sorry.
 
No worries, good to double check!
 
1:17 PM
@MathieuGuindon We create declaration out of ComProjects only for locked prejects and projects we ignore in the remaining process (currently none).
You will have to figure out the base class from the ComProject.
 
I guess that mean we still have to implement some logic to merge the data from Com*** objects into the declarations for parsed projects.
 
Yes
 
I'm inclined to think that it might be easiest to generate all the declarations from the Com** initially and have the resolver fill it out later.
well, maybe not easiest but cleanest
 
However, that can happen in the resolver since there is no interaction with the environment.
That would mean that we loose all data from the parse tree.
No line numbers, no constants, no accessibility.
No enums, no line labels
 
Do you mean when we run a reparse?
 
1:22 PM
The COM project as it is does not see all declarations.
 
Right, hence the need to somehow merge the declarations that we derive from Com** with additional metadata from the resolver for the given declaration, no?
 
Oh, you mean the declarations resolver.
 
Yes
 
Rewriting that might be painful.
 
I know that getting the declarations from Com** is quite fast, so that would be a big gain
 
1:26 PM
Moreover, I would prefer stuff not to change state too often.
 
e.g. that would enable CE to load quickly without a full resolution.
and then we can fill out all the metadata in background. I think that might make a big difference.
 
There would be no performance gain. We still need to completely process the parse trees in order to attach everything.
And then we have to match it to the existing declarations.
 
Hmm. I expected that once we have ComProject, we already have all the modules and methods for CE to display; no need to go through the parsing.
 
We need the positions in source code.
Most commands will not work without the parse tree information.
 
ah yes, that's true.
 
1:32 PM
On another note, how would you run our unit tests?
 
from RubberduckTests project?
 
1:46 PM
@this Last chance to find a bug today :-)
Set this.cell = GetCellFromTag(this|)
Press ., this will (because I'm in a Class) open a autocomplete dropdown menu
So now:
Set this.cell = GetCellFromTag(this.|)
Press )
Set this.cell = GetCellFromTag(this.)|)
I would expect this to go to: Set this.cell = GetCellFromTag(this.)|
 
while that's funky, but the (this.) isn't a legal syntax?
 
But maybe it's another VBE IDE thingie. I recognize that this does not happen often.
Yes it is. :-)
 
TBH, I'm not sure you can expect sane behavior from autocompletion for illegal syntax
 
And without SCP activated it does the same thing and I'm not sure why I didn't bother to try that before I wrote this... :-D
 
That is no different from VS; put in nonsense and you get nonsense formatting (which is also annoying since you have to undo the nonsensical formatting due to fat fingering)
wait, what?
 
1:51 PM
It's late. Too much coffee. Going home.
 
I don't expect vanilla VBIDE to even autocomplete ().
 
(this.|) --> (this.)|) without autocomplete too.
I've been working in VBA for the last past 2 days all day so I noticed some quirks and I wasn't sure what's original and what's Duckie :-)
 
In my SSIS ForEach Loop I have it truncate a table, then call the data flow to load the CSV to the temp table. That load step is failing (reasons yet undetermined - nope just figured it out!), updating the Result variable and updating my load table.
^all as expected.
However, it is not continuing to loop through the rest of the records in the result set that it should be processing.
Do I need to adjust the MaximumErrorCount property for the ForEach to allow it to continue? I wouldn't think so, because it's not really erroring there - the error is in the data flow and that seems to be returning and execution continues, it's just not looping.
Without the erroring files, it does run to completion as expected.
 
@this it's not completing anything.. (thing.|) -> ) -> (thing.)|) is plain vanilla
 
the heck is up with |?
that does something?
 
2:05 PM
represents the caret position
 
ahhhhh, ok that makes 1000% more sense
 
@FreeMan the maximum error count isn't the one you want if you want to basically keep processing
I think you need to have an error handler for your foreach that basically says to continue on iterating (and maybe move the bad file to some folder for you to research later)
the error handler also should log all the error data, so you know why it's there in first place, too.
there should be plenty of info from various SSIS blogs
@MathieuGuindon Ok. I was surprised that it'd do that there - it's not particularly smart with autocompleting the parentheses.
(it being the vanilla VBIDE)
 
...it's not completing anything whatsoever
it's inserting a closing parens where the caret is... when you type the closing parens
 
oh you're right. I'm an idiot
I'd say it's Monday but it's not.... so....yeah, your plain old fashioned village idiot right here.
wanders off aimlessly to drool
 
on a similar note, my sister gave me a GoT t-shirt for my birthday... says "SHAME SHAME SHAME" ...wonder if there's a hidden message...
she said they were out of "I drink and I know things" t-shirts
 
2:15 PM
lol
 
@KySoto internally, AC/SCP uses a CodeString class to encapsulate a logical line of code and the caret position; then there's a TestCodeString that extends it and is able to work with | literally representing the caret position in the code - which is great for the unit tests.
e.g.:
        [Test]
        public void PlacesCaretBetweenOpeningAndClosingChars_PreservesPosition()
        {
            var pair = new SelfClosingPair('(', ')');
            var input = pair.OpeningChar;
            var original = "foo = |".ToCodeString();
            var expected = "foo = (|)".ToCodeString();

            Assert.IsTrue(Run(pair, original, input, out var result));
            Assert.AreEqual(expected, result);
        }
@KySoto also, you may or may not know about this SCP feature yet:
        [Test]
        public void DeletingOpeningCharRemovesPairedClosingChar_Parens()
        {
            var pair = new SelfClosingPair('(', ')');
            var input = Keys.Back;
            var original = @"foo = (|2 + 2)".ToCodeString();
            var expected = @"foo = |2 + 2".ToCodeString();

            Assert.IsTrue(Run(pair, original, input, out var result));
            Assert.AreEqual(expected, result);
        }
assuming legal code, it should work with nested parentheses, and line-continuated expressions too
(a lightweight parser is getting involved for this)
 
2:41 PM
@this thanks. Found this that suggests a combination of MaximumErrorCount = 0 and setting ForceExecutionResult = Success. That gets me a clean run.
I've got a table that I'm looping to determine what needs to be processed. It's also got some columns capturing results, including what step (if any failed). At the moment, at least, that's going to be my best shot at figuring out what went wrong, so I'm not really worried about handling errors w/in SSIS.
I'll report based on the table so I'll know if something failed, and the result column will tell me where it failed, so I'll start sleuthing from there.
 
Interesting. I don't remember having to set the MaximumErrorCount but then again, my memory isn't exactly most reliable.
wait.
You're forcing execution result
that does not feel right.
 
I haven't gotten into the details of the 2nd half of that article yet. I need to get this sucker working so I can get data loaded & reports run for last month.
I'll be more elegant in a bit
#FunctionalThenRightThenFast
 
Gotcha. Yes, the 2nd half is more closer to what I did
such is life.
 
cool. will def come back to it
 
what i hate the most is that often when they're all "hurry and release that shitty crappy code right YESTERDAY!", then when it's over, they're all "meh, don't bother fixing. It's fine as it is."
That drives me insane.
 
2:55 PM
Now I've got to tweak what was a perfectly good package to handle 3 nearly identical input types. Not sure if I want to try to load format 1, if failure, try format 2, if failure try format 3; put a flag in my driver file identifying which format; rely on file name differences to identify; build a whole new package to handle each of the other types...
Probably just a flag in the driver file would make the most sense.
 
3:07 PM
@MathieuGuindon not going to lie, i looked at what you were talking about, and i was not entirely sure what was going on.
 
SCP handles {BACKSPACE} keypresses by deleting matching parentheses
so foo = (|2 + 2), hit backspace and you get foo = 2 + 2
or foo = ((|2 + 2) - 2) -> foo = (2 + 2 - 2)
i.e. you only need to backspace onto the opening parens, SCP finds and removes the matching closing parens
 
3:29 PM
hi @Justin
 
@MathieuGuindon - hi
 
what brings you to our little corner of the Internet? (welcome to "the pond"!)
 
@MathieuGuindon - Just wondering what VBA Rubberducking is :)
 
ha! excellent question! you know how badly the VBA code editor sucks?
we're fixing it :)
...in C#
^ that's our project, this chat is basically our "war room", @Duga the chatbot reports everything happening on the repo here
 
@MathieuGuindon - Ahhhh... That's great! Anyways, it feels a lot better knowing what VBA Rubberducking means. Thanks for helping me out there! I'll visit this chat often, seems interesting. For now, have a good day :)
 
3:38 PM
:+1:
 
4:05 PM
@Justin Welcome to the pond.
 
4:24 PM
@IvenBach - Glad to be here :)
 
If you have any question's were here to answer them.
 
00:00 - 17:0018:00 - 00:00

« first day (1831 days earlier)      last day (1349 days later) »