« first day (156 days earlier)      last day (3024 days later) » 

1:25 AM
REVERT REVERT!!!
 
2:00 AM
lol
 
 
9 hours later…
11:01 AM
Hmmm.... I'm going to need to learn about XML config files I think...
 
 
3 hours later…
2:03 PM
Getting there. I need to figure out how to refresh the list, but I'm almost there.
 
 
2 hours later…
3:50 PM
@RubberDuck use data binding!
(that looks pretty damn good BTW)
I think it needs a "Project" column - there might be more than 1 project opened with a "ThisWorkbook" module
look at the "go to selection" feature in the test explorer code
actually, the OnExplorerGoToSelectedTest method in the TestEngine class
        var codeModule = _vbe.VBProjects.Cast<VBProject>()
                             .First(project => project.Name == selection.ProjectName)
                             .VBComponents.Cast<VBComponent>()
                             .First(component => component.Name == selection.ModuleName)
                             .CodeModule;
        if (codeModule.Find(signature, ref startLine, ref startColumn, ref endLine, ref endColumn))
        {
            codeModule.CodePane.SetSelection(startLine, startColumn, endLine, endColumn);
            codeModule.CodePane.Show();
        }
 
That was on my list of things to add. Nice @Mat'sMug! Thanks!
I know it's going to need some refactoring though. Need to extract those common methods somehow, but first things first.
Hmm... I am using data binding, but the grid view doesn't seem to update. I tried using your TestExplorer as a guide, but I'm missing something.
 
actually the TestExplorer doesn't update automatically either...
had to add this "refresh" button
..or find a way to wrap a codepane's code into some ObservableCollection<string>
i.e. "detect" code changes as they are happening
 
4:08 PM
That might be difficult.....
 
yeah
hence the refresh button ~> "easy way out"
 
Aha! got it. THanks.
 
4:40 PM
parser is starting to look like it's going to work :)
    private IEnumerable<SyntaxTreeNode> ParseModuleMembers(string publicScope, string localScope, IDictionary<int, string> logicalCodeLines)
    {
        var currentLocalScope = localScope;
        var lines = logicalCodeLines.Values.ToList();
        for (int index = 0; index < lines.Count; index++)
        {
            var line = lines[index];
            var instructions = SplitInstructions(line);
            foreach (var instruction in instructions)
            {
                SyntaxTreeNode node;
if (node.DefinesScope) -> then I'm going to pass index by reference to some ParseCodeBlock method, so when it returns index will be at the correct line number. I think I need to implement some builder pattern on SyntaxTreeNode to maintain immutability and allow adding child nodes.
I think I need to rename DefinesScope to HasChildNodes
simpler & more flexible
 
4:58 PM
SyntaxTreeNode ParseCodeBlock(SyntaxTreeNode node, ref int index) will be recursive - so I should get the nesting right.
Thanks! FYI I'll be putting up the parser on Code Review when I get it to do what I intend it to do ;) — retailcoder 1 hour ago
^^ this guy deserves some more votes
71
A: How do I tell my colleagues that the codebase they've built is a total mess and their practices are ancient?

enderlandtl;dr This is not a technical problem it's a people problem. Treat it as such. I ain't changin' anything! You are off to a really bad start and it has nothing to do with the code. It sounds like your people skills are lacking. You don't start charging into a new job telling the current team...

^^ reminds me of my old job!
 
 
2 hours later…
6:44 PM
@Mat'sMug it's funny that this has ended up right back where it began. With a VBA parser... =)
 
indeed!
 
Pull request will be incoming sometime today by the way.
 
great! keep 'em coming!
 
I will. Probably going to have to sit it aside for a few days after this, but I am definitely going to make the test explorer dockable. Then I want to make some things configurable.
I'm not happy that the user can't specify what comments to pick up for the task list..
 
@RubberDuck what do you mean?
oh, do you mean like some options window where the user can configure what specific comments are picked up? like, it's 'TODO:, 'BUG: and 'NOTE: by default, but user could add 'TASK: and 'Work item # to it?
(although I don't agree with "work item" comments)
@RubberDuck I'm probably going to redo some parts of the test code once I get the parser to work as intended - namely the "attributes" part.
        public SyntaxTreeNode(string scope, Match match, string comment, bool hasChildNodes = false)
        {
            _scope = scope;
            _match = match;
            _comment = comment;
            _hasChildNodes = hasChildNodes;
        }

        private readonly string _scope;
        public string Scope { get { return _scope; } }

        private readonly bool _hasChildNodes;
        public bool HasChildNodes { get { return _hasChildNodes; } }

        private readonly Match _match;
^^ Comment being a member of SyntaxTreeNode, you could be leveraging that too, say, with an extension method to SyntaxTreeNode, to walk the tree and locate all "todo" items
this is going to end up being a freakin' ReSharper for VBA!
 
7:16 PM
Yes. That's exactly what I mean!
And isn't that the point? The IDE sucks. Even with MZ Tools installed.
 
and we're going to change that :)
 
Something I would personally like to figure out is how to hijack the built in windows and apply the user's font and background colors everywhere.
I don't even know if it's possible, but it's a real pet peeve of mine.
I guess I'll put that on the "Nice to have" list.
 
I don't see how it could happen though, but yeah would be nice
that, and a CodeModule.Changed event
ugh. I'm not sure how to capture EnumNode child members. If I make an EnumMemberSyntax : ISyntax, it'll be picked up as a grammar syntax and then every line of code that looks like a single identifier and/or an assignation will be picked up with it.
hmm.. perhaps I can have a ISyntax childNodeSyntax member on CodeBlockNode, and then ISyntax can have a bool flag that enables/disables it from being picked up as general syntax.
        /// <summary>
        /// Gets a value indicating whether syntax is specific to a particular parent node.
        /// </summary>
        /// <remarks>
        /// Implementations with this member set to <c>true</c> will not be considered as part of the general grammar.
        /// </remarks>
        bool IsChildNodeSyntax { get; }
and then..
        private IEnumerable<ISyntax> _grammar;

        public Parser()
        {
            var syntaxType = typeof(ISyntax);
            _grammar = Assembly.GetExecutingAssembly()
                               .GetTypes()
                               .Where(type => type.GetInterfaces().Contains(syntaxType))
                               .Select(type => type.GetConstructor(Type.EmptyTypes).Invoke(Type.EmptyTypes))
                               .Cast<ISyntax>()
                               .Where(syntax => !syntax.IsChildNodeSyntax)
ah, that's going to work!
    internal class EnumNode : CodeBlockNode
    {
        public EnumNode(string scope, Match match)
            : this(scope, match, string.Empty)
        {

        }

        public EnumNode(string scope, Match match, string comment)
            : base(scope, match, comment, string.Concat(ReservedKeywords.End, " ", ReservedKeywords.Enum), typeof(EnumMemberNode))
        {

        }


    }
@RubberDuck if you make an options window/dialog, make it have tabs, or another mechanism for having "pages" - the refactorings will need options too, and perhaps the test module/method templates can be configurable too.
scoping is completely flawed... I'll have to fix that later.
and wow, enums are a problem all by themselves... I think I'll skip adding a Value member for now.
 
8:06 PM
Just leave a note. Lots to do. Rome wasn't built in a day.
 
Maybe I'm just overthinking it. An enum member's underlying value has more to do with interpreting than parsing..
I could just have a string Value that returns whatever value the member is declared with.
 
@Mat'sMug It would be a suitable start. And you know the underlying type of any enum is long.
 
Int32 then :)
but yeah I'll just make it a string for now - the parser shouldn't be concerned with underlying values, only whether or not there's an explicit value defined
the fact that the parser's primary assumption is that the code is compilable helps a lot :)
 
Hmmmm might have trouble having a toolbar in the dockable window......
 
oh crap.. what's up with the toolbar?
 
8:10 PM
What's wrong?
 
like, it's not working at all, or it just looks like shit?
 
looks like shit
2
 
then there's gotta be a way to fix it :)
is it the separator breaking it?
 
I'm sure. How do I dock a grid view under the toolbar?
 
you need a panel
for the TestExplorer window I had the toolbar docked at the top, and then a panel docked to fill, and in the panel, the grid, also docked/fill.
 
8:20 PM
Okay. I'll fix it later. I'm out for a bit.
 
later!
 
9:20 PM
The panel fixed it @Mat'sMug. Thanks again.
 
9:34 PM
great!
I think you can drop the black border on the grid, too :)
 
transparent ya think?
Just none maybe. =)
 
I have mine as BorderStyle = None
but hey, it's your branch ;)
 
Doesn't quite match the IDE, but I think it looks all right.
 
well it integrates seamlessly, which is F'n awesome!
I'd make the Description column fill all available width
all right, I think I got the Parser class done
time for a first real test!
 
9:53 PM
@Mat'sMug Ummmm.... okay...... I'll see what I can do.
Learning a lot here. lol
Good learning project.
 
it's the coolest project I've worked on in a long, long while!
and I'm going to learn a truckload from your code, too :)
 
I'm hoping you understand it better than I do to be honest.
I get it, but I don't.
It uses CreateToolWindow to create a native window, and then somehow associates it with a host window that takes care of the resizing.
I don't get the details though. It's kind of still magic to me.
I know I don't like how tightly bound the logic is to the control though.... feels dirty.
There will probably be a CR.
 
^^ good idea :)
same here with the Parser code
oh great, NullReferenceException
 
Ugh.
 
lol.. hadn't set the Parser instance
oops, ArgumentException... missing a closing bracket in the Dim regex
now one too many in the Const regex.. I think I'm starting to regret using regex.
 
10:14 PM
The center cannot hold.
Okay buddy. I've had enough for a day. Submitted the pull request. Everything is working nicely. Don't hesitate to submit issues if anything is wonky or broken. Cya soon.
 
10:36 PM
Awesome, later @ducky!
 

« first day (156 days earlier)      last day (3024 days later) »