diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..efb64a6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/_ReSharper.Node.Net/
+/**/bin/
+/**/obj/
+*.user
+*.suo
\ No newline at end of file
diff --git a/IronJS-Tests/IronJS-FS-Tests.csproj b/IronJS-Tests/IronJS-FS-Tests.csproj
index 26fb4fe..1698737 100644
--- a/IronJS-Tests/IronJS-FS-Tests.csproj
+++ b/IronJS-Tests/IronJS-FS-Tests.csproj
@@ -36,12 +36,6 @@
-
-
-
-
-
-
diff --git a/IronJS-Tests/Program.cs b/IronJS-Tests/Program.cs
index 560939f..b305097 100644
--- a/IronJS-Tests/Program.cs
+++ b/IronJS-Tests/Program.cs
@@ -11,8 +11,8 @@ class Program
{
static void Main( string[] args ) {
Server instance = new Server();
- instance.evalCommandlineArgument();
- instance.runEventLoop();
+ instance.EvalCommandlineArgument();
+ instance.RunEventLoop();
}
}
}
diff --git a/IronJS/Node.Net.csproj b/IronJS/Node.Net.csproj
index c4d423e..e2a226b 100644
--- a/IronJS/Node.Net.csproj
+++ b/IronJS/Node.Net.csproj
@@ -44,12 +44,6 @@
..\lib\ironjs-0.2-clr4-x64\IronJS.dll
-
-
-
-
-
-
diff --git a/IronJS/commonjs.cs b/IronJS/commonjs.cs
index a6057d3..0c18f98 100644
--- a/IronJS/commonjs.cs
+++ b/IronJS/commonjs.cs
@@ -1,14 +1,11 @@
-using System;
-using System.IO;
+using System.IO;
using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace Node.Net
{
- class commonjs
+ internal static class CommonJS
{
- public static Stack RequireStack = new Stack();
+ public static readonly Stack RequireStack = new Stack();
/**
* Find a a given js file according to CommonJS search
diff --git a/IronJS/netserver.cs b/IronJS/netserver.cs
index 8ba2d33..88eb5c2 100644
--- a/IronJS/netserver.cs
+++ b/IronJS/netserver.cs
@@ -15,19 +15,19 @@
*/
namespace Node.Net
{
- public class NetStream : IronJS.CommonObject
+ public class NetStream : CommonObject
{
// XXX making stream public to work around incomplete design - fix this
public Stream stream;
// TODO: callbacks will be JS functions, should probably use
// List
- ArrayList dataCallbacks = new ArrayList();
- ArrayList endCallbacks = new ArrayList();
+ readonly ArrayList dataCallbacks = new ArrayList();
+ readonly ArrayList endCallbacks = new ArrayList();
// TODO: this should be defined somewhere else
// Using 1k buffer - experimentally, seems to be what node.js uses
- int bufferSize = 1024;
+ const int bufferSize = 1024;
public NetStream( Stream stream, IronJS.Environment env ) : base( env, env.Maps.Base, env.Prototypes.Object ) {
this.stream = stream;
@@ -52,7 +52,7 @@ public void ReadCallback( IAsyncResult result ) {
if( bytesRead > 0 ) {
// queue work before calling another read, could be out of order otw
- Server.instance.queueWorkItem( new Callback() { name = "stream:raiseDataEvent", callback = raiseDataEvent, args = new object[] { chunk } } );
+ Server.Instance.QueueWorkItem( new Callback { name = "stream:raiseDataEvent", callback = raiseDataEvent, args = new object[] { chunk } } );
byte[] nextBuffer = new byte[ bufferSize ];
this.stream.BeginRead( nextBuffer, 0, bufferSize, ReadCallback, nextBuffer );
}
@@ -61,7 +61,7 @@ public void ReadCallback( IAsyncResult result ) {
// remote end of socket, not sure if raising "end" when there
// is no more data is the right thing to do. It does the right thing
// when using Telnet as the client
- Server.instance.queueWorkItem( new Callback() { name = "stream:raiseEndEvent", callback = raiseEndEvent, args = new object[]{} } );
+ Server.Instance.QueueWorkItem( new Callback { name = "stream:raiseEndEvent", callback = raiseEndEvent, args = new object[]{} } );
}
}
@@ -76,7 +76,7 @@ public void end() {
this.stream.Close();
}
public void addListener( string eventname, IronJS.FunctionObject callback ) {
- Server.instance.Listeners++;
+ Server.Instance.Listeners++;
log.Trace( "NetStream: adding listener: " + eventname );
if( eventname == "data" ) {
dataCallbacks.Add( callback );
@@ -87,11 +87,11 @@ public void addListener( string eventname, IronJS.FunctionObject callback ) {
}
public void removeAllListeners( string eventname ) {
if( eventname == "data" ) {
- Server.instance.Listeners -= dataCallbacks.Count;
+ Server.Instance.Listeners -= dataCallbacks.Count;
dataCallbacks.Clear();
}
else if( eventname == "end" ) {
- Server.instance.Listeners -= endCallbacks.Count;
+ Server.Instance.Listeners -= endCallbacks.Count;
endCallbacks.Clear();
}
}
@@ -129,13 +129,13 @@ public void raiseEndEvent( object[] args ) {
} // class
- public class NetServer : IronJS.CommonObject
+ public class NetServer : CommonObject
{
TcpListener tcpServer;
- ArrayList listeningCallbacks = new ArrayList();
- ArrayList connectionCallbacks = new ArrayList();
- ArrayList closeCallbacks = new ArrayList();
+ readonly ArrayList listeningCallbacks = new ArrayList();
+ readonly ArrayList connectionCallbacks = new ArrayList();
+ readonly ArrayList closeCallbacks = new ArrayList();
public NetServer( IronJS.FunctionObject callback, IronJS.Environment env ) : base( env, env.Maps.Base, env.Prototypes.Object ) {
// have to set this stuff up. not sure why yet
@@ -162,7 +162,7 @@ public CommonObject listen( object in_port, string host ) {
this.tcpServer = new TcpListener( ipAddress, port );
log.Trace( "net.Server.listen(): starting tcp server" );
this.tcpServer.Start();
- Server.instance.queueWorkItem( new Callback { callback = raiseListeningEvent, args = new object[]{} } );
+ Server.Instance.QueueWorkItem( new Callback { callback = raiseListeningEvent, args = new object[]{} } );
this.tcpServer.BeginAcceptTcpClient( listenerCallback, null );
return this;
}
@@ -175,7 +175,7 @@ public void listenerCallback( IAsyncResult result ) {
TcpClient client = this.tcpServer.EndAcceptTcpClient( result );
NetStream stream = new NetStream( client.GetStream(), Env );
- Server.instance.queueWorkItem( new Callback { callback = raiseConnectionEvent, args = new object[]{ stream } } );
+ Server.Instance.QueueWorkItem( new Callback { callback = raiseConnectionEvent, args = new object[]{ stream } } );
// kick off async read
stream.read();
@@ -209,28 +209,28 @@ public void raiseConnectionEvent( object[] args ) {
func.Compiler.compileAs>(func);
fun.Invoke(func, this, stream );
*/
- func.Call( this, stream );
+ func.Call( this, stream );
}
}
public void removeAllListeners( string eventname ) {
if( eventname == "listening" ) {
- Server.instance.Listeners -= listeningCallbacks.Count;
+ Server.Instance.Listeners -= listeningCallbacks.Count;
listeningCallbacks.Clear();
}
else if( eventname == "connection" ) {
- Server.instance.Listeners -= connectionCallbacks.Count;
+ Server.Instance.Listeners -= connectionCallbacks.Count;
connectionCallbacks.Clear();
}
else if( eventname == "close" ) {
- Server.instance.Listeners -= closeCallbacks.Count;
+ Server.Instance.Listeners -= closeCallbacks.Count;
closeCallbacks.Clear();
}
}
public void addListener( string eventname, IronJS.FunctionObject callback) {
log.Trace( "NetServer - adding listener: " + eventname );
- Server.instance.Listeners++;
+ Server.Instance.Listeners++;
if( eventname == "listening" ) {
listeningCallbacks.Add( callback );
}
@@ -248,19 +248,19 @@ public void addListener( string eventname, IronJS.FunctionObject callback) {
// provides the 'net' namespace
// TODO: rename this class
- public class net : IronJS.CommonObject
+ public class net : CommonObject
{
public net( IronJS.Environment env )
: base( env, env.Maps.Base, env.Prototypes.Object ) {
- var objMethod = Utils.createHostFunction>( Env, CreateServer );
+ var objMethod = Utils.createHostFunction>( Env, CreateServer );
log.Trace( objMethod );
this.Put( "createServer", objMethod );
}
- public IronJS.CommonObject CreateServer( IronJS.FunctionObject callback ) {
+ public CommonObject CreateServer( FunctionObject callback ) {
log.Trace( "net.createServer() called." );
- Net.NetServer server = new Net.NetServer( callback, Env );
+ NetServer server = new Net.NetServer( callback, Env );
log.Trace( server );
return ( server );
}
diff --git a/IronJS/server.cs b/IronJS/server.cs
index 0cbce20..7d0d551 100644
--- a/IronJS/server.cs
+++ b/IronJS/server.cs
@@ -8,7 +8,6 @@
using System.Threading;
using System.IO;
-using System.Text;
using System.Collections;
using System.Collections.Generic;
using System;
@@ -21,40 +20,50 @@ public class Server
{
// temp hack global used to access event queue
// by other modules
- public static Server instance;
+ public static Server Instance
+ {
+ get { return instance;}
+ }
+
+ private static readonly Server instance;
// number of registered callbacks active
public int Listeners = 0;
// dispatch queue and signalling primitive for main event loop
- private ManualResetEvent manualResetEvent = new ManualResetEvent( false );
- private Queue workItems = new Queue();
+ private readonly ManualResetEvent manualResetEvent = new ManualResetEvent( false );
+ private readonly Queue workItems = new Queue();
// toplevel JS execution context used for all JS code
- private static IronJS.Hosting.CSharp.Context ctx = new IronJS.Hosting.CSharp.Context();
+ private static readonly IronJS.Hosting.CSharp.Context ctx = new IronJS.Hosting.CSharp.Context();
- private static Node.Net.net netObj = new Net.net( ctx.Environment );
+ private static readonly net netObj = new net( ctx.Environment );
// TODO: re-add after httpserver.cs is converted to IJS 0.2
// private static http httpObj = new http( ctx.Environment );
+ static Server()
+ {
+ instance = new Server();
+ }
+
public static void Main() {
// eval js file given as first commandline arg and
// run the event loop - runEventLoop() always blocks, unlike node.js
// which returns if no more callbacks are registered
- instance = new Server();
- instance.evalCommandlineArgument();
- instance.runEventLoop();
+ Instance.EvalCommandlineArgument();
+ Instance.RunEventLoop();
}
private static List requireStack = new List();
- /**
- * implements require() for importing js files/namespaces
- *
- * file - the literal expression passed to require() in js.
- * Might be abs or rel path + filename.
- */
- public static IronJS.CommonObject Require( string file ) {
+ ///
+ /// Implements require() for importing js files/namespaces
+ ///
+ /// The literal expression passed to require() in js. Might be absolute or relative path + filename.
+ ///
+ /// The contents of the .
+ ///
+ public static CommonObject Require( string file ) {
// TODO: could possibly break this by doing require('undefined');
if( String.IsNullOrWhiteSpace( file ) || String.IsNullOrEmpty( file ) || file == "undefined" ) {
throw new Exception( "invalid file spec passed to require()" );
@@ -71,23 +80,29 @@ public static IronJS.CommonObject Require( string file ) {
}
// otherwise invoke CommonJS search rules
- commonjs.SetRequireStack( file );
+ CommonJS.SetRequireStack( file );
string filename = Path.GetFileName( file );
- FileStream fs;
- string filepath = commonjs.FindFile( filename );
- fs = new FileStream( filepath, FileMode.Open, FileAccess.Read );
-
- string code = new StreamReader( fs ).ReadToEnd();
- // extra semicolon provided after file contents.. just in case
- code = "var exports = {}; " + code + "; exports;";
- IronJS.CommonObject retval = ctx.Execute( code );
- commonjs.RequireStack.Pop();
- return retval;
+ string filepath = CommonJS.FindFile( filename );
+
+ using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read))
+ {
+ string code = new StreamReader(fs).ReadToEnd();
+ // extra semicolon provided after file contents.. just in case
+ code = "var exports = {}; " + code + "; exports;";
+ CommonObject retval = ctx.Execute(code);
+ // This should probably be inside a finally so it's always executed? [asbjornu]
+ CommonJS.RequireStack.Pop();
+ return retval;
+ }
}
- // threadsafe enqueue function
- public void queueWorkItem( object item ) {
+
+ ///
+ /// Threadsafe enqueue function.
+ ///
+ /// The item.
+ public void QueueWorkItem( object item ) {
log.Trace( "queueWorkItem(): queuing item: " + ( ( Callback )item ).name );
log.Trace( "queueWorkItem(): acquiring lock: " + workItems );
Monitor.Enter( workItems );
@@ -102,31 +117,19 @@ public void queueWorkItem( object item ) {
log.Trace( "queueWorkItem: released lock" );
}
}
-
- private string readFile( string filename ) {
- string fileContents;
- StreamReader streamReader = new StreamReader( filename );
- try {
- fileContents = streamReader.ReadToEnd();
- return fileContents;
- }
- finally {
- streamReader.Close();
- }
- }
-
- public void evalCommandlineArgument() {
+
+ public void EvalCommandlineArgument() {
string[] args = System.Environment.GetCommandLineArgs();
if( args.Length != 2 ) {
Console.WriteLine( "usage: node " );
System.Environment.Exit( 1 );
}
// string script = readFile( args[1] );
- commonjs.SetRequireStack( args[ 1 ] );
- ReadJsFile( args[ 1 ] );
+ CommonJS.SetRequireStack( args[ 1 ] );
+ SetupContext( args[ 1 ] );
}
- public void runEventLoop() {
+ public void RunEventLoop() {
while( this.Listeners > 0 ) {
log.Trace( "event loop running" );
Callback callback = null;
@@ -161,43 +164,33 @@ public void runEventLoop() {
} // while
}
- /**
- * This is badly named - really it sets up the
- * global context and then executes the file given
- * on within that context.
- */
- public void ReadJsFile( string in_filename ) {
-
- commonjs.SetRequireStack( in_filename );
+ ///
+ /// Sets up the global context and then executes the file given on within that context.
+ ///
+ /// The name of the file to execute.
+ public void SetupContext( string filename ) {
+ CommonJS.SetRequireStack( filename );
// string pathpart = Path.GetDirectoryName( in_filename );
// path = Directory.GetCurrentDirectory() + pathpart;
// log.Trace( "path of js file: " + path );
var emit =
- Utils.createHostFunction>(
- ctx.Environment, ( obj ) => {
- Console.WriteLine( IronJS.TypeConverter.ToString( obj ) );
- }
- );
- ctx.SetGlobal( "puts", emit );
+ Utils.createHostFunction>(
+ ctx.Environment, obj => Console.WriteLine( TypeConverter.ToString( obj ) ));
+ ctx.SetGlobal( "puts", emit );
- var require =
- Utils.createHostFunction>(
- ctx.Environment, ( obj ) => {
- return Require( obj );
- }
- );
- ctx.SetGlobal( "require", require );
+ var require = Utils.createHostFunction>( ctx.Environment, Require );
+ ctx.SetGlobal( "require", require );
// Forms the `net" namespace
- ctx.SetGlobal( "net", netObj );
+ ctx.SetGlobal( "net", netObj );
// Forms the `http" namespace
// TODO: re-add after httpserver.cs is converted to IJS 0.2
// ctx.SetGlobal( "http", httpObj );
- ctx.ExecuteFile( in_filename );
+ ctx.ExecuteFile( filename );
}
} // class
diff --git a/ironjs-fs/.gitignore b/ironjs-fs/.gitignore
new file mode 100644
index 0000000..460e47d
--- /dev/null
+++ b/ironjs-fs/.gitignore
@@ -0,0 +1,6 @@
+/bin/
+/obj/
+/_ReSharper.Node.Net/
+/*.csproj.user
+/*.suo
+/*.ReSharper.user