public override void Translate(LambdaExpression model, TranslationContext context) { if (context.IsWritingGlobalStatements) { // write function declaration, with params context.Write("function("); context.WriteModels(model.Parameters, ", "); context.WriteLine(") {"); // write inner body context.Indent(); context.WriteModelBody(model.Body); context.Unindent(); // close function declaration context.Write("}"); } else { // write function declaration, with params context.Write("Blade.del(this, function("); context.WriteModels(model.Parameters, ", "); context.WriteLine(") {"); // write inner body context.Indent(); context.WriteModelBody(model.Body); context.Unindent(); // close function declaration context.Write("})"); } }
public override void Translate(ForStatement model, TranslationContext context) { context.EnsureLineBreak(); context.Write("for("); if (model.VariableDeclaration != null && model.VariableDeclaration.Variables.Any()) { context.Write("var "); context.WriteModels(model.VariableDeclaration.Variables, ", "); } else if (model.Initializers != null && model.Initializers.Any()) { context.WriteModels(model.Initializers, ", "); } // write condition context.Write("; "); context.WriteModel(model.Condition); // write incrementors context.Write("; "); context.WriteModels(model.Incrementors, ", "); // write body context.WriteLine(") {"); context.Indent(); context.WriteModelBody(model.Statement); context.Unindent(); context.WriteLine("}"); }
public override void Translate(AnonymousObjectExpression model, TranslationContext context) { context.WriteLine("{"); context.Indent(); var first = true; foreach (var item in model.Assignments) { if (first) { first = false; } else { context.WriteLine(","); } context.Write(item.Assignee.Definition.Name + ": "); context.WriteModel(item.RightExpression); // anonymous type members are created as properties // however, we translate the declaration as fields // thus must also change the member kind, so that // usage of the member is also translated correctly ((IMemberDefinition)item.Assignee.Definition).MemberKind = MemberDefinitionKind.Field; } context.EnsureLineBreak(); context.Unindent(); context.Write("}"); }
public override void Translate(MethodDeclaration model, TranslationContext context) { if (model == null) { return; } context.WriteDeclaration(model); context.Write(" = function ("); if (model.HasParameters) { context.WriteModels(model.Parameters, ", "); } // begin method context.WriteLine(") {"); context.Indent(); // set optional params to defaults foreach (var param in model.Parameters.Where(p => p.Definition.HasDefaultValue)) { context.Write(String.Format("{0} = ({0} !== undefined) ? {0} : ", param.Name)); context.WriteModel(param.DefaultExpression); context.WriteLine(";"); } // write method body context.WriteModelBody(model.Body); context.Unindent(); context.EnsureLineBreak(); context.WriteLine("};"); }
private void WriteIfModel(IfStatement model, TranslationContext context, bool nested) { // if beginning of new statement, ensure line break if (!nested) { context.EnsureLineBreak(); } // opening if clause context.Write("if ("); context.WriteModel(model.Condition); context.WriteLine(") {"); // write statement context.Indent(); context.WriteModelBody(model.Statement); context.Unindent(); context.Write("}"); // write else condition, or newline if (model.HasElseStatement) { context.Write(" else "); // handle if-else explicitly var elseIf = model.ElseStatement as IfStatement; if (elseIf != null) { WriteIfModel(elseIf, context, true); } else { // begin final else statement context.WriteLine("{"); context.Indent(); // end final else statement context.WriteModelBody(model.ElseStatement); context.Unindent(); context.WriteLine("}"); } } else { context.WriteLine(); } }
private bool HandleSpecialCases(NewExpression model, TranslationContext context) { // check for special cases if (model.Type != null) { if (model.Type.TypeKind == TypeDefinitionKind.Delegate) { // delegates should have a single argument context.WriteModel(model.Arguments[0].Expression); return(true); } if (model.Type.TypeKind == TypeDefinitionKind.Anonymous) { // types view as anonymous, instanciate using object literal notation if (model.Initializer == null || !model.Initializer.Expressions.Any()) { context.Write("{}"); } else { context.WriteLine("{"); context.Indent(); for (int i = 0; i < model.Initializer.Expressions.Count; i++) { var assignment = model.Initializer.Expressions[i] as AssignmentExpression; if (assignment == null) { throw new CompilationException("All initializer expressions must be assignments.", model); } context.Write(assignment.Assignee.Definition.Name + ": "); context.WriteModel(assignment.RightExpression); if ((i + 1) < model.Initializer.Expressions.Count) { context.WriteLine(","); } } context.WriteLine(); context.Unindent(); context.Write("}"); } return(true); } } return(false); }
public override void Translate(SwitchStatement model, TranslationContext context) { // begin switch statement context.EnsureLineBreak(); context.Write("switch ("); context.WriteModel(model.Expression); context.WriteLine(") {"); context.Indent(); // write sections foreach (var section in model.Sections) { foreach (var label in section.Labels) { // labels context.EnsureLineBreak(); context.Write("case "); context.WriteModel(label); context.WriteLine(":"); } if (section.IsDefault) { context.WriteLine("default:"); } // write statements context.Indent(); context.WriteModels(section.Statements, ""); context.Unindent(); } // end statement context.Unindent(); context.WriteLine("}"); }
public override void Translate(AnonymousMethodExpression model, TranslationContext context) { // write function declaration, with params context.Write("Blade.del(this, function("); context.WriteModels(model.Parameters, ", "); context.WriteLine(") {"); // write inner body context.Indent(); context.WriteModelBody(model.Body); context.Unindent(); // close function declaration context.Write("})"); }
public override void Translate(WhileStatement model, TranslationContext context) { // begin while statement context.EnsureLineBreak(); context.Write("while ("); context.WriteModel(model.Condition); context.WriteLine(") {"); context.Indent(); // write inner statement context.WriteModelBody(model.Statement); // end while statement context.Unindent(); context.WriteLine("}"); }
public override void Translate(DoStatement model, TranslationContext context) { // begin do statement context.EnsureLineBreak(); context.WriteLine("do {"); context.Indent(); // write inner statement context.WriteModelBody(model.Statement); // end do statement // write while condition context.Unindent(); context.Write("} while ("); context.WriteModel(model.Condition); context.WriteLine(");"); }
public override void Translate(CodeBlock model, TranslationContext context) { if (model.HasBraces) { context.WriteLine("{"); context.Indent(); } foreach (var item in model.Statements) { context.WriteModel(item); } if (model.HasBraces) { context.EnsureLineBreak(); context.Unindent(); context.Write("}"); } }
public override void Translate(ForEachStatement model, TranslationContext context) { context.EnsureLineBreak(); var identifier = model.IdentifierName; var enumerator = "$" + identifier + "_enum"; context.WriteLine("var " + identifier + " = null;"); context.Write("var " + enumerator + " = "); context.WriteModel(model.Expression); context.WriteLine(".GetEnumerator();"); context.WriteLine("while(" + enumerator + ".MoveNext()) {"); context.Indent(); context.WriteLine(identifier + " = " + enumerator + ".get_Current();"); context.WriteModelBody(model.Statement); context.EnsureLineBreak(); context.Unindent(); context.WriteLine("}"); }
public override void Translate(EventDeclaration model, TranslationContext context) { if (model == null) { return; } string fieldAddScript = null; string fieldRemScript = null; if (model.IsField) { // add a backing event list var fieldName = "$" + model.Definition.Name; var backingField = new FieldDeclaration { Container = model.Container, OriginatingNode = model.OriginatingNode, OriginatingTree = model.OriginatingTree, Definition = new FieldDefinition { Name = fieldName, ContainingType = model.Definition.ContainingType, Type = new ClassDefinition() { Kind = DefinitionKind.Type, Name = "Event", Namespace = "Blade", } }, Initializer = new LiteralExpression { Type = LiteralType.None, Text = "new Blade.Event()" } }; // use same modifier as property, but force private backingField.Definition.Modifiers.Apply(model.Definition.Modifiers); backingField.Definition.Modifiers.Access = Accessibility.Private; context.WriteModel(backingField); // manually create get/set body var fieldPrefix = model.IsStatic ? model.Container.Name : "this"; var fieldAccess = fieldPrefix + "." + fieldName; fieldAddScript = fieldAccess + ".add(func, ctx);"; fieldRemScript = fieldAccess + ".rem(func);"; // add a method to invoke the event context.WriteDeclaration(model); context.WriteLine(" = function() {"); context.Indent(); context.WriteLine(fieldAccess + ".pub.apply(" + fieldAccess + ", arguments);"); context.Unindent(); context.WriteLine("}"); } // write the add accessor context.WriteDeclaration(model, postfix: "$add"); context.WriteLine(" = function(func, ctx) {"); context.Indent(); if (model.IsField) { context.WriteLine(fieldAddScript); } else { context.WriteModelBody(model.AddAccessor); } context.Unindent(); context.WriteLine("};"); // write the remove accessor context.WriteDeclaration(model, postfix: "$rem"); context.WriteLine(" = function(func) {"); context.Indent(); if (model.IsField) { context.WriteLine(fieldRemScript); } else { context.WriteModelBody(model.RemoveAccessor); } context.Unindent(); context.WriteLine("};"); }
public override void Translate(ClassDeclaration model, TranslationContext context) { if (model == null) { return; } // make sure the namespace is available context.EnsureNamespace(model.Definition.Namespace); // begin the class closure context.WriteLine(); context.WriteLine(model.Definition.GetFullName() + " = (function() {"); context.Indent(); if (model.IsDerived) { var baseName = model.Definition.BaseClass.GetFullName(); // derive from base, and create a local variable to access base context.WriteLine(String.Format("Blade.derive({0}, {1});", model.Definition.Name, baseName)); context.WriteLine("var $base = " + baseName + ".prototype;"); } // write the class constructor var instanceCtors = model.Constructors.Where(c => !c.IsStatic); if (instanceCtors.Count() > 1) { throw new CompilationException("Constructor overloading is not supported.", model.Constructors[1]); } var ctor = instanceCtors.FirstOrDefault() ?? new ConstructorDeclaration(); var paramsText = String.Join(", ", ctor.Parameters.Select(p => p.Definition.Name)); // write the ctor context.WriteLine(String.Format("function {0}({1}) {{", model.Definition.Name, paramsText)); context.Indent(); // write initialized fields, and return remaining fields // those remaining may safely be attached to the prototype var pFields = WriteCtorInitializers(model.Fields, context); if (model.IsDerived) { // write explicit call to base class ctor context.Write("$base.constructor.call(this"); if (ctor.HasExplicitBaseCall) { // check for arguments to the base ctor var baseCtor = model.Definition.BaseClass.Constructors.FirstOrDefault(); if (baseCtor != null && baseCtor.Parameters.Any()) { var baseArgs = TranslationHelper.GetInvocationArgs(baseCtor.Parameters, ctor.BaseArguments); if (baseArgs.Any()) { // write base ctor args context.Write(", "); context.WriteModels(baseArgs, ", "); } } } context.WriteLine(");"); } context.WriteModelBody(ctor.Body); context.Unindent(); context.WriteLine("}"); // group all members var members = Enumerable.Empty <IMemberDeclarationModel>() .Concat(pFields).Concat(model.Events) .Concat(model.Properties).Concat(model.Methods); var instanceMembers = new List <IMemberDeclarationModel>(); var staticMembers = new List <IMemberDeclarationModel>(); // separate instance and static members foreach (var item in members) { if (item.IsStatic) { staticMembers.Add(item); } else { instanceMembers.Add(item); } } // write instance members if (instanceMembers.Any()) { context.PrepareForDeclarations(model.Definition.Name); context.EnsureLineBreak(); foreach (var item in instanceMembers) { context.WriteModel(item); } } // apply interfaces if (model.Definition.Interfaces.Any()) { context.Write("Blade.impl(" + model.Definition.Name); foreach (var def in model.Definition.Interfaces) { context.Write(", '" + def.GetFullName() + "'"); } context.WriteLine(");"); } // return class constructor and end closure context.EnsureLineBreak(); context.WriteLine("return " + model.Definition.Name + ";"); context.Unindent(); context.WriteLine("})();"); // write static members as global statements foreach (var item in staticMembers) { CompilationContext.Current.Model.GlobalStatements.Add(item); context.WriteModel(item); } // if the class has a static constructor, add to globals var staticCtor = model.Constructors.FirstOrDefault(c => c.IsStatic); if (staticCtor != null) { staticCtor.Body.HasBraces = false; CompilationContext.Current.Model.GlobalStatements.Add(staticCtor.Body); } }
public override void Translate(PropertyDeclaration model, TranslationContext context) { if (model == null) { return; } string autoGetScript = null; string autoSetScript = null; if (model.IsAutoProperty) { // add a backing field var fieldName = "$" + model.Definition.Name; var backingField = new FieldDeclaration { Container = model.Container, OriginatingNode = model.OriginatingNode, OriginatingTree = model.OriginatingTree, Definition = new FieldDefinition { Name = fieldName, ContainingType = model.Definition.ContainingType, Type = model.Definition.Type, Kind = DefinitionKind.Member, MemberKind = MemberDefinitionKind.Field } }; // use same modifier as property, but force private backingField.Definition.Modifiers.Apply(model.Definition.Modifiers); backingField.Definition.Modifiers.Access = Accessibility.Private; context.WriteModel(backingField); // manually create get/set body var fieldPrefix = model.IsStatic ? model.Container.Name : "this"; autoGetScript = "return " + fieldPrefix + "." + fieldName + ";"; autoSetScript = fieldPrefix + "." + fieldName + " = value;"; } // write the get accessor if (model.HasGetter || model.IsAutoProperty) { context.WriteDeclaration(model, "get_"); context.WriteLine(" = function() {"); context.Indent(); if (model.IsAutoProperty) { context.WriteLine(autoGetScript); } else { context.WriteModelBody(model.GetAccessor); } context.Unindent(); context.WriteLine("};"); } // write the set accessor if (model.HasSetter || model.IsAutoProperty) { context.WriteDeclaration(model, "set_"); context.WriteLine(" = function(value) {"); context.Indent(); if (model.IsAutoProperty) { context.WriteLine(autoSetScript); } else { context.WriteModelBody(model.SetAccessor); } context.Unindent(); context.WriteLine("};"); } }
public override void Translate(TryStatement model, TranslationContext context) { // begin try context.EnsureLineBreak(); context.WriteLine("try {"); context.Indent(); // write try body context.WriteModelBody(model.Body); // end try context.Unindent(); context.EnsureLineBreak(); context.Write("}"); // write catches if (model.HasCatch) { foreach (var item in model.Catches) { context.Write(" catch("); // javascript catch requires an identifier, always var identifier = (item.Identifier != null && !String.IsNullOrEmpty(item.Identifier.Name)) ? item.Identifier.Name : "ex$"; var typeName = (item.Type != null && !String.IsNullOrEmpty(item.Type.GetFullName())) ? item.Type.GetFullName() : null; context.Write(identifier); if (typeName != null && typeName != "Error") { context.Write(" if " + identifier + " instanceof " + typeName); } // begin catch context.WriteLine(") {"); context.Indent(); // write catch body context.WriteModelBody(item.Body); // end catch context.Unindent(); context.EnsureLineBreak(); context.Write("}"); } } if (model.HasFinally) { // begin finally context.WriteLine(" finally {"); context.Indent(); // write finally body context.WriteModelBody(model.FinallyBody); // end finally context.Unindent(); context.EnsureLineBreak(); context.Write("}"); } context.WriteLine(); }