I have a personal project I am working on in which I want to compile the method and class signatures (but not the implementation logic) of JavaScript files.
I found the solution I’m going to use but not before wandering through a buh-zillion pages on the web and trying a few approaches until I arrived at something which I think will work for what I need. This blog entry is about that wandering.
A JavaScript file for testing
I needed a script file with a class and method in it to use for my tests. There are different ways to create a ‘class’ in JavaScript, but for this test I decided to use the function prototype method generated from Script#.
The C# class:
public class Class1
{
public void DoSomething(int parm1)
{
}
}
The resulting JavaScript:
//! SSGen.debug.js
//
(function() {
////////////////////////////////////////////////////////////////////////////////
// Class1
window.Class1 = function Class1() {
}
Class1.prototype = {
doSomething: function Class1$doSomething(parm1) {
///
///
}
}
Class1.registerClass('Class1');
})();
//! This script was generated using Script# v0.7.4.0
Attempt I – Use the Microsoft.JScript.Vsa.VsaEngine
I found an entry on Rick Strahl’s blog about evaluating JavaScript in C# and although it talks about evaluating JavaScript instead of parsing it, I figured it would be a good place to start.
I wrote this C# test code:
static private void ParseJsWithVsa()
{
string jsPath = @"SSGen.debug.js";
string javaScript = File.ReadAllText(jsPath);
VsaEngine engine = VsaEngine.CreateEngine();
object evalResult = Eval.JScriptEvaluate(javaScript, engine);
}
And got these compilation warnings:

But it it did compile! So I ran it and this was my result:

Okay, well that’ll be easy to fix I thought. I decided to just remove the Window. from line 10 of the JavaScript and try it again with this result:

Arrgh. I guess that the parsing worked without trouble but the actual evaluation failed, I couldn’t find any way to get the parsing results so I decided not to work on this approach any longer. Instead I decided I’d try the ICodeCompiler noted in the compilation warnings above.
Attempt II – Use the ICodeProvider
Here’s the c#:
static private void ParseJsWithICodeCompiler()
{
string jsPath = @"SSGen.debug.js";
JScriptCodeProvider jsProvider = CodeDomProvider.CreateProvider("JScript") as JScriptCodeProvider;
using (TextReader text = File.OpenText(jsPath))
{
CodeCompileUnit ccu = jsProvider.Parse(text);
}
}
Here’s the result:

Oh well. So much for that idea.
Attempt III – Use JSLint
I know that JSLint is a code quality tool but I figured that somewhere down in the mess of JSLint code it’s got to parse the target script and maybe I could hook into it and get the results of the parsing action.
I created a test ASP.Net web site which would show me the results of running JSLint against my test script file.
Here is my ASP.Net site’s markup:
JSLint Parse Tester
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js"></script><script type="text/javascript" src="Scripts/Test.js"></script>
<script type="text/javascript" src="Scripts/JSLint.js"></script></pre>
<form id="form1">
<div>
<h3>Result of calling JSLINT(script);</h3>
<hr />
<h3 id="resultsTitle"></h3>
<div id="results"></div>
</div>
</form>
<pre>
And here is the JavaScript I wrote to execute JSLint against my test script file:
///
///
function OnGetScriptToParseComplete(script)
{
var result = JSLINT(script);
$('#jsLintResult').text(result);
if (result)
{
var tree = JSON.stringify(JSLINT.tree, [
'string', 'arity', 'name', 'first',
'second', 'third', 'block', 'else'
], 4);
tree = tree.replace(/\n/g, "
");
tree = tree.replace(/ /g, " ");
$('#results').html(tree);
$('#resultsTitle').text("JSLINT.tree:");
}
else
{
var errs = JSON.stringify(JSLINT.errors, undefined, 4);
errs = errs.replace(/\n/g, "
");
errs = errs.replace(/ /g, " ");
$('#results').html(errs).css('color', 'red');
$('#resultsTitle').text("JSLINT.errors:");
}
}
$(document).ready(function ()
{
$.ajax({
url: "scripts/ToParse.js",
dataType: 'text',
success: OnGetScriptToParseComplete
});
});
And here are the results:

Before I delved into this approach any further I continued looking online for solutions to parse JavaScript and found something named ANTLR which seemed to be exactly what I needed.
Attempt IV – Use ANTLR
ANTLR is a tool which, among many other things, allows me to generate lexers and parsers in a target language (i.e. C#) to use against a specific grammar.
I’ve been working with ANTLR for a couple of days now, it’s got several ‘pieces’ which must be downloaded, version matched, and fitted together to do what I need but it seems to be the best solution so far. I’ll write more about ANTLR and my project in the next part of this series.