« first day (302 days earlier)      last day (2878 days later) » 

12:00 AM
RELOAD!
[ckuhn203/VBEX] 1 commit. 1 issue comment.
[retailcoder/Rubberduck] 2 opened issues. 12 issue comments.
 
@Duga I have commits... just haven't pushed 'em ;)
@SimonAndréForsberg quiet today?
 
12:23 AM
@Mat'sMug surely looks like it
 
@Mat'sMug That's what they all say!
 
ok just 3.. still!
 
 
6 hours later…
6:39 AM
> The reason for this is in the grammar itself: #iFileNumber does not get picked up as an ambiguousIdentifier, but as a literal (more specifically, a FILENUMBER token). I have modified the grammar and regenerated the parser. I introduced a fileNumber grammar rule: fileNumber : '#' (ambiguousIdentifier | literal); And modified the relevant grammar rules to reference this fileNumber rule: openStmt : OPEN WS valueStmt WS FOR WS (APPEND | BINARY | INPUT | OUTPUT | RANDOM) (WS ACCESS...
WS (READ | WRITE | READ_WRITE))? (WS (SHARED | LOCK_READ | LOCK_WRITE | LOCK_READ_WRITE))? WS AS WS fileNumber (WS LEN WS? EQ WS? valueStmt)? ; The good news is that it correctly picks this up: Dim fn As Byte fn = FreeFile ' assignment picked up Open "abc.txt" For Output As #fn Close However for some reason (seriously, that one is beyond me), this doensn't get picked up: Sub foo() Dim iFileNumber As Byte iFileNumber = FreeFile Open "abc.txt" For Output As #iFileNumber Write #iFileNumber,...
"test" Close End Sub I tried various identifiers - some work, some don't. I have no explanation for this behavior, but it's definitely related to the parser, and it's completely ridiculous - this works as expected: Sub foo() Dim fileNumber As Byte fileNumber = FreeFile Open "abc.txt" For Output As #fileNumber Write #fileNumber, "test" Close End Sub If anyone has an explanation for that one, I'm eager to hear it.
 
6:59 AM
> Oh damn.

`#iFileNumber` fails because the parser thinks it's an `#If` conditional compilation statement. Simple as that. I'm changing the `MACRO_IF` tokens to include an obligatory whitespace *as part of the token* - it's a hack really, but I don't see another way.
 
#If ThisIsDumb Then
 
> cleaned up inspections
> removed DeclarationSectionListener and replaced usages with Declarations API
> added Control declarationtype; symbols now include form controls.
> Fixed NonReturningFunctionInspection false positives
> disabled FunctionNotUsed and ProcedureNotUsed inspections.
> MultipleDeclarationsInspection no longer uses a tree listener.
> Removed ProcedureListener. Only ExtractMethodRefactoring is still using unwarranted parse tree listeners now.
> closes #356 - rebuilt grammar
 
take that, @duga!
 
TTGTB
 
 
3 hours later…
 
2 hours later…
11:19 AM
> @wqweto ***If*** it's not a [pre-processor directive](https://msdn.microsoft.com/en-us/library/ee199689.aspx) (`#IF` statement), yes it is. Please see [File Numbers in the Language Spec](https://msdn.microsoft.com/en-us/library/ee157013.aspx).

It's also important to remember that as a suffix, [The `#` character denotes a type hint.](https://msdn.microsoft.com/en-us/library/ee199603.aspx). Not sure if this change took that into consideration @retailcoder.
> Ahhhh wait. I see what you're getting at here now. The compile time and runtime semantics are different. From the spec. Runtime Semantics: > The file number value is the file number (section 5.4.5) that is the result of Let-coercing the result of evaluating the <expression> element of a <file-number> to declared type Integer. Compile Time Semantics: > The declared type (section 2.2) of the <expression> element of a...
<marked-file-number> or <unmarked-file-number> must be a scalar declared type (section 2.2). Where a scalar declared type is practically any type you can declare a variable As. So, yeah. Basically, #"string" is a valid file number at compile time, but not at run-time, because it's not Let-coercible to an integer.
 
11:36 AM
Well, I just fought with VS for 2 hours trying to get it to properly build the Unit Tests. It wins I guess.
 
12:04 PM
> Could it be defined as INTEGERLITERAL instead of full-blown literal?
 
 
1 hour later…
1:28 PM
> No, because many types can be coerced to an integer. Mind if I ask why you ask?
> Shouldn't this use the WS whitespace indicator? I'm not 100% on it.
 
 
1 hour later…
2:33 PM
INTEGERLITERAL would work ;)
And 1234# remains a type hint, too
 
> @ckuhn203 no, it's a lexer rule defining a token; they all define a whitespace as a literal ' ', I didn't want to change that and risk breaking the lexer ;)
> I actually meant that one as a BYTELITERAL, I found INTEGERLITERAL too wide. This part needs work, all I needed was to capture an identifier when there is one; the tree listener enters that rule, but a literal 123 as a file number breaks something and gets picked up as an ErrorNode. I didn't bother for now because I just needed to pick up the identifier usage, but it would be nice to change it so we can have an inspection that finds literal hard-coded file numbers..
 
2:53 PM
Nice to see that my changes are being scrutinized! :)
 
3:48 PM
Only because someone else got me looking at it.
Ironic, because I'm on the "Collaborate Construction and Review" chapters of Code Complete right now.
I took VS being a PITA as a sign. =)
 
> Install folder for 1.22 x64 is

C:\Program Files (x86)\Rubberduck\Rubberduck\

The extra "Rubberduck" subfolder should be removed for next release
 
lol
 
4:34 PM
@RubberDuck did I just do it again?
            var interfaceMembers = parseResult.Declarations.Items
                .Where(item => item.DeclarationType == DeclarationType.Class
                    && item.References.Any(reference => reference.Context.Parent is VBAParser.ImplementsStmtContext))
                .SelectMany(iItem => parseResult.Declarations.FindMembers(iItem).Where(member => interfaceMemberTypes.Contains(member.DeclarationType)));
...
I did
better?
            var interfaceMembers = parseResult.Declarations.Items
                .Where(IsImplemented)
                .SelectMany(iItem => parseResult.Declarations.FindMembers(iItem)
                    .Where(member => interfaceMemberTypes.Contains(member.DeclarationType)));
        public IEnumerable<CodeInspectionResultBase> GetInspectionResults(VBProjectParseResult parseResult)
        {
            var interfaceMembers = parseResult.Declarations.Items
                .Where(IsImplemented)
                .SelectMany(iItem => parseResult.Declarations.FindMembers(iItem)
                    .Where(member => InterfaceMemberTypes.Contains(member.DeclarationType)));

            var functions = parseResult.Declarations.Items.Where(declaration =>
                ReturningMemberTypes.Contains(declaration.DeclarationType)
^^ building. that should remove all the "function 'xyz' returns no value" inspection results I'm having on classes like IRepository and IPresenter in my test workbook.
there's a weird ArgumentOutOfRangeException thrown in the CodeExplorerDockablePresenter at startup. will address this one next.
ugh. doesn't work. well I didn't really expect this to work on the first attempt anyway..
cool, interfaceMembers works
wait.. it does work!
there's a problem with detecting function (variable?) assignations that involve a Set statement
 
4:52 PM
That's some of the cleaner Linq I've seen out of you. =;)-
And honestly, consider the mess of arrow code it would be using traditional iteration.
 
:)
now "Function 'xyz' returns not value" will only fire on an interface method if the interface is never implemented.
we need an "Interface 'xyz' is never implemented" inspection
@RubberDuck I don't even want to think about that!
I added a IEnumerable<Declaration> Declarations.FindMembers(Declaration) method to the Declarations class, that method should be useful for a bunch of things...
@RubberDuck I just forwarded you some nice feedback we got :)
(I got your email address right, ...right?)
(new phone didn't have the contact :(
 
ckuhn 203 @ the googles
Yeah. I got it. Put a big smile on my face man.
 
5:11 PM
and they ain't seen nothin' yet!
ugh. that false positive is driving me nuts. I can't repro on a smaller workbook.
@RubberDuck we need to wrap every single call to the VBE in a try/catch. I'm having random OptionBaseInspection issues with this line: var declarationLines = module.Component.CodeModule.CountOfDeclarationLines;
fires a COMException because the CodeModule can't be accessed for some reason.
but that's not what's causing my false positives...
            catch (COMException)
            {
                // couldn't access the CodeModule. Whiskey Tango Foxtrot.
            }
^^ like, WTF indeed - the module is parsed at that point...
well there's the ArgumentOutOfRangeException in the CodeExplorerDockablePresenter:
            default:
                throw new ArgumentOutOfRangeException();
I bet it's the new DeclarationType.Control blowing it up
 
5:31 PM
Could be. Very possible.
 
lol, imagine the treeview showing all controls of a form?
yup. was it.
that ArgumentOutOfRangeException just saved the day
that could easily have been missed
oh and the treeview shouldn't sort the members, just the modules... right?
otherwise it gets confusing. 1.2x lists the members in the same order as they appear in the code file, which I believe is the most instinctive / correct thing to do
fixed.
 
But does it still list in code order with the ConcurrentBag discovery?
 
ok. I'm merging into Next
@RubberDuck seems to
 
crosses fingers
 
> Fixed NonReturningFunctionInspection to stop flagging interface members when an interface is implemented. we don't really have a way of telling whether a member is an interface member if the interface is never implemented though.
> Swallowed weird COMException in OptionBaseInspection. No idea how this exception happens, the CodeModule can't be accessed, but then the module has already been parsed at that point. WTF.
> Fixed CodeExplorerDockablePresenter was throwing ArgumentOutOfRangeException when trying to find an icon for the controls on a form; controls are not "real" members, and shouldn't appear in the code explorer. Also fixed member ordering to display members in the same order as they appear in their respective code module.
 
5:42 PM
Don't do this. Event handlers are meant to be called by VBA when an event is raised. The correct thing to do is to extract the logic outside the handler and into another procedure - then to call that procedure from the event handlers. — Mat's Mug 8 secs ago
^^ when we identify event handler procedures, I want an inspection that finds direct handler calls and screams "YUCK!!"
 
YUCK!!
2
 
#SmoothSailing
pushing Next into Refactorings now
 
huzzah!
@RubberDuck I just hope SourceControl will be just as smooth of a merge ;)
(should be)
 
5:54 PM
It should be. It's all fairly isolated from the rest of the project.
 
1.3 is almost here! :)
I think we should stick to calling it 1.3
ooh shiny
        /// <summary>
        /// Finds all event handler procedures for specified control declaration.
        /// </summary>
        public IEnumerable<Declaration> FindEventHandlers(Declaration control)
        {
            return _declarations.Where(declaration => declaration.ParentScope == control.ParentScope
                && declaration.DeclarationType == DeclarationType.Procedure
                && declaration.IdentifierName.StartsWith(control.IdentifierName + "_"));
        }
("_")
I'm on fire today!
reinstating ProcedureNotUsedInspection :)
oh crap
 
@Mat'sMug "_"
 
IKR!
'_' would work just as well ;)
 
oh wow, I don't even need to change anything to pick up class member usages, it just works already!
 
wth
 
7:14 PM
okay. ProcedureNotUsedInspection only can't determine if a procedure is called from CallByName - I think that's fair enough.
 
I'm such a whore.
0
A: Better to write your .NET library with COM limitations in mind, or separate your .NET library from Interop?

RubberDuck However, if you only intend to use COM does this sort of design bring any benefits that I don't see? This snippet of your question is the most important part of your design decision here, and the answer is (as always) it depends. If you only intend to use the library via COM Interop, then ...

Any excuse to link to Rubberduck
 
7:58 PM
lol
@RubberDuck guess what
ProcedureNotUsedInspection works :)
0
Q: Code Inspection: Procedure not used

Mat's MugHere is yet another piece of Rubberduck code, this time the nasty ProcedureNotUsedInspection class, whose role is to identify all procedures that are never called anywhere, and to issue a ProcedureNotUsedInspectionResult for each one. Here's the code: using System.Collections.Generic; using Sys...

and I'm just as much of a whore!
 
> Reinstated ProcedureNotUsedInspection
2
 
Awesome sauce.
 
damn right!
it's only flagging Sub procs though
gotta run
</36-hours-alone-with-visual-studio>
 

« first day (302 days earlier)      last day (2878 days later) »