scala-js/scala-js — pull request #493 by sjrd (2014-04-19 16:32:38+00:00)
Title: New IR 1st review

**DO NOT MERGE AS IS** (obviously)

This PR should clearly not be merged as is (at the very least, all the commits should be squashed and given a proper commit message). The individual commits are not important; only the diff is interesting.

This new IR is meant to be an interchange format between the compiler and the packager and optimizers (instead of raw JavaScript code), so that inlining will eventually be possible. In this PR, though, it simply replaces the JS Trees as an intermediate representation in the compiler: the compiler emits the IR and immediately desugars it in the JavaScript subset, which is emitted as source code as before.

Some highlights of the IR compared to JS trees:

First things to know:
* The IR represents Scala.js classes independent of an encoding (so the variable `ScalaJS` and its fields are never in the IR)
* It is statically typed, with an additional `dyn` type.

Types (in `ir/Types.scala`):
* They are essentially JVM types with only `int` and `double` for numerics, with an additional Nothing and Null type, and an additional `dyn` type which is a dynamically typed value.
* All raw JS values are always typed as `dyn` (or `any` if upcast).
* Nothing is typed as `java_lang_Object` because it is always replaced by `any`.
* The primitive types do not admit `null` as a value of their type. All `ClassType`s and `ArrayType`s admit `null` (but not `undefined`).

Trees (in `ir/Trees.scala`):
* They basically *are* the IR.
* Classes, hijacked classes, modules, interfaces, raw JS types and trait impl classes are first-class in the IR as instances of the `ClassDef` node.
* Classes (including module classes but excluding hijacked classes) can have fields, methods, properties, and exported constructors/modules. They do *not* have a constructor (the constructor is implied to be a call to super + creating the fields).
* Operations on Scala values (statically typed, with DCE and inlining possible) are separated from operations on JavaScript values (those start with `JS`, e.g., `JSBinaryOp`, and apply only to primitive types and `dyn` types, never on class types or array types, with the exception of `===` and `!==` which take `any`'s).
* `JSApply` always takes an arbitrary number of `any` parameters, and returns a `dyn`.

I believe that should get the reader started on understanding it. I can expand if necessary.