Skip to content
kswoll edited this page Jan 31, 2014 · 7 revisions

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.

  1. All methods with yield statements are compiled into iterator classes that implement IEnumerable and IEnumerator (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.

  2. All expressions that instantiate new anonymous types are discovered. Their (distinct) types are compiled into Javascript.

  3. 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 this to spontaneously be the window object.

  • 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.Assembly instance representing the assembly when using either typeof(T) or AppDomain.CurrentDomain.GetAssemblies(). This includes all the assembly level attributes you may have in your AssemblyInfo.cs file 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.

Clone this wiki locally