private void EmitMethod(DeclarationEmitContext dgc, string id, IEnumerable<ParameterSyntax> parameters, SyntaxNode body) { var ltype = dgc.LType; var qname = ltype.ID + "." + id; TraceEmit(" method '{0}' ...", id); var rtype = ltype.RType; var ps = TranslateMethodParameters(parameters); var jsw = new JScriptWriter(); jsw.Write(GetPrototypeClause(ltype, id) + " = function(" + ps + ")"); // method context var context = ModuleFactory.CreateMethodContext((IDeclarationContext)ltype); // CS to JS rewriter using the method context. var rewriter = CreateRewriter(dgc, context); // parameter variables rewriter.AddMethodParameters(parameters); if (null == body) { Trace("WARNING: method " + id + " has no body."); return; } // convert the method body var node = rewriter.Visit(body); // prefix with the 'this' replacement node = AddLambdaThis(node); // and emit the JS method declaration jsw.WriteLine(node.ToString()); dgc.Writer.Write(jsw); }
private void EmitConstructorFields(DeclarationEmitContext dgc, CSharpToJScriptRewriter rewriter, JScriptWriter jsw) { var info = dgc.LType; var rtype = info.RType; var cls = dgc.Source.ClassDeclaration; // emit class member fields (LN4NL4H5PI) foreach (var fielddecl in cls.ChildNodes().OfType<FieldDeclarationSyntax>()) { foreach (var declarator in fielddecl.DescendantNodes().OfType<VariableDeclaratorSyntax>()) { var id = declarator.Identifier.ToString(); if (null != rtype) { var field = rtype.GetField(id, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (null != field && field.IsStatic) { continue; } } // identifier, prepend 'this'. //var idsyntax = SyntaxFactory.IdentifierName(declarator.Identifier); var idsyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName(Settings.OuterThis), SyntaxFactory.IdentifierName(declarator.Identifier) ); var idnode = rewriter.Visit(idsyntax); jsw.Write(idnode.ToString()); var equals = declarator.ChildNodes().FirstOrDefault(); if (null != equals) { var node = rewriter.Visit(equals); jsw.Write(node.ToString()); } else { jsw.Write(" = null"); } jsw.WriteLine(";"); } } // event objects (LMGMELDMQ7) foreach (var ev in cls.Members.OfType<EventFieldDeclarationSyntax>()) { foreach (var v in ev.Declaration.Variables) { // initialize event object to null, as in C# var id = Settings.OuterThis + "." + v.Identifier; jsw.WriteLine(id + " = null;"); jsw.WriteLine("this.add_" + v.Identifier + " = function(h) {"); jsw.WriteLine(id + " = Delegate.Combine(" + id + ", h); };"); jsw.WriteLine("this.remove_" + v.Identifier + " = function(h) {"); jsw.WriteLine(id + " = Delegate.Remove(" + id + ", h); };"); jsw.WriteLine("this.fire_" + v.Identifier + " = function(sender, e) {"); jsw.WriteLine("Delegate.Fire(" + id + ", sender, e); };"); } } // constructor var constructor = cls.Members.OfType<ConstructorDeclarationSyntax>().FirstOrDefault(); if (null != constructor) { foreach (var stmt in constructor.Body.Statements) { var ctor = rewriter.Visit(stmt); // ctor = AddLambdaThis(ctor); jsw.Write(ctor.ToString()); } } }
private void EmitConstructor(DeclarationEmitContext dgc, IEnumerable<string> autoprops) { var ltype = dgc.LType; var rtype = ltype.RType; var typename = ltype.CodeName; var declctx = (IDeclarationContext)ltype; // method context for constructor var context = ModuleFactory.CreateMethodContext(declctx); // rewriter var rewriter = CreateRewriter(dgc, context); // writer receiving constructor and related code. JScriptWriter jsw = new JScriptWriter(); // initialize the prototype string basename = null; if (null != ltype.BaseType) { if (null != ltype.BaseType.RType) { basename = ltype.BaseType.CodeName; jsw.WriteLine(typename + ".prototype = new " + basename + "();"); jsw.WriteLine(typename + ".prototype.constructor = " + typename + ";"); } } // static EmitStaticInitializer(dgc, jsw); // analyze constructors ... var cls = dgc.Source.ClassDeclaration; var constructors = cls.Members.OfType<ConstructorDeclarationSyntax>(); if (constructors.Count() > 1) { throw new Exception("multiple constructors are not supported [" + typename + "]."); } var constructor = constructors.FirstOrDefault(); var ps = string.Empty; if (null != constructor) { var parameters = constructor.ParameterList.ChildNodes().OfType<ParameterSyntax>(); rewriter.AddMethodParameters(parameters); ps = TranslateMethodParameters(parameters); } // constructor method jsw.WriteLine("function " + typename + "(" + ps + ")"); jsw.EnterBlock(); // call base constructor if (null != basename) { jsw.WriteLine(basename + ".prototype.constructor.call(this);"); } // type identifier jsw.WriteLine("this.$type = '" + typename + "';"); // initialize our 'this' replacement. var cthis = CreateLambdaThis(); jsw.Write(cthis.ToString()); foreach (var ap in autoprops) { jsw.Write(Settings.OuterThis + "." + DeriveAutomaticName(ap) + " = null;"); } foreach (var dp in dgc.DependencyPropertyInitializations) { // TODO: constant management required. //var dvalue = dp.DefaultMetadata.DefaultValue; object dvalue = null; if (null == dvalue) { jsw.Write(Settings.OuterThis + ".InitValue(\"" + dp.Name + "\");"); } else { jsw.Write(Settings.OuterThis + ".InitValue(\"" + dp.Name + "\", " + dvalue + ");"); } } // field initializers and constructor body ... EmitConstructorFields(dgc, rewriter, jsw); jsw.LeaveBlock(); // commit to class output dgc.Writer.Write(jsw); }
private void EmitStaticInitializer(DeclarationEmitContext dgc, JScriptWriter staticinit) { var cls = dgc.Source.ClassDeclaration; var ltype = dgc.LType; var typename = ltype.CodeName; var rtype = ltype.RType; staticinit.WriteLine(typename + ".prototype.$static = "); staticinit.EnterBlock(); if (null != ltype.BaseType) { staticinit.WriteLine("BaseClass: \"" + ltype.BaseType.CodeName + "\","); } var dplist = new List<DependencyProperty>(); // emit static variables foreach (var fielddecl in cls.ChildNodes().OfType<FieldDeclarationSyntax>()) { foreach (var declarator in fielddecl.DescendantNodes().OfType<VariableDeclaratorSyntax>()) { var id = declarator.Identifier.ToString(); var field = rtype.GetField(id, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (null != field && field.IsStatic) { if (field.FieldType == typeof(DependencyProperty)) { var dp = field.GetValue(null) as DependencyProperty; if (null == dp) continue; dplist.Add(dp); } } } } EmitDependencyPropertyDefinitions(staticinit, dplist); staticinit.LeaveBlock(); staticinit.WriteLine(";"); }
private void EmitDependencyPropertyDefinitions(JScriptWriter jsw, List<DependencyProperty> dplist) { foreach (var dp in dplist) { var dptype = dp.PropertyType; var ldptype = _context.TranslateRType(dptype, TranslateOptions.MustExist); var convert = ldptype.GetConvertMethod(); jsw.Write(dp.Name + "Property:"); jsw.EnterBlock(); jsw.WriteLine("Type: \"" + ldptype.ID + "\","); if (null != convert) { jsw.WriteLine("Convert: function(p) { return " + convert.ID + "(p); },"); } jsw.LeaveBlock(); jsw.WriteLine(","); } }
private void EmitNativeScript(IScriptReference script) { using (var s = script.Assembly.GetManifestResourceStream(script.Key)) { if (null == s) { Log.Warning("native script '{0}' was not found.", script.Key); } else { if (Log.ShowScripts || Log.ShowCodeGeneration) { Log.Trace(" inline script '{0}' ...", script.Path); } var jsw = new JScriptWriter(); using (var reader = new StreamReader(s)) { jsw.WriteLine(reader.ReadToEnd()); } RewriteDeclaration(jsw); } } }
private void EmitScript(XmlWriter writer) { EmitScriptIncludesBefore(writer); var code = new JScriptWriter(); code.WriteLine(); code.WriteLine("// generated"); code.Write(_scriptincludes); code.Write(Declarations); // consumed, more to come ... // resize handler function (unused currently) code.WriteLine("function docResized() "); code.EnterBlock(); code.WriteLine("ResizeManager_Initialize();"); code.Write(_resizebuilder); code.LeaveBlock(); // bindings initialization code.WriteLine(); code.WriteLine("function Bindings_Initialize() "); code.EnterBlock(); code.WriteLine("if(window['BindingObject'] !== undefined)"); code.EnterBlock(); code.Write(CodeBuilder); code.LeaveBlock(); code.LeaveBlock(); // primary document ready handler code.WriteLine(); code.WriteLine("docReady(function() "); code.EnterBlock(); code.WriteLine("DataContext_Initialize(function() { Bindings_Initialize(); });"); code.WriteLine("docResized();"); code.WriteLine("DragDrop_Initialize();"); code.LeaveBlock(); code.WriteLine(");"); // TraceTarget.Trace("jscript code in HTML:\n{0}\n\n", code.Text); writer.WriteStartElement("script"); if (!IsOptimized) { writer.WriteRaw(code.Text); } else { Information("generating optimized code ..."); var builder = new JScriptBuilder(); builder.SuppressedGlobalFunctions.Add("trace"); builder.RewriteProgram(code); writer.WriteRaw(builder.Text); } writer.WriteEndElement(); // application specific initializer scripts ... _scriptincludes = new JScriptBuilder(); EmitScriptIncludesAfter(writer); if (_scriptincludes.Text.Length > 0) { writer.WriteStartElement("script"); writer.WriteRaw(_scriptincludes.Text); writer.WriteEndElement(); } }
private void EmitScriptItems(XmlWriter writer, IEnumerable<string> scriptincludes) { if (!InlineAllScript) { foreach (var include in scriptincludes) { writer.WriteStartElement("script"); writer.WriteAttributeString("src", include); writer.WriteString("\u00A0"); writer.WriteEndElement(); } } else { var common = new JScriptWriter(); if(null == ScriptSource) { throw new Exception("script source required to inline scripts."); } foreach (var include in scriptincludes) { using(var reader = new StreamReader(ScriptSource(include))) { Log.Trace("including script '{0}' ...", include); var jscode = reader.ReadToEnd(); common.WriteLine(jscode); } } // compactify code ... var compacter = new JScriptBuilder(); compacter.IsCompact = IsCompact; compacter.RewriteProgram(common); _scriptincludes.Write(compacter); } }