Understanding Script#

This page describes how the Script# system works, what is provided in addition to the compiler, and how to use it for your own project.



Script# works by converting C# source directly into JavaScript (instead of MSIL like the regular C# compiler). In order to do so, it parses your C# code like a real C# compiler. In addition to your .cs source files, it consumes a set of reference assemblies that contain metadata about namespaces and types representing existing script APIs like the DOM or JavaScript or existing script libraries that you are importing to use while writing your own code. The assumption is that these assemblies have corresponding JavaScript files you will include into your deployed Web application, along with your generated script code. In addition to the Script# compiler, you can also run the regular C# compiler to both validate your C# code and also, to generate an assembly that can be in turn used as a reference in a future project if needed. In fact, the Script# compiler assumes that you will compile your code through the C# compiler to ensure it is valid C# code. The diagram above does not depict this for simplicity, but the Script# compiler also consumes .resx files for the purposes of generating localized script files, and it also consumes XML doc-comments produced by the C# compiler to generate script documentation.

When authoring code to be compiled into JavaScript it is important to reference the sscorlib.dll instead of the regular mscorlib.dll that C# projects ordinarily do. sscorlib.dll provides the definition of key .NET types such as System.Object, primitive types, as well as other core BCL types. However the definition of these standard types have been changed ever so slightly to match exactly what the script engine provides at runtime. Note that a C# project can avoid depending on mscorlib.dll using the /nostdlib option on the command line call to csc.exe and by setting the NoStdLib property to True in the .csproj project file. The Script# install provides appropriate project templates with the right project settings to get you started without having to worry about this.

The Script# System

Logically speaking there are three layers to Script# system: the compiler, the core runtime, and the framework.

The Script# compiler compiles the C# code into JavaScript. The compiled script builds on top of a type system that simulates various OOP constructs.

The Script# runtime is provided in the form of sscorlib.dll which must be referenced by every C# project that will be compiled to script. Its equivalent script file, sscorlib.js must be referenced by Web applications when deployed. This core runtime defines the type system that the compiler generates code against. The runtime also extends the core set of JavaScript types such as String, Number, Date etc. so that they provide key APIs that model what the C# or .NET programmer would expect.

The Script# Framework provides higher level application framework and abstractions that make application authoring more productive, and provides a way for structuring UI code and attaching functionality to the HTML DOM in more robust manner. The Script# framework provides a layered system of assemblies and associated script files. The Script# core framework provides an Application class, base classes for writing controls and behaviors to attach to the HTML DOM, a networking stack to issue Web requests, JSON and JSONP support, Reflection capabilities, and higher level UI widgets such as an AutoComplete behavior and other form controls.

The compiler is completely decoupled from the Script# framework. Hence the framework is optional. You may decide to use it or you may not. You can also build an alternative framework that provides its own set of patterns, if you have an alternate design, or have specific unique requirements.

Using Script#

Script# can be used either via the command-line or via MSBuild (the preferred approach).

The Script# compiler can be invoked via ssc.exe (run ssc.exe -? for help on options).

When you install Script#, a number of project templates to create Script# are installed. These projects are based on msbuild .csproj files, and invoke Script# via an MSBuild task in the post-compile event (i.e. once the C# compiler has compiled your C# source into a .dll and validated the source code).

Limitations

C# Limitations
Script# is not intended to take an arbitrary existing C# application, and convert it to script to run within the browser. It does not attempt to provide a script implementation for the full .NET framework (eg. things like Windows Forms or the entire BCL). Doing so would not be practical or scale to the runtime scripting environment. Script# targets a subset of the C# 2.0 language as implemented in .NET Framework 2.0. The idea is that Script# is very much about script development, but in a manner that benefits from an overall better tooling and authoring support. As such, for the most part the limitations listed here have little impact in real Ajax scenarios. The following are the set of unsupported C# constructs:

  • All types must belong to a namespace. Nested types are not allowed.
  • Nested namespace declarations are not allowed. Instead you must declare the whole namespace name in a single namespace statement.
  • The "System" namespace can only be used for imported types representing native scriptable objects or existing script types.
  • The set of reserved words that cannot be used in Script# include not only C# reserved words, but also JavaScript’s reserved keywords.
  • Struct types are disallowed, as script does not have value-type semantics.
  • Pointer types are also disallowed.
  • Method and constructor overloads are not supported except in imported types. Overloading to produce alternate signatures is allowed.
  • Destructors, operators and object conversion are not supported.
  • Enumeration fields must have an explicit value.
  • Set-only properties are not supported.
  • "new" modifiers are not supported on members.
  • Throw statements must be associated with an explicit object.
  • Unsupported statements: goto, using scope statement, lock/unlock, and yield.
  • Unsupported expressions: sizeof, fixed, stackalloc, and default value.
In addition there are a set of limitations in the current implementation that will hopefully be supported in future builds:
  • You cannot specify namespaced-qualified type names either. As a workaround you can use aliases (eg. using Foo = SomeNamespace.SomeType;) if you have type name conflicts you are trying to disambiguate.
  • Generics
  • Support for ref, out and params modifiers on parameters

JavaScript Limitations
Script# provides support for the majority of JavaScript constructs needed to write real world applications and frameworks. It does however have some limitations, and some small differences in the authoring model as a result of being grounded in C# and OOP.

  • Limited support for closures
    Closures are used for a few scenarios. They may be used to define classes, and implement encapsulation of member variables and implementation private to the class. They are also used to implement callback methods, which have access to data/variables present in the outer scope. While Script# supports the second scenario using anonymous delegates, the first scenario is not supported. The generated types do not use closures as their implementation. Instead Script# types are implemented using the more natural JavaScript prototype-based model.
  • Functional Programming
    Script# provides an OOP-style using C#, and hence does not provide a more functional style of programming that can otherwise be used when working with JavaScript. Script# does support functional programming such as array comprehensions using delegates as a mechanism to represent functions that can be passed as parameters to various APIs.
  • Identifier Characters
    JavaScript allows the use of "$" within an identifier. This is not supported in C#. In fact the generator makes use of “$” in generated identifier names to ensure they do not conflict with your own identifiers.

Google
   

Script#

Script# compiles C# source code into JavaScript and brings the power and productivity of C# and .NET tools to Ajax development.

Latest Release (Version 0.5.0.0)