« first day (2 days earlier)      last day (3178 days later) » 

00:07
@ckuhn203 it's essentially a function that takes a parameter and returns a bool ;)
And you're right, we'll need to be able to write to the code file.. I think the simpler approach would be to just generate the content
@ckuhn203 I've created a Trello account
and added a Trello user by the name of [ckuhn203] as a member of the organisation that's going to host our board.
I'll make you an admin when you confirm that I've added the right Trello user ;)
00:47
Writing the code file back would be nothing more than traversing the modeled tree structure and calling .ToString() on every single component. At least that's how I'd picture it... at this point ;)
@ckuhn203 looking at the FileHeaderValidatorTests unit tests will help:
    var rules = new[]
        {
            new FileHeaderValidatorCodeFileReader
                .ValidationRule("validation rule", "rule failed.", content => content.Contains("foo"))
        };
this fake validation rule takes the content and returns true (i.e. validation passes) if any of the lines in content say "foo".
the lambda expression is basically a function; stuff at the left of the lambda (=>) is the function's parameter(s), stuff at the right is its body.
so content => content.Contains("foo") takes a parameter called content (that is a string[] per the ValidationRule constructor)
and returns the result of content.Contains("foo"), which is a bool.
you're going to fall in love with lambdas, trust me
01:24
I've created a card per namespace on the trello board, and each card has a "checklist". I think these checklists should be converted into cards.
01:47
using VBEX.Lexer;

namespace VBEX.Parser
{
    public interface ICodeParser
    {
        ICodeFileTree Parse(string[] code);
    }
}
^^ this is where the magic is going to be happening! :)
 
10 hours later…
11:49
I'm assuming I need the 4.5 framework version of Ninject @Mat'sMug?
I didn't know C# supported any kind of functional paradigm. That's pretty cool.
12:13
Oh, if the solution doesn't build because of missing packages, right-click the solution and then "Maanage NuGet Packages..." - from there you're one click away from downloading all the missing stuff at once ;)
Yup. Just figured that out.
Just took a minute. =)
I had to add a solution to get the Parser.Tests to see the VBEX reference, is that right?
Like this.
Sorry if I'm being a total n00b here man.
No prob
What's your folder structure like?
If you open from source control instead, do you need to create a solution?
I did open from control source. I could open the csproj files individually, but they couldn't see each other.
(I thought just syncing would fix that)
There should already be a .sln solution - don't open projects, open the solution (it contains the projects), and then yeah the references should work
I just realized I haven't verified the .sln was in the github repo... is it (it should)
12:35
There's no sln in the repo I cloned.
Seems like you're half a step ahead of me every time I check this window. heh
Ah, that explains it, looks like I f'd up somewhere, hold on..
Ok. gonna go get a cup o' joe.
Ah, I see. I don't know how to fix this though. But you're right there's no solution in the repo. Weird..
Perhaps we should scratch the repo and create a new one, if the initial commit has files in a project and projects in a solution the repo should have everything. Can you do that? I need to put on the daddy hat and take care of my little twins for a while..
12:51
Yeah. I think I've got it.
13:33
I think we're not going to need a DeclarationsSection and a CodeSection abstraction - if ICodeFileTree has an IEnumerable<IMember>, then the declarations section logically contains all the members that aren't properties, procedures or functions..
Yes. I thought we talked about that already?
Two biggest buckets.
I think it can be simplified
Oh. I see what you're getting at now.
Yeah. Ok.
public interface ICodeFileTree
{
    string FileName { get; }
    CodeModuleType ModuleType { get; }
    IIdentifier Identifier { get; }
    IEnumerable<IMember> Members { get; }
}
would this make sense?
    public class Property : IMember
    {
        public AccessModifier Accessibility { get; }
        public IIdentifier Identifier { get; }

        public ICodeBlock PropertyGet { get; }
        public ICodeBlock PropertyLet { get; }
        public ICodeBlock PropertySet { get; }
    }
if PropertyLet and PropertySet are null, the property is get-only.
and the blocks don't eat up another IIdentifier, they all use the same one.
A generic member wouldn't have those. I'm not sure null & read only is the best way to go.
A generic member only has an identifier & content
13:48
IMember only has an Accessibility and an Identifier
public interface IMember
{
    AccessModifier Accessibility { get; }
    IIdentifier Identifier { get; }
}
Oh. d'oh.
public class Property.......
so a constant in the declarations section is a member too
Help if I read closer.
So this lets a single class property get a "hook" on all of it's methods.
Yeah. Makes sense.
I created a branch with a top level solution in it. If you want to take a look when you get a chance.
not sure about ICodeBlock being the appropriate interface here.. hmm let's see, we need a signature here.
Remind me, what are we considering a code block. Yes. It needs a signature.
In my head each of those is a code block.
But I don't think that's how we defined it.
13:52
exactly
what should we call something that contains executable code, that has an identifier and an access modifier, and can have parameters? (i.e. getter/letter/setter/sub/function)
I feel like we're missing a step. Like code block is bigger than we've defined it, but we still need that thing we're calling a code block.
A procedure.
It's a procedrue.
so we'll have a function procedure, a property get procedure, .. right?
I feel like calling the abstraction ICallable
Bingo!
That's good.
that's exactly what it is, callable
yup. I think we got it.
I've gotta go get some chores done while vs updates. bbiab
14:05
Oh and it can have a return value as well.. and this is where our design needs a big decision taken: do we model the type system?
I think a String ReturnTypeName can work for now
Do we really need the actual type? I think ReturnTypeName is ok, but I'm not sure. Truthfully though, I have no idea how we could return an actual type. I think Name is ok.
well if we go all the way with a type system, ...I don't see what's stopping us from implementing a whole freakin' IDE - in other words yeah, would probably be overkill at this point ;)
Valid point. KISS.
The more I think about it, name is more than sufficient for any kind of analysis or update.
14:21
right
Shite... The packages folder got duplicated. I need to fix that.
maybe
..e.g. if we can tell an Integer from a Byte or a Long, then we can verify possible overflow errors.... ...but then we can also just raise a flag if a call is passing a Long into a signature that wants an Integer
like, "Warning: Implicit type conversion"
14:39
I think we're ok.
The slnTest branch looks good. wanna double check it before I merge?
I feel like I'm getting a grip on what you're doing now that I've finally been able to step through the tests. I think.
15:15
Have you seen the selfie answer I posted on CR? I'm hoping to receive good counter-points, deep down I think the decorators are overkill... but they do make everything super easy to test.
I read it, but it's just slightly over my head.
15:31
so..... I have no idea what you're working on, so I'm hesitant to do anything. Ping me when you figure out what you'd like me to work on.
I need to draw stuff and sort out ICallable, I'll update the trello board with new tasks as soon as the interfaces make sense ;)
 
2 hours later…
17:42
Ok I think I got this straight. Let me know what you think:
    /// <summary>
    /// An abstraction representing a member in a code module.
    /// </summary>
    public interface IMember
    {
        /// <summary>
        /// The member's accessibility / scope.
        /// </summary>
        AccessModifier Accessibility { get; }

        /// <summary>
        /// The member's associated identifier.
        /// </summary>
        IIdentifier Identifier { get; }
    }
I might have missed a few here:
public enum AccessModifier
{
    Public,
    Private,
    Friend,
    Global
}
An IIdentifier boils down to a name and a type:
    /// <summary>
    /// An abstraction representing anything with a name and a type.
    /// </summary>
    public interface IIdentifier
    {
        /// <summary>
        /// A string that determines how an identifier is being referred to in code.
        /// </summary>
        string Name { get; }

        /// <summary>
        /// The type associated with the identifier.
        /// </summary>
        /// <remarks>
        /// For a field or a variable identifier, this is the variable's type.
An IVBType is an abstraction representing a type:
    /// <summary>
    /// An abstraction representing a type.
    /// </summary>
    public interface IVBType
    {
        /// <summary>
        /// The exact string representation of the type's name.
        /// </summary>
        string TypeName { get; }

        /// <summary>
        /// True if an identifier of that type must be Set.
        /// </summary>
        bool? IsReference { get; }
    }
So when we process all the code in a VB project, when we come across a Class Module we can create an IVBType implementation on the fly:
    public class ClassReferenceType : IVBType
    {
        private readonly string _typeName;

        public ClassReferenceType(string name)
        {
            _typeName = name;
        }

        public string TypeName { get { return _typeName; } }
        public bool? IsReference { get { return true; } }
    }
The reason why IsReference is nullable (bool? is shorthand notation for Nullable<bool>, is because a Variant could be literally anything:
    public class Variant : IVBType
    {
        public string TypeName { get { return "Variant"; } }
        public bool? IsReference { get { return null; } }
    }
So, an ICallable is an IMember with a signature and some executable code:
    /// <summary>
    /// An abstraction representing a callable member.
    /// </summary>
    public interface ICallable : IMember
    {
        /// <summary>
        /// The member's signature.
        /// </summary>
        ISignature Signature { get; }

        /// <summary>
        /// A tree structure representing the member's body.
        /// </summary>
        IExecutableTree Body { get; }
    }
An ISignature is an abstraction of a callable member's declaration/signature:
    /// <summary>
    /// An abstraction representing a callable member's signature.
    /// </summary>
    public interface ISignature
    {
        /// <summary>
        /// The identifier associated with a member's signature.
        /// </summary>
        /// <remarks>
        /// For an <see cref="IMember"/> implementing <see cref="ICallable"/>,
        /// this reference should be the same as the member's <c>Identifier</c>.
        /// </remarks>
        IIdentifier Identifier { get; }

        /// <summary>
So when we'll create implementations for these interfaces, we'll have to keep in mind that a callable member's identifier is also referenced in its signature.
so I'm here:
    /// <summary>
    /// An abstraction representing an executable sequence of instructions.
    /// </summary>
    public interface IExecutableTree
    {

    }
18:15
The parsing of a code file is going to have to be done in successive passes, a bit like compiling code.
like, first identify the members, then parse the executable content.
ooh this is getting fun!
18:52
I'm committing what I have on my working copy - feel free to review, tweak and question everything I did
 
3 hours later…
21:35
Ugh. PropertyGetter & friends should implement IPropertyAccessor.
 
2 hours later…
23:42
@Mat'sMug Do we just convert the Dim keyword to Private for variables?
For a variable's identifier, once we know it's a variable, we have to remember to default to variant if it's not defined. Should we differentiate between explicit variant and implicit variant?
What you've posted her seems logical. Good catch including the parameters.
I'll take a look at the commit in the morning. I only browsed through what you posted ehre.

« first day (2 days earlier)      last day (3178 days later) »