« first day (1908 days earlier)      last day (1272 days later) » 

7:00 PM
@MathieuGuindon that means the formatter knows too much about the declarations, I think.
 
    public class DeclarationFormatter : IExportable
    {
        private readonly Declaration _declaration;
        public DeclarationFormatter(Declaration declaration)
        {
            _declaration = declaration;
        }

        // TODO: implement IExportable
    }
@this ...do different declarations export differently anyway?
 
I assumed that there might be extra properties that needs to be described. That might not be the case though.
 
if the output is to be a table, it stands to reason that every declaration needs to produce the same output
 
also consider the case where we are given a list of declarations; to describe them, we need to know the most derived type.
sure, but the contents of the table wouldn't be the same.
e.g. Class vs. Module
My memory might be mistaken but we have a ClassModuleDeclaration and.... just ModuleDeclaration?
 
take ParameterDeclaration - IIRC it adds info about whether the parameter is ByRef or ByVal. But the text of it is already in its Context, which the base class can access; and the output won't have a ByRef/ByVal column to put that information in
besides isn't the current implementation on Declaration anyway?
I think we can make a one-size-fits-all formatter for declarations, and adjust as needed, if needed.
 
7:07 PM
you might be right - this is overcomplicating it.
so one-size-fits-all for now.
Gonna remember the YAGNI principle, too. :)
 
@IvenBach it's exactly what's happening here: we need Declaration (and others) to be able to do something, but we don't want to bloat these classes with the new functionality - so we put it elsewhere and, in this case, use composition to wrap the type we want to extend in a class that implements the interface that defines the tack-on functionality
I wonder if they also flagged it as spam...
@random-downvoter: thanks for not letting me know what's wrong with this post. I love being kept in the dark and receiving random unjustified downvotes. The linked add-in is free & open-source software, I did put in a disclaimer, and the described features genuinely make dealing with VBA module & member attributes a much more pleasant experience. — Mathieu Guindon 10 mins ago
 
7:24 PM
For now do I place each of the new derived types in Rubberduc.JunkDrawer.Output?
 
I'd put it in Core I think
 
RD.Core.Common?
 
@IvenBach Took me ages to grok, but I'll have a stab at an explanation... Imagine you distribute an interface, which people start using and relying on. It's fine to provide implementations of that interface, and add more implementations over time (open for extension). But you should avoid changing the interface (i.e. the 'contract'), because you'll break your customer's code (closed for modification).
The big ducks will tell me all the things that are wrong with what I just said :-)
 
So like with Excel.Range.Value how it formats and that's why they introduced Value2 so as to not break any of the previous code based on Value and the formatting it does?
 
yes, I would say so
 
7:30 PM
:click: ah.
 
Technically Value2 modified the Range interface though. Would have been a problem if user code could implement it
 
Yeah I figured there'd be hackery involved, didn't know the specifics :-)
 
the thing with Value/Value2 is more of a COM thing than SOLID, I think.
because per COM, you should never change the interface that you've published
or the consumers start having compilation errors. After all, COM is an ABI, not an API.
 
tbf, you should never change the interface of any public API. At least unless / until default interface implementations arrive...
 
@IvenBach thinking RD.Core.Formatters or something. I mean, it's a feature in its own right, and if we ever splice UI out of Core, then it remains accessible assuming Core depends on RD.UI
 
7:36 PM
MS seem to be moving more towards (abstract) class based APIs, as they're slightly more forgiving.
But take your point, its even worse in COM
 
It's too easy to dump stuff in RD.Common if we start putting features in there
 
@mansellan Yes, Nuget helps makes it much easier to distribute changes but still there's limitations - you proably don't want to delete a published method for example.
 
@MathieuGuindon We should have no Common anywhere.
 
Is the resolver PR good to go? LGTM
@this nah Common is fine, say, for shared UI components
 
7:39 PM
@MathieuGuindon I only reviewed a bit but not enough. LGTM so far.
@MathieuGuindon Sure but it should be more specific - why notSharedUiComponents or SharedComponents or something that's more descriptive. Common says nothing.
 
@this @this cool. feel free to hit that green button any time!
@this oh, 100% agreed!
looks at contents of RD.Core.Common, closes tab
 
That being said... there's only so many ways to express "stuff that's useful to any project, and none in particular" - get too specific and you end up with 100 projects...
 
I think ClipboardWriter and ExportFormatter should go to RD.Core.Formatters ..or perhaps RD.Core.ClipboardExport
 
Hence the discussion WRT com / typelib stuff. ;-)
 
inclined to say RD.Common, then namespace from there... but maybe I'm nuts ;-)
 
7:43 PM
@MathieuGuindon I like RD.Core.Formatters
right now it's just clipboard but no reason why it won't be only clipboard.
 
ClipboardFormatters would be more descriptive though
 
agree that Core is probably slightly less irksome a word than Common
 
Right - I think it's more organic to start with Formatters, then later grow into Formatters.Clipboard and Formatters.whatever
See, Core shouldn't exist either....
in reality it's UI with some other concerns tacked on.
 
eh, Core is ALL TEH FEATUREZ!
 
... except for some features in main, inspections, etc. :p
 
7:45 PM
@this interesting. this could make a nice home for the RD commandbar "current selection" formatting code
yeah except the stuff we pulled out of it ;-)
 
I chose Framework at work. Ended up with many projects, but that's because I wanted to separate out nuget dependencies 1:1 - so we get Acme.Framework.ServiceFabric, Acme.Framework.NLog, etc...
 
@MathieuGuindon exactly!
the problem (at least for me) is that the build order isn't that intuitive
 
ProTip: If you're not sure where to put your code, dump it in Core :-)
 
doesn't help that VS arrange them alphabetically, too
so you have to remember that Core is in middle of the build process, which can complicate things esp for inspections or refactoring which IIRC comes after core
but core depends on parsing and vbeeditor. oh the joy!
 
@this uh, wut?
loads VS
 
7:51 PM
@this IIRC @Vogel612 reversed that dependency - it used to be that Core had no idea about inspections (we wanted to load them "plug-in style"), but unless I'm mistaken that's no longer the case
 
let's see if I'm making up random stuff again! :-D
 
Huh, it has 11 dependencies...
 
@MathieuGuindon ah OK. I might have missed/forgotten about that
 
yup, confirmed
  <ItemGroup>
    <ProjectReference Include="..\Rubberduck.CodeAnalysis\Rubberduck.CodeAnalysis.csproj" />
    <ProjectReference Include="..\Rubberduck.Interaction\Rubberduck.Interaction.csproj" />
    <ProjectReference Include="..\Rubberduck.JunkDrawer\Rubberduck.JunkDrawer.csproj" />
    <ProjectReference Include="..\Rubberduck.Parsing\Rubberduck.Parsing.csproj" />
    <ProjectReference Include="..\Rubberduck.Refactorings\Rubberduck.Refactorings.csproj" />
    <ProjectReference Include="..\Rubberduck.RegexAssistant\Rubberduck.RegexAssistant.csproj" />
 
@this Baskin Robbin Three-or-Two Flavors.
 
7:53 PM
Oof, so core knows everyone except Main, it looks like.
 
well it's the Core :)
 
(and only Main knows about VB6/VBA, IIRC)
 
Don't you mean Voltron?
 
7:54 PM
I guess I misunderassumed what it was for from the name. Was expecting it to have zero project dependencies.
But it knows, uh, lots about the duck.
 
See? My point exactly about the names like Core or Common
had it been a Rubberduck.UI, there'd be little doubt
 
good point
 
in Rubberduck.UI I'd expect the dockable and WinForms hosts, xaml controls & resource dictionaries, ...and that's all. ViewModels? tough call.
 
@this and that's marginal. the only reason it has a hard ref to VBA/VB6 is to avoid build snafus. I think it's about 2 LoC to decouple it.
 
@MathieuGuindon should they belong in their respective project?
we kind of have that situation w/ refactoring and it's not.... ideal.
 
7:57 PM
IDK what the best architecture is :-/
 
who knows. maybe it's all wrong. Maybe refactoring project should have total control over its forms and stuff
and the core project provides the shared UI components
and the main project well, unites them all (just like Voltron)
but that's a change in build process - core would have to build then refactoring / code analysis then finally main
 
I like that Main is pretty lean and very focused on initializing everything
hm, why does DockableWindowHost need to be in Main?
I suspect it's COM-registration related, but ...
 
@MathieuGuindon That would be my guess
 
yes because of how VBiDE works
Main also double as the public COM API for RD's stuff
 
8:02 PM
Hence all the mocks/fakes stuff
 
might as well register all COM in one place, makes sense
 
yep and TBH I'm not 100% enthusiastic about the architecture.
In the case of FAkes, we ahve some implemetnation in Core
but COM -visible types in Main
for mocking... I have no idea in hell what I want....
 
part of that is me wanting the VBA code to care for nothing other than Rubberduck.tlb
moving these types would break existing users' unit tests
 
yeah...
 
agreed. it'd get really messy to ship .tlb for each project
 
8:04 PM
pain
 
except for API, which is kind of a separate user case
at least in amin, they are all in the Com folder so we know that it's there for that purpose.
(at least until we merge the mocking PR which makes mess of main...)
 
Huh, just seen that COM-visible stuff is in both Main and Api - why are they separate?
 
the API stuff registeres to Rubberduck.API.tlb, which comes up as Rubberduck API
it has been like that since the start. Was that a good question? IDK.
ah, I think I know why - you don't want experimental stuff in your type library
 
I guess it's the difference between stuff that's com-visible so that the VBE can load us, versus com-visible so users can set a VBA reference?
 
because if it changes, then you end up breaking the code that's based on more stable types like fakes.
 
8:06 PM
API is fully experimental and entirely expected to break when we figure out a good way for it to be leveraged in VBA client code
 
^
 
ok cool, makes sense
 
I don't think it's marked experimental ATM, though
 
it's not a Core feature ;-)
 
Core 3 - 23 September :-)
 
8:08 PM
lol
 
yeah. I'm not sure how much mileage the API's getting, either.
 
none, basically
 
Discoverability...
 
that's the thing: it's known to be somewhat borked, so it was never really advertised as a feature
 
that's one part of the problem, yes.
but the real problem, IMO is that it's not very.... useful.
 
8:09 PM
we could just sunset it
and wait until someone opens an issue asking "hey what happened to Rubberduck.API?"
 
yeah, that would be one option.
 
I thought it was used to give early-binding in unit tests? Am I misunderstanding?
 
No, that's from Rubberduck.tlb
 
ah ok
 
API basically gives you the declarations in VBA
and .... that's it.
 
8:11 PM
it's an attempt to expose RD's parser to client VBA code... some kind of reflection API
 
yeah i see
 
it's just.. it's a shitty API to work with :)
 
^
and the declarations has had some updates since but API wasn't updated, either
 
and I don't remember if the event-driven parser ever worked
 
One major problem is that you get one whopping huge list of declarations
 
8:12 PM
Hey, we could always re-architecht to supply a langauge server - known and widely used API there...
HHCIB?
 
with no way of searching/filtering
 
;-)
 
so parser.Parse would be an annoying blocking call
 
just need some volunteer to maintain it.
@MathieuGuindon I think I fixed that at one point.
 
cool, so at least it's somewhat usable :)
 
8:13 PM
but it very well could have had broken, again because parser was changed, too.
yeah. I think what it really is missing is the DeclarationFinder, basically
 
actually I cloned OmniSharp's LSP the other day... Now I just need a spare, uh 20 years or so to grok it :-)
ttgh
 
> The COM API was originally intended to expose RD's internal awesomeness to VBA code, so as to enable some kind of reflection capabilities in VBA.

Problem is, it's a fringe feature that was never advertised, never really completed, and using it tends to make the VBE unstable.

Shall we cure it or kill it?
 
@Duga leaner is cleaner, my vote goes to kill it
 
@Duga is posting in RPN now
 
huh?
oh
been doing that forever though
 
8:24 PM
sometimes she gets it right
 
> IMPOV, the main problem with the API is that it's not very useful because in the end all it does is give you a giant list of all declarations from a parser that knows nothing about the add-in's parser's cache (meaning you must parse separately using API's parser to get the same information) and you don't have an easy way of filtering/searching the results.

So at very least, it needs a `DeclarationFinder`. There are probably other features that could be added but as it is right now, it is i
 
I think it depends whether the SE chat server agrees with her posting
 
I thought it also had to do with what events she gets from github API
 
that too
but
if
you
posting
try
faster than the chat server allows, you hit timeouts - if your message queue isn't waiting for the previous message to succeed, then you're outputting out of order
or maybe the GH API just spits out events out of order and @Simon did the queuing right :)
 
granted but in that scenario above, that was Duga's first post for a while.
 
8:29 PM
16 secs ago, by Mathieu Guindon
or maybe the GH API just spits out events out of order and @Simon did the queuing right :)
 
'bout to fall asleep at my desk. I think that's a sign I should go home.
 
yeah, that.
 
@FreeMan have an espresso, for the road!
 
Yeah, just might
TTFN
 
@Duga to be clear, "sunsetting" implies merging a commit that removes it from the project, burying that work in the commit history, correct?
 
8:32 PM
yeah, as long it's int he commit historyit shoudl be always recoverable....
which is what we did for SC, right?
 
yeah
the more I think about it, the more next release shouldn't have RD.API
 
I have to agree.
i really like the idea of API but if nobody's around to keep it up to the date, it's going to just add to the build and it doesn't have any proper unit tests so nobody knows if it's working or has broken.
 
if the API does come back (and that's a big if), they can set up unit tests similar to what I did for mocking which would enable testing of using the API via COM, closely simulating the usage from VBA.
 
8:48 PM
neat
 
> Sounds like it's in a similar spot to Source Control, except less used.

I vote we remove it for now, it can always be resurrected if need be.
> The defunct Source Control panel is a good analogy, although lots of folks would use RD *just for that*, whereas the parser API... meh.

Let's kill it then.
 
9:05 PM
random question - all the cool kids seem to be using cake - could it help tame our build process?
 
Vogel612 mentioned that few months ago
 
ah ok
 
IDK if he wants to take it up and use it
 
how do these OSS projects afford all these CI platforms?
 
well cake is a net foundation project, so I guess they get lots of freebies...
 
9:07 PM
?
cake isn't a platform?
 
> This project is supported by the .NET Foundation.
yeah that explains it :)
also this looks familiar:
> A big thank you has to go to JetBrains who provide each of the Cake Developers with an Open Source License for ReSharper that helps with the development of Cake.
 
@this nope, its just a build system
 
also I love how AppVeyor is the only one whose badges don't display
 
Azure Pipelines is pretty nice tbh. I wasn't expecting much from it, was pleasantly surprised.
@MathieuGuindon huh, they do for me?
 
9:10 PM
the way I understood it, you can run cake on AV - it's just another program to run, basically\
 
they do now
the way I understand it, it replaces msbuild?
 
@this I think you can run it anywhere - it can produce local builds too
 
No, it doesn't.
It just makes it easier for us to orchestrate complex build
 
> # Execute the bootstrapper script.
./build.ps1
 
One thing I'm not 100% clear that maybe @Vogel612 can clarify - whether that will replace the VS's default build.
 
9:12 PM
no it won't.
VS's default build directly calls msbuild as a child process
 
hmm. meh.
 
a cake build would first build the cake project and then run that project, which will invoke the toolchain
 
i definitely don't want something that requires doing something different than simply building. Any customizations on our part should be invisible to the potential contributors
 
sounds like bolting-on yet another step?
 
the projects that I have seen using cake are shipping a build.sh
which then does the cake stuff
the more time passes, the less interested I am in migrating to cake, though.
especially considering that the dotnet-cli is getting ever closer to being the default toolchain for .NET dev
 
9:17 PM
given that we already have a custom msbuild task, I'd rather just extend that project instead.
 
I agree with that
 
Who's that?
3
(sorry couldn't resist)
 
tfw you see code solving a familiar problem in a different setting...
or even better:
public async Task<QuickFixResponse> Handle(FindSymbolsRequest request = null)
 
ohhh what?
 
9:21 PM
the C# language server used by VS code
 
I had to manually install it, I know what it is 😉 I just didn't know they were doing QuickFixes that way
 
yeah, it's all request/response over stdio
 
2 hours ago, by Mathieu Guindon
@this IIRC @Vogel612 reversed that dependency - it used to be that Core had no idea about inspections (we wanted to load them "plug-in style"), but unless I'm mistaken that's no longer the case
^ sidenote re that: I'm pretty sure I had a reason for that, but I can't for the life of me remember right now ...
but yes, I did reverse that dependency. Probably more than once, actually
 
it was a plain PITA
half-assed decoupling and all
 
relately to that earlier discussion:
 
9:27 PM
Removing the reference from code analysis to core was necessary to get the settings under control, IIRC.
 
I'd say that the IExportable implementations are best off being ViewModels
@M.Doerner right, that was the thing
 
@Vogel612 there's no UI?
 
and that RD.Core should be split into RD.UI and RD.Core, with the ViewModels being in the UI project
@this but exporting is mostly a UI concern.
especially for CopyToClipboard, which only makes sense for stuff selected in the UI
1 hour ago, by this
it has been like that since the start. Was that a good question? IDK.
^that was not always the case, I think. At some point we shipped both Rubberduck and the API in the same TLB, but I don't think we ever green-released that
 
so, until there's a RD.UI, RD.Core is the best place for it
 
hmm. I can see clipboard as being an UI concern, but in general, exporting isn't necessarily a UI concern.... right?
 
9:31 PM
@Vogel612 I believe we did
 
@this yes, generally speaking, that's true.
 
There were quite a few green releases with the API inside Core.
Then somebody separated it.
 
but the export is always triggered through user action and has nothing to do with the "business logic" of whatever's being exported
 
yes. should it be just an ICommand implementation?
 
it's not already?
1 hour ago, by Mathieu Guindon
or maybe the GH API just spits out events out of order and @Simon did the queuing right :)
^ GH hooks delivers events via separate HTTP requests, which may be routed differently resulting in nondeterministic ordering
okay, with that I seem to be caught up on chat :D
 
@Duga 2.4.2 is past due by 4 months
 
I would like to get a few more things in before release.
 
so would I...
also I'd say with the resolver improvements (and the devtime put into it), it's better to release it as 2.5.0
 
In particular, I would like to fix the ObjectVariableNotSetInspection and add inspections leveraging the new capability to resolve default member accesses.
I think I will also go the route suggested by @MathieuGuindon and add failed let coercion references.
That will make the ObjectVariableNotSetInspection rather simple.
Moreover, it would allow to warn about more contexts in which an object without a default member is used but required.
The VBE does not warn about that on compile time.
 
9:53 PM
@M.Doerner hm, got an example of that in mind?
 
In any arithmetic expression or in parentheses
 
Wait does that mean we can now warn about redundant parentheses?
 
For objects, they are not redundant.
They actually cause a Let coercion.
 
yeah. I have MsgBox ("foo") in mind
 
ooooh that is completely totally moronic
I found out why test is misbehaving
        [Test]
        public void doop()
        {
            var mockFso = new Mock<Scripting.FileSystemObject>();
            var mockDrives = new Mock<Scripting.Drives>();
            var mockDrive = new Mock<Scripting.Drive>();

            mockFso.Setup(x => x.Drives).Returns(mockDrives.Object);
            mockDrives.Setup(x => x[It.Is<object>(p => p == (object)"abc")]).Returns(mockDrive.Object);
            mockDrive.Setup(x => x.Path).Returns("foobar");

            var input = "abc";
it looks like dynamic is dumb WRT indexed parameters.
 
10:01 PM
@M.Doerner so we could turn foo = (a + b) into foo = a + b?
 
No
But we would know whether it is legal if a is of a class type.
 
that's a huge, huge win already
 
In my current PR, we just return the inner expression, if the coercions fails.
My idea is to wrap it in another expression with ExpressionClassification.ResolutionFailed and then to save the references on the module states like we do now for the unbound default member calls.
Then we can have an inspection that returns results based on the collcted failed coercions.
 
@MathieuGuindon 2 year, and thanks :)
 
If @this or @Vogel612 have no objections, I'd merge #5089 tonight
 
10:11 PM
Set up a ToDoItemFormatter but am unsure where usage for it goes.
 
@MathieuGuindon go for it :)
I'm not going to have the time to thoroughly look at it, but considering there's already an approval, I'm not going to withhold mine :)
Hey @M.Doerner unrelatedly: could you explain to me why you're filtering the annotations in the DeclarationResolveRunnerBase to only those where AnnotatedLine.HasValue?
you seem to be assuming that the value has been accessed before the resolver runs...
 
The annotations are collected in the parser. So, they are there when the resolver runs.
 
@IvenBach start tracing usage by following the breadcrumbs from the "copy to clipboard" button & the associated command ;-)
 
nevermind, I'm an idiot..
 
They are attached to declarations based on their type (Member,Module, etc.) and the line they are on.
 
10:16 PM
I confused HasValue with IsValueCreated
 
So, an annotation without a line does not help much.
 
@Vogel612 this is turning into a meme lol
 
"turning into"?
 
haha
TTGH
 
@MathieuGuindon Instead of OfType<IExportable> would the more appropriate use be Of<FooBarSpecificType>?
I feel like I'm more stuck on the idea itself instead of actual usage.
 
10:19 PM
@IvenBach why would you need to handle the specific type?
 
If all you need is IExportable, use that.
 
the whole point of the interface is to be able to not handle the specific type
 
:derp:
 
that's what LSP is about :)
 
That's what I get for exposing my self ignorance. Always learning.
 
10:21 PM
However, if you already know that your types implement IExportable, you might move that requirement into the type of the original parameter.
 
^ That thought has occurred to me.
 
Then, no cast is required at all.
 
That would also eliminate the switch entirely.
 
Here, it is convenient that IEnumerable<out T> is covariant.
 
covariant means what?
 
10:23 PM
i.e given interface Foo, class Bar : Foo, class Baz : Foo, you can pass an IEnumerable<Bar> as an IEnumerable<Foo>
 
If T can be cast to U, then IEnumerable<T> can be cast to IEnumerable<U>.
 
past-Iven read Covariance and Contravariance in Generics before but couldn't understand it.
 
^^too slow typing
 
That's what is meant by a derived class is narrower than it's base/parent from which it derives?
 
yes.
because a parent has a "wider base" of possible children in the tree of types
 
10:26 PM
current-Iven should probably read that link again. Skiwi'd for later reading.
 
There we go.
 
@Hosch250 Wrong photo. Need one of the Pineapple-in-Chief.
 
yaaaay, down to 73 failing tests!
okay, test run is still not finished, actually ...
~sigh
up to 87, 1.6k test still to run
okay, down to 160 failing tests, probably going to get a few knocked down with easy fixes.
 
10:54 PM
@Vogel612 Did a double-take there - I'm into a different LSP rn :-)
Too many acronyms, not enough letter combinations :-)
@IvenBach (probably wildly inaccurate) simple example - If you have a List<Animal>, you can add a Dog, a Cat, etc, as long as they all inherit from Animal, because List<T> is covariant with respect to T. Wasn't always true - when .net first got generics, they were invariant, you could only add the exact type.
Contravariance is also essential, but less easily explained :-)
 
List<T> should not be covariant, actually.
 
bah
fml
ok, so IEnumerable... #LifeFail
 

« first day (1908 days earlier)      last day (1272 days later) »