« first day (1007 days earlier)      last day (2173 days later) » 

00:01
RELOAD!
[Hosch250/CheckersUI] 2 commits. 72 additions. 58 deletions.
[retailcoder/Rubberduck] 14 commits. 1007 additions. 319 deletions.
[rubberduck-vba/Rubberduck] 12 commits. 6 opened issues. 5 closed issues. 18 issue comments. 869 additions. 271 deletions.
[VSDiagnostics/VSDiagnostics] 2 opened issues.
> Rubberduck.Setup.2.0.12.0.exe (5.86 MiB) - Downloaded 123 times.
Last updated on 2017-03-05
> Total Downloads 10,035
@Comintern I think Excel only tries to restart if it recognizes that it has crashed. If it hasn't crashed, and is instead only a ghostly husk, you still need to End Task it from WTM
@IvenBach That was on HackerNews yesterday
So I'm completely blind-siding it now?
@ThunderFrame That's pretty messed up, albeit there is humor there.
IKR - optional, but so is the measles vaccine
A friend applied for a role recently and got an offer. They asked for references and because they couldn't reach the referees (although voicemails were swapped), they decided to go with another candidate, without telling him until he called to ask about progress.
00:15
@ThunderFrame That couldn't have been the least bit awkward...
Trying to articulate my question properly.
When a class implements another class in VBA. If the class which is implemented is `Ishape` and it has `Public Function GetArea() as Double` and the class that implements it has both `Private Function Ishape_GetArea() as Double`(which is required by the `Implements` keyword) and `Private Function GetArea() as Double`. Why is the Ishape_GetArea method accessible even though in the concrete example it's private. Does this behavior occur because the class its implementing has it as `Public`?
@IvenBach the GetArea function isn't needed
IShape_GetArea is private as far as the concrete type is concerned
But it's public on the IShape interface
yep, the interface implementation is Private when the consumer uses the object as a Shape, but it's Public when the object is used as an IShape
If you made it public in the concrete class, then you could reach it from the interface AND from an instance of the concrete class, but the concrete method would be the full name including the interface prefix
and you don't want that
^
It's the same mechanism that makes events work btw
Event handlers are private
Yet external callers call them all the same
00:29
It's a bit more complicated than that.
but the concrete implementation of the interface method is able to call into the concrete class's explicit member.
Because they access the methods from the event provider's interface
eg. Private Function Ishape_GetArea() : Ishape_GetArea = Me.GetArea() : End Function
OK, HTH do I stop the unload process until the WM_DESTROY message gets through?
Extension unhooking VBENativeServices events.
Extension broadcasting shutdown.
DockableWindowHost removed event handler.
DockableWindowHost removed event handler.
DockableWindowHost removed event handler.
DockableWindowHost removed event handler.
DockableWindowHost removed event handler.
Extension calling App.Shutdown.
App calling Hooks.Detach.
Extension calling Kernel.Dispose.
Extension waiting for GC to complete.
Extension calling ReleaseDockableHosts.
DockableWindowHost dispose called.
DockableWindowHost dispose called.
dafuq
00:31
The DockableWindowHosts don't receive the kill message until after the addin unloads.
If I don't dispose them, it forces an Excel restart, and the VBE pops itself open. It's freaky.
Crazy thought: what if we ditched Ninject and went poor man's DI all the way?
It would be A) harder, B) easier.
Ninject causes so many problems, but doing it by hand has its own problems, and is more work.
Hmm, wouldn't change anything - DWH isn't even under Ninject handling
I already bypassed it completely. I'm grabbing a control reference in IWindows when the toolwindow is created.
@Hosch250 not sure what problems you're referring to
00:37
Disposal problems.
If I hold it there in a static, the kernel can dispose the DockableToolwindowPresenter, but the _DockableWindowHost doesn't get GC'd.
Just go look through the crazy config file to see them.
What, because you need to specify a scope???
Ninject was disposing it before - It calls Dispose on the presenter, which frees the last handle to the windowhost. I'm just holding a static reference open so that I can keep the message pump running.
00:40
@ThunderFrame I think I'm understanding it now. I've gone over stackoverflow.com/questions/19373081/… several times now aiming to understand something new each time. The mixing of Public and Private with Implements made it difficult to grasp till now.
The problem is that the VBE isn't sending the destroy message until after the addin finishes its unload.
Could we inject a WM_DESTROY message into the pump without wrecking things worse?
So... it's a catch-22. If I leave the message pump active, it forces Excel to restart. If I pull the message pump before the VBE send the WM_DESTROY, I leave a gap in the WndProc chain.
I still don't understand. Can you give me a hand-holding explanation?
I'm not used to seeing `:` in line this way.
@Mat'sMug I thought about that. Might need to send it to the VBE, asking it to destroy the window.
00:42
@IvenBach colon is an instruction separator token
Let me give that a shot.
Hey the worse that could happen is a BSOD right? ;-)
@Mat'sMug so instead of vbNewLine and seeing it on its own line you can mash them all onto one with :?
Where then does the Me. come from?
Me refers to the current instance of a class in VB
It's like this in C#
and is that why in several of your examples you have Private this as <Whatever>?
00:46
Sort of... My VBA this essentially stands for "the current instance's private fields"
An arguably better name would be internal or encapsulated... But this just has that nice ring to it
and since it means nothing special in VB...
Thanks again for the explanations. Heading home to see about getting VS to work.
01:29
@Comintern BSOD? ;-)
Nah, just some normal crashes.
Did you end up pulling my [next] branch?
I'm moving inspections to Rubberduck.Parsing tonight
Yeah, I'm currently even with next, + my teardown hacking.
Woot!
Just the move though - in next I got carried and went too far
^That's the site of the access violation.
01:38
@Comintern probably just happens to run first?
Note that the other 4 toolwindows all run 4 deep in children. The Test Explorer in that screener is being garbage collected.
Yeah, the order is pretty much random.
So the element host and the wrapper are gone at that point.
That leaves the just the DockableWindowHost.
It gets a sizing request, and has a null ActiveX child.
So....
I might need to extend the lifespan of the child controls.
02:08
For pull requests
Base fork (left): Repo to be updated
Head fork (right): Source to pull from (RubberDuck Main)
@Comintern IIUC, The ToolWindows host an ActiveX document, and in the case of RD, that ActiveX document is a WPF container. Is it possible to switch the ActiveX document of the ToolWindow to an innocuous ActiveX control (is innocuous ActiveX Control and Oxymoron???) and unload the WPH container before the ToolWindow is destroyed, so that when the ToolWindow is destroyed, it's only destroying the ActiveX control?
Or maybe we can make an intermediary ActiveX container that RD controls, that can add/remove the WPF container on demand?
ie. Tool Window --> WinForms ActiveX (that can itself host an ActiveX) --> WPF Container ActiveX -- WPF all the way down
02:12
lol
I got a +1 from @Mat'sMug and Duga says I'm doing it wrong. I'm not understanding something
flip it
[rubberduck-vba/Rubberduck] build for commit 5882d5e5 on unknown branch: AppVeyor build cancelled
:sigh:
give yourself a break, I think it took me a year to get it right every time
@ThunderFrame The _DockableWindowHost is the ActiveX container - it inherits from UserControl. The problem is that I think there's a bug in the implementation that makes the assumption that it has children. The WPF container itself is already 3 wrappers deep.
Right now I'm trying to see if there's anything I can override on its Accessibility interface.
...which is a PITA because we have 2 different Accessibility enumerations, and the MS one isn't wrapped in a MS namespace. Grrrrr....
02:15
huh?
@Duga #2824?
[rubberduck-vba/Rubberduck] build for commit 166f2e3f on master: AppVeyor build succeeded
@ThunderFrame - My thought was that if I can override UserControl.CreateAccessibilityInstance(), I can just create a dummy that "Yessir's" the ActiveX calls and responds with "Pay no attention to the Duck behind the curtain".
@Mat'sMug so did my last request succeed?
what was the number?
Merge pull request #2797 from rubberduck-vba/next #2823
02:22
nope
hrm
I can't seem to get the correct order down.
How do I get to that screen. What is the process of navigation, so that I learn it myself?
/IvenBach
"new pull request"
the default seems to be rubberduck-vba/Rubberduck/next as base
look at the commits underneath
02:27
I see those
they're not the commits you want in that PR
these are not the commits you're looking for
the url says rubberduck-vba/Rubberduck
so you change the base (left) side to IvenBach/Rubberduck
the url changes to IvenBach/Rubberduck
you need to compare across forks
and then select rubberduck-vba/Rubberduck on the head (right) side
the commit list should update to show commits that your fork doesn't know about
once you see these commits from the main repo, you type, say, "sync with main repo" and hit "create pull request"
so I click compare across forks which then changes base: next and compare: next to be base fork: <> and head fork: <> respectively?
Why does that seem to be more complicated than it needs to be?
because the default PR use case / the use case GitHub wants to encourage, is to push your changes to another repository :)
02:37
Trust me, it's way less complicated than trying to roll back something in the master branch with a bunch of people working on it.
They need to think about derpy people like me that take a while to learn it.
huh - I never realized that the concrete Class_Initialize doesn't run when accessed as an interface.
but makes sense, I guess
Wait what?
@ThunderFrame wait, even if you New up the concrete type??
'IShape
Option Explicit

Public Function GetArea() As Double
End Function

Public Function GetPerimiter() As Double
End Function
'Ellipse
Option Explicit

Implements IShape

Private Type TEllipse
  Radius As Double
End Type

Private this As TEllipse

Private Sub Class_Initialize()
  'Default the radius to 1
  this.Radius = 1
End Sub

Public Property Let Radius(Value As Double)
  this.Radius = Value
End Property

Public Property Get Radius() As Double
  Radius = this.Radius
End Property

Public Function GetArea() As Double
  GetArea = WorksheetFunction.PI * this.Radius ^ 2
End Function

Public Function GetCircumference() As Double
02:41
that's "perimeter" ;-)
'Module 1
Option Explicit

Sub test()

  Dim abstractCircle As IShape
  Dim concreteCircle As Ellipse

  Set abstractCircle = New IShape '**** Class_Initialize isn't called???****
  With abstractCircle
    'IShape doesn't expose a radius property, so method
    'calls will get whatever the default radius is.
    Debug.Print .GetArea          'Calls the Interface member
    Debug.Print .GetPerimiter     'Calls the Interface member
 End With

  Set concreteCircle = New Ellipse
  With concreteCircle
well no... you're newing up the IShape class
how does / why would IShape know about a Class_Initialize?
instead you do Dim shape As IShape and then Set shape = New Ellipse
02:45
the concrete object in your 2nd test could be owned by the With block
I think I just had an inspection idea
@Mat'sMug Yeah, I know - But I spelled it out with an explicit type, for @IvenBach
@IvenBach - Ignore the example above
'IShape
Option Explicit

Public Function GetArea() As Double
End Function

Public Function GetPerimeter() As Double
End Function
'Ellipse
Option Explicit

Implements IShape

Private Type TEllipse
  Radius As Double
End Type

Private this As TEllipse

Private Sub Class_Initialize()
  'Default the radius to 1
  this.Radius = 1
End Sub

Public Property Let Radius(Value As Double)
  this.Radius = Value
End Property

Public Property Get Radius() As Double
  Radius = this.Radius
End Property

Public Function GetArea() As Double
  GetArea = WorksheetFunction.PI * this.Radius ^ 2
End Function

Public Function GetCircumference() As Double
'Module 1
Option Explicit

Sub test()

  Dim abstractCircle As IShape
  Dim concreteCircle As Ellipse

  Set abstractCircle = New Ellipse
  With abstractCircle
    'IShape doesn't expose a radius property, so method
    'calls will get whatever the default radius is.
    Debug.Print .GetArea          'Calls the Interface member
    Debug.Print .GetPerimeter     'Calls the Interface member
 End With

  Set concreteCircle = New Ellipse
  With concreteCircle
    .Radius = 4
    Debug.Print .GetArea          'Calls the concrete member
How do you know if it's skipping items? With the loops of 35 nested 9 levels deep, that's 78,815,638,671,875 iterations. It's probably just not completed (I know because we haven't experienced the heat death of the universe yet). — Comintern 9 secs ago
Wow.
lol
#DoingItWrong
> A *language opportunity* inspection:

````vb
Dim something As Object
Set something = New Object
With something
.Foo = 42
Debug.Print .Bar
End With
````

If a local variable is only ever used as a `With` variable and inside that `With` block, and only ever assigned with `= New` (or auto/self-assigned), then the object reference could be owned by the `With` block, and the snippet can be written as a `With New` block:

````vb
With New Object
.Foo = 42
Debug.Print .
02:58
When all you have is a ̶h̶a̶m̶m̶e̶r̶ loop, everything looks like a ̶n̶a̶i̶l̶ exponent.
@Duga Code-path-analysis?
an assignment might be found inside an unreachable conditional block located above the With block.
@ThunderFrame I'll get to this after defogging my brain of GitHub update stuff.
var foo = declarations.Where(d => d.References.All(r => r.Context.Parent is WithStmtContext)); is still a good start.
The harder inspection would be suggesting adding a with block for repeated dereferences.
That would be a bad-ass refactoring.
@Mat'sMug Are you available to help with debugging VS and any errors that come up while I attempt to step through it?
I have the chatroom on my right and two VS tabs in front of me, working on moving FindSelectedDeclaration into the DeclarationFinder
03:08
@Comintern or @ThunderFrame would either of you be available?
I meant I'm sort-of here :)
I get stuck whitin Rubberduck.VBEditor trying to load up RD.
The part I get stuck on is Rubberduck.VBEditor.SafeComWrappers.Office.Core.Commandbars.DeleteExistingComman‌​dBar()
Within that method on line 34 var existing = Target[name]; won't let me go past
what version of Office are you running?
03:11
what's the name?
The messed up thing is that it's in a try-catch. It shouldn't even be asserting the debugger, let alone not allowing it to continue.
@Comintern Yep
@Mat'sMug "Rubberduck"
@IvenBach - And IIR it doesn't load the menus correctly when you launch it directly from Excel?
it's the indexer
03:14
It appears to load RD when I open VBE.
has to be the indexer
I think I was having a parser issue previously. Currently it seems to be parsing and resolving correctly.
how about var existing = Target.Cast<Microsoft.Office.Core.CommandBar>().FirstOrDefault(bar => bar.Name == name);?
Where is that located?
03:17
I had this:
nowhere, the current code is var existing = Target[name];
               var existing = Target.GetEnumerator();
                while (existing.MoveNext())
                {
                    dynamic item = existing.Current;
                    if (name.Equals(item.Name))
                    {
                        item.Delete();
                    }
                }
aka manual linq :)
manual iteration actually
probably more stable/safe
I like yours better TBH.
It should do the same thing.
^
mine is strongly-typed though ;o)
03:20
Can CommandBars return a non-CommandBar?
One would hope not.
I hope not; IIRC the wrapper implements IEnumerable<ICommandBar>
sort of: IComCollection<ICommandBar>
public interface IComCollection<out TItem> : IEnumerable<TItem>
{
    int Count { get; }
    TItem this[object index] { get; }
}
That's apparently busted in next. My mystery throws on startup are gone.
Weird. It clearly exports this[object].
@IvenBach - Replace the function with this and see if it works:
private void DeleteExistingCommandBar(string name)
{
    try
    {
        var existing = Target.Cast<Microsoft.Office.Core.CommandBar>().FirstOrDefault(bar => bar.Name == name);
        if (existing != null)
        {
            existing.Delete();
            //Marshal.FinalReleaseComObject(existing);
        }
    }
    catch
    {
        // specified commandbar didn't exist
    }
}
Pasted it and got a red squiggly underline
03:29
purple, or red?
(are you still debugging?)
Add using System.Linq; at the very top.
(is the purple highlight a R# thing?)
ah, yes
command bars does not contain a definition for cast and no extension method cast accepting a first argument type of command bars could be found (are you missing a using directory or an assembly reference)
using System.Linq; will give you the missing extension methods
File diff FTW.
03:31
on var existing = Target.Cast<Microsoft.Office.Core.CommandBar>().FirstOrDefault(bar => bar.Name == name); specifically Cast<Microsoft.Office.Core.CommandBar>
And just add that to the very top, correct?
yes
I'm actually surprised VS didn't just add it
that removed the red squiggly line. Going to build and try debugging
On mine it gives a pop-up for "import types for pasted code", but I never really checked to see if that's VS or R#.
It's likely my version of VS being the poor mans version and it doesn't offer help
03:41
@Comintern thoughts?
        public Declaration FindSelectedDeclaration(ICodePane activeCodePane)
        {
            if (activeCodePane.IsWrappingNullReference)
            {
                return null;
            }

            var selection = activeCodePane.GetQualifiedSelection();
            if (!selection.HasValue || selection.Value.Equals(default(QualifiedSelection)))
            {
                return null;
            }

            _lastSelection = selection.Value;

            // statistically we'll be on an IdentifierReference more often than on a Declaration:
(in DeclarationFinder.cs)
Was going to say "needs indentation", but the edit fixed that.
(haven't tested it yet ..hold on, building/running tests)
Tracking _lastSelection in the finder?
I couldn't resist moving FindSelectedDeclaration into the declaration finder
activeCodePane should have a null check in addition to .IsWrappingNullReference.
03:44
it shouldn't be null, but ok done :)
Yeah, IIR I pass nulls in some of the eventargs that feed it. I probably missed it myself.
uh-oh
10 tests failed
03:46
I messed up the constructor
            _declarationsBySelection = declarations.Where(declaration => !declaration.IsBuiltIn)
                .ToDictionary(
                    declaration => declaration.QualifiedSelection,
                    declaration => declaration);
            _referencesBySelection = declarations
                .SelectMany(declaration => declaration.References)
                .Select(reference => reference)
                .ToDictionary(
                    reference => new QualifiedSelection(reference.QualifiedModuleName, reference.Selection),
there's a dupe somewhere
wtf how...
debugs WithVariableMemberCall_IsReferenceToMemberDeclaration
You don't need to call .ToArray() - the raw enumerable is fine if you change the if at the end to a switch on matches.Count.
ha, nice
> Applies equally to the use of factory methods

```vb
Dim scratchPad As Workbook
Set scratchpad = Workbooks.Add()

scratchpad.sheets(1).Name = "SCRATCH"
```

Would become

```vb
With Workbooks.Add()
.sheets(1).Name = "SCRATCH"
End With
```
> @ThunderFrame that's more complex, it involves adding a With block - here it would be seeing that there's already a With block in place. But that would be a very interesting/valuable refactoring!
/equally /unequally
@IvenBach I had an issue with accessing CommandBar properties. It was because I had multiple versions of Office installed, and the registry was borked... The problem goes away if I run the host as Admin. Have you tried running Excel as Administrator, and then Attaching to the Excel process with VS?
Pull selection.Value.Selection and selection.Value.QualifiedName into locals and put the locals in the predicates.
Do the OrderByDescending calls work on declarations with multiple type flags set?
03:57
why not? it's just a long integer at the end of the day ;-)
Right, but do you get the expected sort order?
    [DebuggerDisplay("Variable")]
    Variable = 1 << 15,
    [DebuggerDisplay("Member")]
    Member = 1 << 7,
    [DebuggerDisplay("Procedure")]
    Procedure = 1 << 8 | Member,
I'd hope so :)
Yeah, it looks like the |s are all lower order.

« first day (1007 days earlier)      last day (2173 days later) »