-
Notifications
You must be signed in to change notification settings - Fork 21
Technical Design
WootzJs is built using Roslyn, Microsoft's managed compiler that represents the future of the C# compiler. This means we get to enjoy an always up-to-date parser that performs what is by far the most difficult task for creating a C# to Javascript cross-compiler -- converting a C# project into a fully symbolicated suite of syntax trees.
###Transformation### The transformation process is multiphase.
-
All methods with
yieldstatements are compiled into iterator classes that implementIEnumerableandIEnumerator(and their generic versions if that's what the method returns). This is implemented using a state machine roughly similar to the output of the normal C# compiler. -
All expressions that instantiate new anonymous types are discovered. Their (distinct) types are compiled into Javascript.
-
Each type in the assembly is compiled using a visitor that knows how to convert every (applicable) C# syntax type into Javascript.
###Javascript Composition###
Each C# project is compiled into a single output .js file. The file is composed of several key parts:
-
Strict Mode - The first line of the file is always:
"use strict";Strict mode makes errors easier to reason about, if for no other reason than that you never want
thisto spontaneously be thewindowobject. -
The next chunk defines the assembly related data. In particular, it creates an array to store all the type functions in the assembly. Also, it creates a function that will lazily create the
System.Reflection.Assemblyinstance representing the assembly when using eithertypeof(T)orAppDomain.CurrentDomain.GetAssemblies(). This includes all the assembly level attributes you may have in yourAssemblyInfo.csfile or elsewhere. -
The next section declares all the namespaces defined in your assembly. For example, if you have a namespace such as
namespace MyProduct.MyNamespace { ... }, the compiler will generate:window.MyProduct = window.MyProduct || {}; MyProduct.MyNamespace = MyProduct.MyNamespace || {};The namespace objects are created using
||because assemblies often have at least portions of their namespaces that would otherwise collide with those in other assemblies. -
Finally, each type is sorted based on their dependency graph so that types with few dependencies (such as those that implicitly or explicitly derive from
object) are placed before types with many dependencies. This ensures that a type's dependencies always come first.