Commit graph

432 commits

Author SHA1 Message Date
joeduffy c3027f6822 Map MuJS interface types to MuIL
This change maps MuJS interface types to MuIL, including property and
method declarations.  The mapping is fairly straightforward, and similar
to the existing class lowering, except for some minor AST differences in
the TypeScript representations.  We emit interface types as classes with
the interface bit set, and all method declarations being abstract.
2017-01-12 12:12:29 -08:00
joeduffy 069ab369e9 Improve line-by-line error reporting in test failures
This change improves the line-by-line error reports when a test fails,
both in the diagnostics messages and AST tree baseline comparisons.
Previously, the test would fail at the first occurrence of a mismatch,
often with little information about the context.  In this change, the
test will now fail with a full dump of the comparison.

For instance, here is the before for a test failure in a new case I'm adding:

     AssertionError: Expected tree line #1 to match
           + expected - actual

                 -     "name": "iface_1",
                 +     "name": "class_1",

In comparison, here is what the test failure looks like now:

      AssertionError: Expected trees to match; 6 did not
      + expected - actual

      -1:     "name": "iface_1",
      -10:                 "I": {
      -14:                         "ident": "I",
      -19:                                 "column": 10
      -23:                                 "column": 11
      -29:                     "interface": true,
      +1:     "name": "class_1",
      +10:                 "C": {
      +14:                         "ident": "C",
      +19:                                 "column": 6
      +23:                                 "column": 7
      +29:                     "abstract": false,
2017-01-12 12:06:15 -08:00
joeduffy 3f81e2f15f Add proper errors for Mufile validation 2017-01-12 08:10:43 -08:00
joeduffy a93841dab2 Add real diagnostics
This change adds a set of true diagnostics constructs, underneath the
new `diag` module.

This includes projecting Mu-specific errors as real diagnostics in a
way that is unified with TypeScript errors.  The only difference, of
course, is that Mu errors tend to happen in later passes.  But this is
not necessarily always the case.

As part of this, I've rearranged the compiler passes to present a
simpler interface to users of the compiler API (currently just the CLI
and test harness, but it's just a library, so anybody can use it).

Namely, there are three phases:

    1. Compilation is the overall process of taking an input path
       and driving the entire compilation process, yielding a set of
       diagnostics and, ideally, a final MuPackage at the end of it.

    2. Script compilation is the process of driving the front-end
       compiler -- in this case TypeScript -- yielding a set of Mu
       diagnostics and, if that went well, the script's AST.

    3. Transformation is the process of taking the script output and
       lowering it into the final MuPackage form.

Most people will deal with 1, blissfully unaware of the presence of
independent 2 and 3 phases.  We choose to keep them distinct for
white box testing and for future scenarios we have yet to envision.
2017-01-11 12:11:46 -08:00
joeduffy b3247a37cd Ensure locations are propagated everywhere
There were a few places where we didn't propagage source locations
correctly.  This fixes that.  Part of the issue was we didn't have
good helper methods to propagate "ranges" (e.g., a sequence of
statements or expressions), so this change adds those.

This change also establishes a new naming convention; the addLocation*
methods adds a newly allocated location based on translating a TypeScript
AST node, whereas the copyLocation* methods copy them directly from
other MuIL nodes.  Thus, there are now four methods: addLocation,
addLocationRange, copyLocation, and copyLocationRange.
2017-01-11 08:31:03 -08:00
joeduffy 6c3826659c Map call expressions 2017-01-11 08:17:13 -08:00
joeduffy 2d5ec61aeb Map new expressions
This change adds a new AST node kind to represent "new" expressions.
Originally I had thought we could simply represent these as calls to
a constructor, however, there is a sizeable semantic difference and so
it's better for this node kind to be distinct; for example, we will
most likely permit allocation of objects without explicit constructors.

In addition, I've added a "complex" scenario test, which is just a
Point class.  It has a constructor, two properties, and an instance
method that performs arithmetic and allocates a new instance.  It works!
2017-01-11 08:06:11 -08:00
joeduffy 00e0c00ac9 Fix "this" capture in callbacks 2017-01-11 07:50:31 -08:00
joeduffy c964a0fa8d Use explicit type coercions
This uses explicit type coercions when creating interface types with
object literals.  This helps the compiler catch some additional errors,
such as mistyped property names (of which we had two instances, for
load location expressions ("key" vs "name")).
2017-01-11 07:43:00 -08:00
joeduffy 86a67869af Map property access expressions 2017-01-11 07:38:51 -08:00
joeduffy f413b1d2db Add basic class property mapping 2017-01-11 07:25:22 -08:00
joeduffy dbce1d5170 Rearrange some VariableLike and FunctionLike code sharing
The old way we shared code between VariableLike and FunctionLike cases --
across module, class, and locals -- was slightly confusing, and required a
lot of dynamic object property copying, etc.  This change is a little bit
easier on the eyes, correctly handles variable initializers more uniformly,
and prepares us for class properties (the next change to land).
2017-01-11 07:16:56 -08:00
joeduffy 7db6f12d6f Translate member access expressions
This change maps MuJS access expressions to the MuPack/MuIL forms.

As part of this, I've changed the representation in the AST.  It doesn't
make much sense to distinguish between variable, member, and function access.
Instead, all accesses will be uniform, and will evaluate to the proper type.
2017-01-10 16:39:50 -08:00
joeduffy 82657c7cdb Add basic class lowering
This change introduces basic class lowering into MuPack/MuIL.  There are
a handful of things not yet supported (like extends/implements and properties),
however, simple methods and variables are supported.
2017-01-10 16:13:28 -08:00
joeduffy fc1899e1ee Translate and lower function definitions
This change introduces lowering for function definitions and parameters.
This includes a few tests for both exported and unexported module-level
function definitions.  Class members will come shortly...
2017-01-10 15:29:14 -08:00
joeduffy 780d3d31b1 Emit accessibility in module properties
This change properly retains and emits the desired accessibility for
module properties, based on whether a property has been exported or not.
It also updates the existing export property test baseline and adds
another one for unexported module properties.
2017-01-10 14:41:52 -08:00
joeduffy 3c1fdf6d88 Use relative paths in AST source location
This change uses paths relative to the compilation root context path,
so that they aren't absolute and therefore aren't tied to a specific
machine.  This fixes marapongo/mu#42, and cleans up our test baselines.
2017-01-10 14:34:46 -08:00
joeduffy 35fce68e37 Refactor transformation into a class
The transformation now needs some context information throughout its
execution, so it makes sense to turn it into a class.
2017-01-10 14:27:26 -08:00
joeduffy aa51bda2d0 Shorten module names
Per marapongo/mu#42, this change shortens module names to be more "Mu-like"
and to reflect the relative module paths.  There is still awkwardness if there
are any "up and over" references, i.e. using "..", but this handles the 95%
case.  We still don't mark entrypoints, but this gets us one step closer.
2017-01-10 13:55:07 -08:00
joeduffy 4ed118e8fa Add basic Mu metadata parsing support
This change adds discovery of Mu metadata in the form of a Mu.json file.
This allows us to eliminate the "TODO" in place of a real package name in
the output ASTs, so our baselines are adjusted accordingly.  This is part
of marapongo/mu#42 -- implementation of real module and package names.
2017-01-10 12:42:42 -08:00
joeduffy 57e8a6aa67 Do a line-by-line comparison for AST checking
This changes the test harness to do a line-by-line comparison, rather than
full text comparison, for AST checking.  This is a bit nicer to diagnose, because
failures will specifically point out the line that deviates, rather than dumping
the (possibly huge) string containing the full expected/actual ASTs.
2017-01-10 12:40:59 -08:00
joeduffy f2f6826f5b Add a test for exporting a module property 2017-01-10 08:20:01 -08:00
joeduffy 7017828ae5 Add a baseline for the empty test
This adds a baseline for the empty module test, and it passes.
Unfortunately, because module names are absolute file paths, this
baseline file has my machine's specific path embedded in it.  I want
to lock these in so they are passing as I make progress.  Sometime
later this morning I'll fix the module naming to be "relative" and
more Mu-friendly, and this issue will go away.
2017-01-10 08:15:34 -08:00
joeduffy a2b02381fc Use the module's fileName as its name
For now we will use the module's fileName as its name.  This matches
the ECMAScript semantics, however, we will eventually want to do a pass
to normalize these names into more "Mu-friendly" module names.
2017-01-10 08:14:02 -08:00
joeduffy 641fb5bd21 Fix a few TSLint errors 2017-01-10 08:13:39 -08:00
joeduffy 27eef9903b Use JSON object maps instead of ES6 Maps
This change uses JSON object maps in the AST, rather than ES6 Maps,
so that the resulting data structure is easily serializable.
2017-01-10 07:57:22 -08:00
joeduffy 62e11f37e0 Rename formats doc to languages 2017-01-10 07:32:01 -08:00
joeduffy 2669f5b860 Lower identifiers
This changes the way we represent identifiers slightly, and then lowers
the TypeScript representation to them.  Prior to this change, identifiers
could be naked strings; after this change, identifiers are always first class
AST nodes -- so they can carry location information -- and tokens assume the
role of naked strings.  This means some definition maps must now be keyed by
tokens and also means that some AST node properties that used to carry just
naked strings needed to be updated to carry first class AST nodes.
2017-01-10 07:21:03 -08:00
joeduffy 478d1c3173 Handle unexported top-level variables
This change rearranges some logic to properly handle both exported and
unexported top-level module properties (variables).
2017-01-10 07:07:36 -08:00
joeduffy 972842b687 Implement variable declaration lowering
This is an initial cut at implementing variable declaration lowering.

The lowering is slightly different for module properties and local variables,
since the former requires that code go into the module initializer, while the
latter can mostly happen "inline" as the local variable is bound.

There are some incomplete parts in here -- like lowering type names -- that
are dependent on a few upcoming changes.
2017-01-10 08:33:41 -06:00
joeduffy 1d1e11bb13 Project MuJS modules into MuPack/MuIL metadata
This change translates MuJS modules and their various top-level statements
into the corresponding MuPack/MuIL metadata.  Notably, to ensure static analyzability,
MuIL doesn't permit arbitrary class, function, etc. definitions as statements.  Instead,
they must occur at the top-level, and be recognized as such statically.  That's the bulk
of this change.  The individual nodes aren't necessarily mapped yet, however.
2017-01-09 21:20:19 -06:00
joeduffy 9cb9b4eed8 Export a top-level list of modules
The way ECMAScript and Python work is that each file maps to a module.  There
isn't really an "official" notion of a submodule; instead, directories on the
import path are conventionally used as submodule names.  Aggregate submodules
can be achieved by convention with re-exports in ECMAScript, however this is an
informal notion.  We could keep the current structured submodule notion and require
that all languages map to it, however, it is just as easy to have a flat list of
top-level modules indexed by name.  This change rearranges the AST accordingly.
2017-01-08 16:20:19 -06:00
joeduffy 094d0aa6e0 Add a handy executable wrapper for MuJS 2017-01-08 15:34:10 -06:00
joeduffy 89f2424df1 Add a new harness for test cases
This adds a new test harness that will be used to run baseline-style
tests.  Each subdirectory underneath tests/output will be interpreted as
a test case, each of which can contain an optional `messages.txt` file
which will be compared as the expected output against the compiler's error
and warning messages, and/or an optional `Mu.out.json` file which will be
compared as the expected output against the compiler's output tree.

There's just a single "empty" test case for now.  I will start getting in
the habit of checking in a companion test for each AST kind we lower.
2017-01-08 15:20:46 -06:00
joeduffy 2eaff6a316 Implement unary operator lowering 2017-01-08 10:13:15 -06:00
joeduffy 7873ce0874 Add a note about exceptions vs fail-fast 2017-01-08 07:47:12 -06:00
joeduffy d36a522c33 Mention we want to lock down SSH by default
Also, add a link to marapongo/mu#33.
2017-01-08 07:31:59 -06:00
joeduffy a4f68abafb Add more details on pinned versions 2017-01-08 07:27:12 -06:00
joeduffy 92dd19d98a Add new AST node types to MuPack doc 2017-01-03 04:14:56 -08:00
joeduffy f2e70c6222 Map binary operators during lowering 2017-01-03 04:14:37 -08:00
joeduffy 2d5a81e350 Add a note about the need to figure out string functions 2017-01-03 03:56:15 -08:00
joeduffy 0979c0c165 Add IsInst and TypeOf expressions
This adds two expressions we will need to support many type test patterns.

IsInst simply checks an expression for castability to a target type; it evaluates
to a boolean.

TypeOf fetches the runtime type of a given expression and evaluates to its name.
Right now, this is just a string token, rather than some richer RTTI object.
2017-01-03 03:48:28 -08:00
joeduffy bebc952998 Add a note on dependency pinning 2017-01-03 03:41:41 -08:00
joeduffy ca124ea3a6 Add more AST lowerings for trivial kinds
This includes AST lowering for DebuggerStatements and ConditionalExpressions,
both of which are straightforward boilerplate mappings.
2017-01-02 16:44:51 -08:00
joeduffy e8e031f97c Map a few more trivial AST kinds
This is mostly boilerplate, mapping the following AST kinds: IfStatement,
ReturnStatement, ThrowStatement, Block, EmptyStatement, ExpressionStatement,
and LabeledStatement.
2017-01-02 16:33:31 -08:00
joeduffy 25c321e5f6 Fix a few random typos I noticed 2017-01-02 16:26:19 -08:00
joeduffy 41323c1dc7 Reorder some things 2017-01-01 18:34:31 -08:00
joeduffy c403f9b444 Nit, shorten the ridiculously lengthy title 2017-01-01 18:33:28 -08:00
joeduffy 17a0f62f8d Add a few tidbits, include an AST shape snapshot in MuIL section 2017-01-01 18:29:07 -08:00
joeduffy 78b2adc9fe Overhaul the stacks.md design document
The stacks.md document used to describe the metadata format.  Now that we've
moved away from the old model of YAML + Go templates, and created the MuPack/MuIL
format, this document needed to be overhauled.

It's pretty bare bones now, however it will eventually evolve into a document
describing how the Mu abstractions map down onto MuPack/MuIL concepts.  For example,
it describes how subclassing mu.Stack creates a "stack", even though at the MuPack/MuIL
level it's just any old subclass.
2017-01-01 18:06:03 -08:00