« first day (1008 days earlier)      last day (2172 days later) » 

00:00
@Hosch250 no wait, that's the meta
RELOAD!
[Hosch250/Rubberduck] 32 commits. 42106 additions. 44939 deletions.
[retailcoder/Rubberduck] 18 commits. 1320 additions. 1682 deletions.
@Duga That's all those tests.
[rubberduck-vba/Rubberduck] 9 commits. 2 opened issues. 1 closed issue. 4 issue comments. 594 additions. 402 deletions.
the name/description would be "Option Base 0 is redundant", and the meta would be "Option Base 0 is the default setting and does not need to be specified."
00:02
Fixed.
[Hosch250/Rubberduck] Hosch250 pushed commit 96b35510 to Issue2185: Update strings
[Hosch250/Rubberduck] Hosch250 pushed commit 96f7286f to Issue2185: Merge branch 'Issue2185' of github.com/Hosch250/Rubberduck into Issue2185
whatever
thanks
Uh, I changed the wrong one.
Option Explicit: Option Base 0: Option Compare Text test?
00:05
[rubberduck-vba/Rubberduck] build for commit 96f7286f on unknown branch: AppVeyor build succeeded
Or...
Option Explicit: Option _
Base 0: Option Compare Text
@Comintern I have something similar.
Except I used Option Base 1 instead of Option Compare Text
It doesn't mind if you have them twice.
VBA doesn't have any constructors, does it?
You have to assign them manually via export update text file and reimport, correct?
00:09
@Hosch250 Until you compile.
Well, the parser doesn't care.
> Compile error: Duplicate Option statement
Please stay out of the tests until my cleaning up is merged.
I just need @Mat'sMug to finish what he is doing in the inspection tests.
[rubberduck-vba/Rubberduck] build for commit ea77c8f8 on unknown branch: AppVeyor build succeeded
@IvenBach just the default, parameterless constructor, if it is in scope: Set x = New Collection
00:11
But you can't feed in a parameter for it? If you want that you have to implement your own constructor?
@IvenBach No you can't, but you can use a factory method - For example - You can't call the constructor on a Workbook (Set x = New Workbook won't compile because the ctor is unreachable), you have to use the factory method Set x = Workbooks.Add(...)
@ThunderFrame That went over my head. I still can't fully understand this 'Factory' stuff
@IvenBach You can't create a new Workbook yourself, you have to ask Excel's Workbooks collection to add it for you. So Workbooks is the "Factory", and its Add method is the factory's method for creating a new Workbook. You, as a VBA programmer, and a consumer of the Workbooks object, can ask Workbooks to create a new instance of a workbook for you, and you provide arguments to Workbooks.Add that Workbooks will use to create the Workbook to your requirements.
Like a lot of stuff in VBA, you can't have a ctor with arguments because of COM restrictions. Classes are new'd up using Windows APIs - take a look at IClassFactory interface.
Factories and Factory Methods allow the factory to determine the initial state of new class instances according to the method arguments, so that consumers of the class don't need to create a new object and then configure it before use. Eg. Workbooks.Open` is a factory method for creating a new workbook based on an existing file (and all of the overhead that goes on for doing that behind the scenes)...
while Workbooks.Add is a factory method for creating a new workbook based on an optional template (and all of the overhead that goes on for doing that behind the scenes.)
Imagine if you created a Workbook with Set x = New Workbook, YOU would then be responsible for determining how many worksheets are created by default, whether the file is loaded from an existing file, or from an existing template, and a bunch of other things that Excel's Object Model doesn't trust you to get right.
00:28
@Hosch250 and once again I fixed too many things at once... I should have left that off-by-one alone
@ThunderFrame I still don't fully understand. It's going to take more reading on my part until it 'clicks'. I've read many factory examples but it still hasn't come together for me, yet.
LOL.
So, is that permission to do the inspections and PR?
Looks good to me.
Since it's my first PR in a while, I'll let someone else merge it.
@Hosch250 yeah, I'll bring in your changes and handle the conflicts
00:30
Cool. I'll do that after supper.
Bye-bye VS2013
NULL-COALESCE ALL THE THINGS!!!
[rubberduck-vba/Rubberduck] build for commit be3d98c8 on next: AppVeyor build succeeded
@IvenBach "Hey Mr. Workbooks (aka Ye Olde Factory for creating new Workbook instances), you won't let me use Set x = New Workbook, so can I please use your Open method for requesting a new workbook, if I tell you it already exists at "C:\Temp\Foo.xlsm"? Just make the damn thing already, and give it back to me all ready to go, and if I gave you the incorrect path, feel free to throw your toys out of the pram an error (and don't return anything)."
00:47
@ThunderFrame I'm a bit slow on the uptake... It's going to be a this is so easy moments once I understand it. I'll get there eventually. Not for lack of reading or other people explaining it to me.
01:25
@Comintern you free? I'm ready to take a crack at this again.
I am - my computer probably needs 15-30 minutes though - I'm in the middle of upgrading my VS install to 2015.
Ah, I noticed that @Mat'sMug seems to be doing the same thing. Either that or he's busy null-coalescing everything.
I'll hold off until tomorrow, assuming that won't be an issue for tonight.
NP - this is going really slow.
@FreeMan nah, kids' bedtime. My local is still on VS2013, I already have 2015 up (RD-Web is C#6)
I want that off-by-one gone
01:30
yeah. I'd have been ready earlier, but my headphones crapped out on me a week ago, and it seems they're not going to honor the warranty, so I was doing some shopping. Plus I've been playing with different run trackers, because... different
is the migration to 2015 now recommended, necessary, optional, or at your discretion?
Necessary. I'm long over-due for updating my VM though.
necessary for all, or for you because reasons?
got it. Tomorrow OK to update or should I kick it off now and we'll work later/tomorrow?
You doing the community version? That one goes pretty quick IIR
01:42
yes, community. Is there an in VS update or do I hit up MS? if MS, is there an update or just vs2015 community & it figures out that I only need to update, not full install...
It's a full install that will land you side by side versions. There's a web installer on the MS site.
At work I have 4 versions of VS installed...
any reason to keep 2013 around, then?
any reason for me to keep 2013 around then?
Nah, not really. Only real reason would be if you need to work on VS 2013 solutions.
Shall I kill all the // arrange, // act, and // assert comments too?
I keep the old ones around at work because we have a ton of legacy code. There's some stuff that won't compile in anything other than VC6.
Here at home, a VS 2013 uninstall is going to quickly follow the VS 2015 install.
I'll probably kick SQL Server up to 2016 while I'm at it.
01:45
@Comintern I'm already working in VS 2017. I'm using some of my own tools :)
@Hosch250 I'm cool with that.
@Hosch250 sure
OK, give me a few more minutes to finish the inspections and do that.
I'll not move to xUnit until after I PR this, and you approve it.
only took about 6 tries to find a link to the 2015 download instead of 2017, but I'm on it.
I upgraded an old PC to VS2015 Community (keeping VS2013 Pro in place) - Delpending on which options you choose, the update is usually fast, but I picked pretty much a complete install and it took 12 hours)
01:47
We tend to stay a release behind the curve on a lot of stuff, mainly for a combination of institutional inertia and stability fears.
any optional items that are recommended? I always click Custom even if I don't change anything, I like to know what my options are... :)
new features, unless orders of magnitude better, are very often just a distraction
it doesn't include any programming languages by default? weird...
@FreeMan Not really - you can reconfigure pretty easily.
IIR it will ask on first start.
I figure the GitHub Extension for VS might just come in handy...
01:49
Yeah, you want that one.
I'm not exactly sure what the Powershell Tools for VS are, but it sounds like fun!
It installs VB.NET and C# by default, I think.
I forget exactly what's available in community, but you can skip things like Azure support, Windows Phone builds, the profilers, etc., etc.
F# is not installed by default in 2015, but it is in 2017, I think.
hrm... maybe I saw C++ and read C# so I clicked it... :/
01:51
IIUC, Python isn't in the RTM for VS2017
oh well, I'll have a bonus, I guess
It's worthless without the Windows SDK.
That's not a bad install to have though - it's nice to have access to the header files.
There's also a bunch of utility tooling in there.
@ThunderFrame I added a couple of options. And it's currently "Acquiring" Visual C++ Library so that musta been the option I picked. It's not exactly zipping along, but, then, my connection tests really fast, but in real life use seems pretty darn slow.
Yay! Restart time.
I'm in the P's.
02:05
[Hosch250/Rubberduck] Hosch250 pushed commit cd422f87 to cleanUpTests: More inspections
Does RD flag CONST c1 as string, c2 as string, ..., cN as string as a code inspection?
I am still stuck on a resolver error and can't check myself.
Even if RD didn't complain, it's not a great idea. ;-)
the logs would have an exception logged by the resolver, somewhere
02:17
Huh. Clean exit right off the bat after installing VS2015.
Some framework fix that didn't get back-ported?
Time to head home and see if I can mess up RD via VS! Thanks for the help again today.
@Comintern DO IT AGAIN!
Yeah, not so much. LOL
@Comintern I don't have a clean exit in 2017.
Performance improvement though - it crashes really fast.
3
Gah! Why do I have 3 SQL server versions on this machine?
02:27
[Hosch250/Rubberduck] Hosch250 pushed commit 6df5003e to cleanUpTests: Remaining inspections
[Hosch250/Rubberduck] Hosch250 pushed commit 5470e7f1 to cleanUpTests: Remove the "arrange", "act", and "assert" comments
Whoa.
> Regex replace much? That's not going to compile.
That found a lot of comment out Assert.Inconclusive calls.
Time to kill the rest of the calls.
@Comintern How many passing tests do you have?
Want to make sure I still have them all.
1735 passed, 8 skipped.
[Hosch250/Rubberduck] Hosch250 pushed commit e1e2c8a1 to cleanUpTests: Fix a couple things
@Duga LOL, yup.
02:37
That's going to be a bit high on mine. I'm 19 commits behind so I only have 1731. IIR 5 skipped.
Well, I'm PR'ing.
Mat said he had 7 skipped, but all 8 have an Ignore, and I didn't add any.
Oh, likely one had been commented out as well.
I uncommented a lot of things (after commenting them).
Yeah the 2 extra skipped ones are for the selected declaration finder I haven't synched.
OK, here we go.
        return declarations.Select(issue =>
            new IdentifierNotAssignedInspectionResult(this, issue, issue.Context, State.GetRewriter(issue.QualifiedSelection.QualifiedName)));
this is going to rock
02:40
Some of the inspection ones can be cleaned up even further but that can happen later.
Oooo... State.GetRewriter.
enough messing around
Green build.
[rubberduck-vba/Rubberduck] build for commit e1e2c8a1 on unknown branch: AppVeyor build succeeded
I can pass the rewriter instance to everything that needs to modify a module, and then GetText when I've removed/added/whatever all the tokens I needed to play with.. and dump it in a module
02:42
Grrr... OutOfMemoryException in the tests again.
Some 23 commits, that was.
Deleted several thousand lines of code.
126 files changed.
Huh. Some weird testing math going on.
@Hosch250 deleted code passes tests!
------ Discover test started ------
========== Discover test finished: 1694 found (0:00:03.0318848) ==========
------ Run test started ------
========== Run test finished: 1731 run (0:03:06.9860144) ==========
it found a few more while it was running?
02:45
IKR?
"Discover test" needs a unit test.
I'm sure it has several.
same issue in 2013 btw
So, I more-or-less get the difference between struct and class, but why would I want to use a struct? (Maybe I don't get the difference after all...)
If you have a value type.
02:47
The main reason I use structs is that you can give them sequential memory layout.
If two of your objects have have identical property/field values, but are two separate objects, then give them a class.
Like, if two families adopted identical twins.
Different objects, but identical (well, pretty much).
If two identical objects are always the same (the way 1 is always 1), then it is a value type, and you should use a struct.
Unless, that is, the value is huge. You want your structs to stay small.
You guys can review the cleaned-up tests any time now.
This is the example from the site I'm reading:
struct Rectangle
{
    private int m_width;
    public int Width
    {
        get
        {
            return m_width;
        }
        set
        {
            m_width = value;
        }
    }

    private int m_height;
    public int Height
    {
        get
        {
            return m_height;
        }
        set
        {
            m_height = value;
        }
    }
}
mutable struct: bad
not sure I understand your example, @Hosch250 in relation to this one.
System.Int32 is a struct
02:52
Use auto-properties. Seriously.
And stop doing that m_ stuff.
an make your value types (struct) immutable
@Hosch250 gosh yeah
Makes me feel ill to my stomach.
This is my all-time favorite trick:
    [StructLayout(LayoutKind.Explicit)]
    struct DWord
    {
        [FieldOffset(0)]
        public uint Number;
        [FieldOffset(0)]
        public ushort LowWord;
        [FieldOffset(2)]
        public ushort HighWord;
    }
    var foo = new DWord {Number = 0x00FFFF00};
    Debug.WriteLine(foo.HighWord);
    Debug.WriteLine(foo.LowWord);
02:54
I didn't use m_, that was copied from the example
OK.
Who? gets out 2x4
okay serisously, whatever website that's coming from...... close that tab and never go there again lol
@Mat'sMug mutable meaning...
Mutable. Don't change properties in your fields.
They should be assigned with the struct is created and left alone--they are values.
If you need a different value, then go get a different value--don't change the one you have.
It doesn't make sense to make an int containing 1 start containing 2...
You go and get one containing 2.
so essentially a struct is/should be read only?
02:56
yes
@Comintern that's also a mutable struct.
with public fields
It needs to be mutable.
so a struct would be good for defining Window.TitleBarColor, Window.BackgroundColor, Window.TextColor, etc. they get set, maybe at build time, or once during loading, then they're read only from then on.
foo.HighWord = 0xFF is a lot easier to read than bit-shifting.
Well, considering the rest of stuff going on in that picture, you need a class.
you could make it implement a bunch of interfaces and override a conversion operator (explicit cast) to/from uint
03:00
What fun is that?
> +2,695 −9,566
2
Lines of code involved in the test cleanup.
You can even overlay other views in the same struct:
[StructLayout(LayoutKind.Explicit)]
struct DWord
{
    [FieldOffset(0)]
    public uint Number;
    [FieldOffset(0)]
    public ushort LowWord;
    [FieldOffset(0)]
    public byte ByteOne;
    [FieldOffset(1)]
    public byte ByteTwo;
    [FieldOffset(2)]
    public ushort HighWord;
    [FieldOffset(2)]
    public byte ByteThree;
    [FieldOffset(3)]
    public byte ByteFour;
}
moving on past structs... This I get:
Because interfaces must be implemented by derived classes and structs, they define a contract. For instance, if class foo implements theIDisposable interface, it is making a statement that it guarantees it has the Dispose() method, which is the only member of the IDisposableinterface.
This I don't:
Any code that wishes to use class foo may check to see if class foo implements IDisposable. When the answer is true, then the code knows that it can call foo.Dispose().
@Comintern BigEndianDWord / LittleEndianDWord?
03:06
if the interface is a contract that anything that implements it will have all the given pieces, why is it necessary for code to check to see if class foo implements IDisposable? if foo is an IDisposable, it'll have .Dispose() or it won't compile, right?
@FreeMan So, if (foo is IDisposable d) { d.Dispose() } (c# 7)
That's right.
But the caller might not know that.
@ThunderFrame Adding a bitflag enum would be fun.
The caller might only know that it is a type Fizz, not that it is type IDisposable. Or it might not know what type the object is until runtime.
@FreeMan You should use using with IDisposable's when you can.
03:08
so I say foo Bar = new foo without knowing that foo is implementing IDisposable?
Yeah.
rule#1: he who creates a disposable, disposes the disposable
how the heck do I go about using Bar without knowing what kind of class I've just instantiated?
Of course, Intellisense will tell you what members foo has, so you typically don't have to do the check.
Or using(var bar = new foo())
03:09
@FreeMan Maybe you were passed an IRepository.
rule#1: he who consumes someone else's disposable, shall not dispose it
True.
That the other Rule #1.
Just giving generic examples--this is about interfaces in general.
@Mat'sMug Tell that one to UserForm...
03:09
yep
@Comintern IKR!
it's almost as if MS guidelines came from "see, it bit us in the @$$, don't do that"
so my method may be passed a class of unknown type and it's up to my method to figure out how to use it at run time?
Anyone want to review my test changes, or do you trust in me?
To be fair, the use case of requesting a COM server to create a managed object and hand it back to you isn't exactly the most common one.
That, as a general rule, means you have a rotten design.
03:12
@Hosch250 I scanned over it, but you're not like those fair-weather friends of ours.
@Mat'sMug then I don't understand why I would have to test for the existence of .Dispose() if I know I'm working with an IDisposable. I shouldn't be getting an IRepository...
@FreeMan That's way more common in the unmanaged world than the managed one.
@FreeMan you generally don't have to, because if you have to know that, then you're the one who instantiated the concrete disposable type anyway, so you already know
I must be totally, blissfully unaware of the unmanaged world, then.
03:14
More often you'll have the opposite problem - you get an object that you know implements an interface, but you can't cast it.
well you could, but that would violate LSP
cue "what's LSP?"
[rubberduck-vba/Rubberduck] build for commit 03f0f3f6 on next: AppVeyor build succeeded
Structured, or unstructured LSP?
Substitutability is a principle in object-oriented programming stating that, in a computer program, if S is a subtype of T, then objects of type T may be replaced with objects of type S (i.e. an object of type T may be substituted with any object of a subtype S) without altering any of the desirable properties of T (correctness, task performed, etc.). More formally, the Liskov substitution principle (LSP) is a particular definition of a subtyping relation, called (strong) behavioral subtyping, that was initially introduced by Barbara Liskov in a 1987 conference keynote address titled Data abstraction...
03:15
I've heard of Lithp, er... Lisp
@FreeMan Your appreciation of VBA's guts will skyrocket if you read up on how IUnknown and IDispatch work.
feeling much like IvenBach right now. Well, pretty much all the time...
RELOAD!
er... REBOOT!
2015 is done installing.
var rewriter = _state.GetRewriter(module.Parent); // todo: determine if we still need to reparse or if we can just pass the rewriter around
03:22
@FreeMan This is an easy starting place: support.microsoft.com/en-us/help/245115/…
hmm, if the RPS cached rewriters, we could share rewriter state between refactorings and quickfixes
will nobody stop me? I'm way too deep here
@FreeMan After that, this is a great reference: daimi.au.dk/~datpete/COT/COM_SPEC/pdf/com_spec.pdf
@Mat'sMug What's the advantage of sharing rewriter state?
Can't they alter the original stream?
I think the stream is immutable
both pages opened for reading
Hmmm...
03:26
but the rewriter keeps tokenized state; you can remove ranges of tokens, insert literal strings between tokens, ...
and then GetText gives you the modified module
so when you have a quick-fix that runs across all modules, you could have n write operations for n modules
instead of n write operations for n targets
Hmmm... I need to wrap my head around:
> Since the operations are done lazily at getText()-time, operations do not screw up the token index values. That is, an insert operation at token index i does not change the index values for tokens i+1..n-1.
i.e. token 12 is still token 12 after you've inserted a string between tokens 4 and 5
so the rest of our parser state / token positions isn't stale
Yeah, I was thinking of the lazy part of it.
buzzword for "you get the entire modified token stream in a string when you call GetText"?
It would generally not be a lazy operation in RD because the tokens we care about are meaningless without knowing the Text. I.e. - Identifier.
03:30
I know - but what I'm looking at now is the perfect storm: something that can manipulate tokens at will, and something that knows everything about the target declaration and its context
OK, I get it.
Might be time to break the Indenter again.
Next horrific Indenter bug I might try to re-write it using the parser state. That isn't exactly going to be straight-forward...
hmm
okay, it builds
Gah! I forgot about the stupid stage changes thing.
Do we like expression bodies?
public int Count => IsWrappingNullReference ? 0 : Target.Count;
and we've had that scalpel right in front of us all this time
Nice!
Missed a comma there, but... Nice!
03:43
yeah still need to figure that one out
this is the rewriter API
Do we have an extension method like PreviousChild(this ParserRuleContext)?
I can't think of anything cooler than module.Remove(declaration) as an API ATM
context.Replace(string newCode)?
@Comintern I think I need to make GetStmtContext also return some int startTokenOffset value
context.Replace(ParserRuleContext newContext)?
03:45
actually it's module.Remove(rewriter, target)
extension methods, so static context
It needs some sort of API for working directly with contexts that aren't part of a declaration.
A lot of the inspections are easier to work with the parent contexts than the declared ones.
really?
almost every inspection result has either a declaration or an identifierreference target
Now that I'm in VS2015, I just want to clone from my remote right on top of my previous local, right?
there were no changes that needed to be committed or pushed.
03:50
just hit
@Mat'sMug Getting ahead of myself there. I meant to say "in a world without Declaration..."
oh
well, yeah lol
@FreeMan Nah, just open your local in VS 2015.
Or do you mean synch your fork?
I'm going to leave a bunch of debug output in my next commit.
I'm curious what the shutdown sequence looks like for those of you who can exit cleanly...
I'm also leaving in a ton of commented Dispose code in case it turns out to not improve the stability of the parser. I'll clean it out when I'm sure it can go.
@Comintern I need to get 2015 to know what remote to sync the local to, right?
@Mat'sMug I don't have a sync button to hit
Nope. That's all in your git config.
03:56
@FreeMan team explorer > unsynced commits > ?
so, since I opened the previous .sln file, it now knows where to push to & pull from?
Can you see the RD solution in Team Explorer - Home?
ah! it didn't come up in the home screen. I see it now.
Were we going to update 2.0.12 with a hotfix release?
03:59
lol
@FreeMan You constantly are feeling lost and behind everyone elses knowledge base?
the hotfix is getting overboard isn't it
@IvenBach just a touch...

« first day (1008 days earlier)      last day (2172 days later) »