示例#1
0
        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("})");
            }
        }
示例#2
0
        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("}");
        }
示例#3
0
        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("};");
        }
示例#4
0
        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();
            }
        }
        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("})");
        }
示例#6
0
        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("}");
        }
示例#7
0
        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(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("}");
        }
示例#9
0
        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("};");
        }
示例#10
0
        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);
            }
        }
示例#11
0
        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("};");
            }
        }
示例#12
0
        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();
        }