Пример #1
0
        public static void EmitYield(AbstractEmitterBlock block, IType returnType)
        {
            block.Write("var $yield = []");

            block.WriteSemiColon();
            block.WriteNewLine();
        }
Пример #2
0
        public virtual void WriteScript(object value)
        {
            this.WriteIndent();
            var s = AbstractEmitterBlock.ToJavaScript(value, this.Emitter);

            this.Emitter.Output.Append(s);
        }
Пример #3
0
        public static void EmitYield(AbstractEmitterBlock block, IType returnType)
        {
            block.Write("var $yield = []");

            block.WriteSemiColon();
            block.WriteNewLine();
        }
Пример #4
0
 public ExpressionTreeBuilder(ICompilation compilation, IEmitter emitter, SyntaxTree syntaxTree, AbstractEmitterBlock block)
 {
     _compilation   = compilation;
     _emitter       = emitter;
     _syntaxTree    = syntaxTree;
     _expression    = (ITypeDefinition)ReflectionHelper.ParseReflectionName(typeof(System.Linq.Expressions.Expression).FullName).Resolve(compilation);
     _allParameters = new Dictionary <IVariable, string>();
     _block         = block;
 }
Пример #5
0
        public virtual void WriteIndented(string s, int?position = null)
        {
            var level = position.HasValue && position.Value == 0 ? this.InitialLevel : this.Level;

            var indented = new StringBuilder(AbstractEmitterBlock.WriteIndentToString(s, level));

            this.WriteIndent(indented, level, 0);

            this.Write(this.Output, indented.ToString(), position);
        }
Пример #6
0
        public static string ReplaceInlineArgs(AbstractEmitterBlock block, string inline, Expression[] args)
        {
            var emitter = block.Emitter;

            inline = _formatArg.Replace(inline, delegate(Match m)
            {
                int count       = emitter.Writers.Count;
                string key      = m.Groups[2].Value;
                string modifier = m.Groups[1].Success ? m.Groups[4].Value : null;

                StringBuilder oldSb = emitter.Output;
                emitter.Output      = new StringBuilder();

                Expression expr = null;

                if (Regex.IsMatch(key, "^\\d+$"))
                {
                    expr = args.Skip(int.Parse(key)).FirstOrDefault();
                }
                else
                {
                    expr = args.FirstOrDefault(e => e.ToString() == key);
                }

                string s = "";
                if (expr != null)
                {
                    var writer = block.SaveWriter();
                    block.NewWriter();
                    expr.AcceptVisitor(emitter);
                    s = emitter.Output.ToString();
                    block.RestoreWriter(writer);

                    if (modifier == "raw")
                    {
                        s = s.Trim('"');
                    }
                }

                block.Write(block.WriteIndentToString(s));

                if (emitter.Writers.Count != count)
                {
                    block.PopWriter();
                }

                string replacement = emitter.Output.ToString();
                emitter.Output     = oldSb;

                return(replacement);
            });

            return(inline);
        }
Пример #7
0
        protected virtual void WriteMultiLineComment(string text, bool newline, bool wrap = true)
        {
            bool needRemoveIndent  = false;
            var  methodDeclaration = this.Comment.GetParent <MethodDeclaration>();
            int  mode = 0;

            if (methodDeclaration != null)
            {
                foreach (var attrSection in methodDeclaration.Attributes)
                {
                    foreach (var attr in attrSection.Attributes)
                    {
                        var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter);

                        if (rr.Type.FullName == "Bridge.InitAttribute")
                        {
                            if (attr.HasArgumentList && attr.Arguments.Count > 0)
                            {
                                var argExpr = attr.Arguments.First();
                                var argrr   = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter);

                                if (argrr.ConstantValue is int && (int)argrr.ConstantValue > 0)
                                {
                                    mode             = (int)argrr.ConstantValue;
                                    needRemoveIndent = true;
                                }
                            }
                        }
                    }
                }
            }

            if (!newline && this.RemovePenultimateEmptyLines(true))
            {
                this.Emitter.IsNewLine = false;
                this.WriteSpace();
            }

            if (needRemoveIndent)
            {
                text = AbstractEmitterBlock.RemoveIndentFromString(text, this.Comment.StartLocation.Column - (mode == 1 ? 5 : 1));
            }

            if (wrap)
            {
                this.Write("/* " + text + "*/");
                this.WriteNewLine();
            }
            else
            {
                this.Write(text);
            }
        }
Пример #8
0
        public static string ReplaceInlineArgs(AbstractEmitterBlock block, string inline, Expression[] args)
        {
            var emitter = block.Emitter;
            inline = _formatArg.Replace(inline, delegate(Match m)
            {
                int count = emitter.Writers.Count;
                string key = m.Groups[2].Value;
                string modifier = m.Groups[1].Success ? m.Groups[4].Value : null;

                StringBuilder oldSb = emitter.Output;
                emitter.Output = new StringBuilder();

                Expression expr = null;

                if (Regex.IsMatch(key, "^\\d+$"))
                {
                    expr = args.Skip(int.Parse(key)).FirstOrDefault();
                }
                else
                {
                    expr = args.FirstOrDefault(e => e.ToString() == key);
                }

                string s = "";
                if (expr != null)
                {
                    var writer = block.SaveWriter();
                    block.NewWriter();
                    expr.AcceptVisitor(emitter);
                    s = emitter.Output.ToString();
                    block.RestoreWriter(writer);

                    if (modifier == "raw")
                    {
                        s = s.Trim('"');
                    }
                }

                block.Write(block.WriteIndentToString(s));

                if (emitter.Writers.Count != count)
                {
                    block.PopWriter();
                }

                string replacement = emitter.Output.ToString();
                emitter.Output = oldSb;

                return replacement;
            });

            return inline;
        }
Пример #9
0
        public static void EmitYieldReturn(AbstractEmitterBlock block, IType returnType)
        {
            block.WriteReturn(true);

            if (returnType != null && returnType.Name == "IEnumerator")
            {
                block.Write("Bridge.Array.toEnumerator($yield)");
            }
            else
            {
                block.Write("Bridge.Array.toEnumerable($yield)");
            }

            block.WriteSemiColon();
            block.WriteNewLine();
        }
Пример #10
0
        public static void EmitYieldReturn(AbstractEmitterBlock block, IType returnType)
        {
            block.WriteReturn(true);

            if (returnType != null && returnType.Name == "IEnumerator")
            {
                block.Write("Bridge.Array.toEnumerator($yield)");
            }
            else
            {
                block.Write("Bridge.Array.toEnumerable($yield)");
            }

            block.WriteSemiColon();
            block.WriteNewLine();
        }
Пример #11
0
        protected override void EmitConversionExpression()
        {
            if (this.PrimitiveExpression.IsNull)
            {
                return;
            }

            var isTplRaw = this.Emitter.TemplateModifier == "raw";

            if (this.PrimitiveExpression.Value is RawValue || isTplRaw)
            {
                this.Write(AbstractEmitterBlock.UpdateIndentsInString(this.PrimitiveExpression.Value.ToString(), 0));
            }
            else
            {
                this.WriteScript(Bridge.Translator.Emitter.ConvertConstant(this.PrimitiveExpression.Value, this.PrimitiveExpression, this.Emitter));
            }
        }
Пример #12
0
        protected virtual void WrapToModules()
        {
            this.Log.Trace("Wrapping to modules...");

            foreach (var outputPair in this.Outputs)
            {
                var output = outputPair.Value;

                foreach (var moduleOutputPair in output.ModuleOutput)
                {
                    var module       = moduleOutputPair.Key;
                    var moduleOutput = moduleOutputPair.Value;

                    this.Log.Trace("Module " + module.Name + " ...");

                    AbstractEmitterBlock.RemovePenultimateEmptyLines(moduleOutput, true);

                    switch (module.Type)
                    {
                    case ModuleType.CommonJS:
                        this.WrapToCommonJS(moduleOutput, module, output);
                        break;

                    case ModuleType.UMD:
                        this.WrapToUMD(moduleOutput, module, output);
                        break;

                    case ModuleType.ES6:
                        this.WrapToES6(moduleOutput, module, output);
                        break;

                    case ModuleType.AMD:
                    default:
                        this.WrapToAMD(moduleOutput, module, output);
                        break;
                    }
                }
            }

            this.Log.Trace("Wrapping to modules done");
        }
Пример #13
0
        public static bool IsUserDefinedConversion(AbstractEmitterBlock block, Expression expression)
        {
            Conversion conversion = null;

            try
            {
                var rr = block.Emitter.Resolver.ResolveNode(expression, null);
                conversion = block.Emitter.Resolver.Resolver.GetConversion(expression);

                if (conversion == null)
                {
                    return false;
                }

                return conversion.IsUserDefined;
            }
            catch
            {
            }

            return false;
        }
Пример #14
0
        public static bool IsUserDefinedConversion(AbstractEmitterBlock block, Expression expression)
        {
            Conversion conversion = null;

            try
            {
                var rr = block.Emitter.Resolver.ResolveNode(expression, null);
                conversion = block.Emitter.Resolver.Resolver.GetConversion(expression);

                if (conversion == null)
                {
                    return(false);
                }

                return(conversion.IsUserDefined);
            }
            catch
            {
            }

            return(false);
        }
Пример #15
0
        public static bool IsUserDefinedConversion(AbstractEmitterBlock block, Expression expression)
        {
            Conversion conversion = null;

            try
            {
                // The resolveNode call required to get GetConversion not fail
                block.Emitter.Resolver.ResolveNode(expression, null);
                conversion = block.Emitter.Resolver.Resolver.GetConversion(expression);

                if (conversion == null)
                {
                    return(false);
                }

                return(conversion.IsUserDefined);
            }
            catch
            {
            }

            return(false);
        }
Пример #16
0
        public static void EmitYieldReturn(AbstractEmitterBlock block, IType returnType)
        {
            block.WriteReturn(true);

            if (returnType != null && returnType.Name == "IEnumerator")
            {
                if (returnType.TypeArguments.Count > 0)
                {
                    block.Write(JS.Types.SYSTEM_ARRAY + "." + JS.Funcs.TO_ENUMERATOR + "(" + JS.Vars.YIELD + ", " + BridgeTypes.ToJsName(returnType.TypeArguments.First(), block.Emitter) + ")");
                }
                else
                {
                    block.Write(JS.Types.SYSTEM_ARRAY + "." + JS.Funcs.TO_ENUMERATOR + "(" + JS.Vars.YIELD + ")");
                }
            }
            else
            {
                block.Write(JS.Types.SYSTEM_ARRAY + "." + JS.Funcs.TO_ENUMERABLE + "(" + JS.Vars.YIELD + ")");
            }

            block.WriteSemiColon();
            block.WriteNewLine();
        }
Пример #17
0
        protected virtual void WrapToModules()
        {
            foreach (var outputPair in this.Outputs)
            {
                var output = outputPair.Value;

                foreach (var moduleOutputPair in output.ModuleOutput)
                {
                    var moduleName   = moduleOutputPair.Key;
                    var moduleOutput = moduleOutputPair.Value;
                    AbstractEmitterBlock.RemovePenultimateEmptyLines(moduleOutput, true);
                    var str = moduleOutput.ToString();
                    moduleOutput.Length = 0;

                    moduleOutput.Append("define(");

                    if (moduleName != Bridge.Translator.AssemblyInfo.DEFAULT_FILENAME)
                    {
                        moduleOutput.Append(this.ToJavaScript(moduleName));
                        moduleOutput.Append(", ");
                    }

                    moduleOutput.Append("[\"bridge\",");
                    if (output.ModuleDependencies.ContainsKey(moduleName) && output.ModuleDependencies[moduleName].Count > 0)
                    {
                        output.ModuleDependencies[moduleName].Each(md =>
                        {
                            moduleOutput.Append(this.ToJavaScript(md.DependencyName));
                            moduleOutput.Append(",");
                        });
                    }
                    moduleOutput.Remove(moduleOutput.Length - 1, 1); // remove trailing comma
                    moduleOutput.Append("], ");

                    moduleOutput.Append("function (_");

                    if (output.ModuleDependencies.ContainsKey(moduleName) && output.ModuleDependencies[moduleName].Count > 0)
                    {
                        moduleOutput.Append(", ");
                        output.ModuleDependencies[moduleName].Each(md =>
                        {
                            moduleOutput.Append(md.VariableName.IsNotEmpty() ? md.VariableName : md.DependencyName);
                            moduleOutput.Append(",");
                        });
                        moduleOutput.Remove(moduleOutput.Length - 1, 1); // remove trailing comma
                    }

                    WriteNewLine(moduleOutput, ") {");

                    string indent = str.StartsWith("    ") ? "" : "    ";
                    moduleOutput.Append("    ");
                    WriteNewLine(moduleOutput, "var exports = { };");
                    moduleOutput.Append(indent + str.Replace("\n", "\n" + indent));

                    if (!str.Trim().EndsWith("\n"))
                    {
                        WriteNewLine(moduleOutput);
                    }

                    WriteNewLine(moduleOutput, "    return exports;");
                    WriteNewLine(moduleOutput, "});");
                }
            }
        }
Пример #18
0
        protected void VisitAsyncForeachStatement()
        {
            ForeachStatement foreachStatement = this.ForeachStatement;

            if (foreachStatement.EmbeddedStatement is EmptyStatement)
            {
                return;
            }

            var oldValue       = this.Emitter.ReplaceAwaiterByVar;
            var jumpStatements = this.Emitter.JumpStatements;

            this.Emitter.JumpStatements = new List <IJumpInfo>();
            this.WriteAwaiters(foreachStatement.InExpression);

            bool containsAwaits = false;
            var  awaiters       = this.GetAwaiters(foreachStatement.EmbeddedStatement);

            if (awaiters != null && awaiters.Length > 0)
            {
                containsAwaits = true;
            }

            this.Emitter.ReplaceAwaiterByVar = true;

            if (!containsAwaits)
            {
                this.VisitForeachStatement(oldValue);
                return;
            }

            var iteratorName = this.AddLocal(this.GetTempVarName(), null, AstType.Null);

            var for_rr = (ForEachResolveResult)this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter);
            var get_rr = for_rr.GetEnumeratorCall as InvocationResolveResult;
            var in_rr  = this.Emitter.Resolver.ResolveNode(foreachStatement.InExpression, this.Emitter);
            var inline = get_rr != null?this.Emitter.GetInline(get_rr.Member) : null;

            var checkEnum = in_rr.Type.Kind != TypeKind.Array && !in_rr.Type.IsKnownType(KnownTypeCode.String) &&
                            !in_rr.Type.IsKnownType(KnownTypeCode.Array);
            var isGenericEnumerable = for_rr.CollectionType.IsParameterized &&
                                      for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable";
            var emitInline = checkEnum && !isGenericEnumerable && inline != null;

            this.Write(iteratorName, " = ");

            if (!emitInline)
            {
                this.Write(JS.Funcs.BRIDGE_GET_ENUMERATOR);
                this.WriteOpenParentheses();
                foreachStatement.InExpression.AcceptVisitor(this.Emitter);
            }

            if (checkEnum)
            {
                if (for_rr.CollectionType.IsParameterized &&
                    for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable")
                {
                    this.WriteComma(false);
                    this.Write(BridgeTypes.ToJsName(((ParameterizedType)for_rr.CollectionType).TypeArguments[0], this.Emitter));
                }
                else if (get_rr != null)
                {
                    if (inline != null)
                    {
                        var argsInfo = new ArgumentsInfo(this.Emitter, foreachStatement.InExpression, get_rr);
                        new InlineArgumentsBlock(this.Emitter, argsInfo, inline).Emit();
                    }
                    else
                    {
                        var name = OverloadsCollection.Create(this.Emitter, get_rr.Member).GetOverloadName();

                        if (name != "GetEnumerator" && name != "System$Collections$IEnumerable$GetEnumerator")
                        {
                            this.WriteComma(false);
                            this.WriteScript(name);
                        }
                    }
                }
            }

            this.Emitter.ReplaceAwaiterByVar = oldValue;
            if (!emitInline)
            {
                this.WriteCloseParentheses();
            }
            this.WriteSemiColon();
            this.WriteNewLine();
            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");
            this.WriteNewLine();

            IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep();

            this.WriteIf();
            this.WriteOpenParentheses();
            this.Write(iteratorName);
            this.WriteDot();
            this.Write(JS.Funcs.MOVE_NEXT);
            this.WriteOpenCloseParentheses();
            this.WriteCloseParentheses();
            this.WriteSpace();
            this.BeginBlock();

            this.PushLocals();

            var varName = this.AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType);

            this.WriteVar();
            this.Write(varName + " = ");

            var rr = this.Emitter.Resolver.ResolveNode(foreachStatement, this.Emitter) as ForEachResolveResult;

            bool isReferenceLocal = false;

            if (this.Emitter.LocalsMap != null && this.Emitter.LocalsMap.ContainsKey(rr.ElementVariable))
            {
                isReferenceLocal = this.Emitter.LocalsMap[rr.ElementVariable].EndsWith(".v");
            }

            if (isReferenceLocal)
            {
                this.Write("{ v : ");
            }

            string castCode = this.GetCastCode(rr.ElementType, rr.ElementVariable.Type);

            if (castCode != null)
            {
                this.EmitInlineCast(iteratorName + "." + JS.Funcs.GET_CURRENT, castCode);
            }
            else if (this.CastMethod != null)
            {
                this.Write(BridgeTypes.ToJsName(this.CastMethod.DeclaringType, this.Emitter));
                this.WriteDot();
                this.Write(OverloadsCollection.Create(this.Emitter, this.CastMethod).GetOverloadName());
                this.WriteOpenParentheses();
                var pos = this.Emitter.Output.Length;
                this.Write(iteratorName + "." + JS.Funcs.GET_CURRENT);
                Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);
                this.WriteCloseParentheses();
            }
            else
            {
                var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type);
                if (needCast)
                {
                    this.Write(JS.Funcs.BRIDGE_CAST);
                    this.WriteOpenParentheses();
                }

                var pos = this.Emitter.Output.Length;
                this.Write(iteratorName);

                this.WriteDot();
                this.Write(JS.Funcs.GET_CURRENT);
                Helpers.CheckValueTypeClone(rr, this.ForeachStatement.InExpression, this, pos);

                if (needCast)
                {
                    this.Write(", ", BridgeTypes.ToJsName(rr.ElementVariable.Type, this.Emitter), ")");
                }
            }

            if (isReferenceLocal)
            {
                this.Write(" }");
            }

            this.WriteSemiColon();
            this.WriteNewLine();

            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");

            BlockStatement block = foreachStatement.EmbeddedStatement as BlockStatement;

            var writer = this.SaveWriter();

            this.Emitter.AsyncBlock.AddAsyncStep();
            this.Emitter.IgnoreBlock = foreachStatement.EmbeddedStatement;
            var startCount = this.Emitter.AsyncBlock.Steps.Count;

            if (block != null)
            {
                block.AcceptChildren(this.Emitter);
            }
            else
            {
                foreachStatement.EmbeddedStatement.AcceptVisitor(this.Emitter);
            }

            IAsyncStep loopStep = null;

            if (this.Emitter.AsyncBlock.Steps.Count > startCount)
            {
                loopStep            = this.Emitter.AsyncBlock.Steps.Last();
                loopStep.JumpToStep = conditionStep.Step;
            }

            this.RestoreWriter(writer);

            if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString()))
            {
                this.Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";");
                this.WriteNewLine();
                this.Write("continue;");
                this.WriteNewLine();
            }

            this.PopLocals();

            this.WriteNewLine();
            this.EndBlock();
            this.WriteNewLine();

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            conditionStep.JumpToStep = nextStep.Step;

            if (this.Emitter.JumpStatements.Count > 0)
            {
                this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position));
                foreach (var jump in this.Emitter.JumpStatements)
                {
                    jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step);
                }
            }

            this.Emitter.JumpStatements = jumpStatements;
        }
Пример #19
0
 public bool IsOnlyWhitespaceOnPenultimateLine(bool lastTwoLines = true)
 {
     return(AbstractEmitterBlock.IsOnlyWhitespaceOnPenultimateLine(this.Emitter.Output, lastTwoLines));
 }
Пример #20
0
        public static void WriteResolveResult(ResolveResult rr, AbstractEmitterBlock block)
        {
            if (rr is ConversionResolveResult)
            {
                rr = ((ConversionResolveResult)rr).Input;
            }

            if (rr is TypeOfResolveResult)
            {
                block.Write(BridgeTypes.ToJsName(((TypeOfResolveResult)rr).ReferencedType, block.Emitter));
            }
            else if (rr is ArrayCreateResolveResult)
            {
                TypeSystemAstBuilder typeBuilder =
                    new TypeSystemAstBuilder(new CSharpResolver(block.Emitter.Resolver.Compilation));
                var expression = typeBuilder.ConvertConstantValue(rr) as ArrayCreateExpression;
                new ArrayCreateBlock(block.Emitter, expression, (ArrayCreateResolveResult)rr).Emit();
            }
            else if (rr is MemberResolveResult)
            {
                var mrr = (MemberResolveResult)rr;

                if (mrr.IsCompileTimeConstant && mrr.Member.DeclaringType.Kind == TypeKind.Enum)
                {
                    var typeDef = mrr.Member.DeclaringType as DefaultResolvedTypeDefinition;

                    if (typeDef != null)
                    {
                        var enumMode = Helpers.EnumEmitMode(typeDef);

                        if ((block.Emitter.Validator.IsExternalType(typeDef) && enumMode == -1) || enumMode == 2)
                        {
                            block.WriteScript(mrr.ConstantValue);

                            return;
                        }

                        if (enumMode >= 3 && enumMode < 7)
                        {
                            string enumStringName = mrr.Member.Name;
                            var    attr           = Helpers.GetInheritedAttribute(mrr.Member,
                                                                                  Translator.Bridge_ASSEMBLY + ".NameAttribute");

                            if (attr != null)
                            {
                                enumStringName = block.Emitter.GetEntityName(mrr.Member);
                            }
                            else
                            {
                                switch (enumMode)
                                {
                                case 3:
                                    enumStringName =
                                        Object.Net.Utilities.StringUtils.ToLowerCamelCase(mrr.Member.Name);
                                    break;

                                case 4:
                                    break;

                                case 5:
                                    enumStringName = enumStringName.ToLowerInvariant();
                                    break;

                                case 6:
                                    enumStringName = enumStringName.ToUpperInvariant();
                                    break;
                                }
                            }

                            block.WriteScript(enumStringName);
                        }
                        else
                        {
                            block.WriteScript(rr.ConstantValue);
                        }
                    }
                }
                else
                {
                    block.WriteScript(rr.ConstantValue);
                }
            }
            else
            {
                block.WriteScript(rr.ConstantValue);
            }
        }
Пример #21
0
        protected void InjectSteps()
        {
            foreach (var label in this.JumpLabels)
            {
                var tostep = this.Steps.First(s => s.Node == label.Node);
                label.Output.Replace("${" + label.Node.GetHashCode() + "}", tostep.Step.ToString());
            }

            for (int i = 0; i < this.Steps.Count; i++)
            {
                var step = this.Steps[i];

                if (i != 0)
                {
                    this.WriteNewLine();
                }

                this.Write("case " + i + ": ");
                var output = step.Output.ToString();

                if (string.IsNullOrWhiteSpace(output) && step.JumpToStep == (i + 1))
                {
                    continue;
                }

                this.BeginBlock();

                bool addNewLine = false;

                if (step.FromTaskNumber > -1)
                {
                    var expression = this.AwaitExpressions[step.FromTaskNumber - 1];

                    if (this.IsTaskResult(expression))
                    {
                        this.Write(string.Format("$taskResult{0} = $task{0}.getResult();", step.FromTaskNumber));
                    }
                    else
                    {
                        this.Write(string.Format("$task{0}.getResult();", step.FromTaskNumber));
                    }

                    addNewLine = true;
                }

                if (!string.IsNullOrWhiteSpace(output))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write(this.WriteIndentToString(output.TrimEnd()));
                }

                if (!this.IsOnlyWhitespaceOnPenultimateLine(false))
                {
                    addNewLine = true;
                }

                if (step.JumpToStep > -1 && !AbstractEmitterBlock.IsJumpStatementLast(output))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write("$step = " + step.JumpToStep + ";");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else if (step.JumpToNode != null && !AbstractEmitterBlock.IsJumpStatementLast(output))
                {
                    var tostep = this.Steps.First(s => s.Node == step.JumpToNode);

                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write("$step = " + tostep.Step + ";");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else if (i == (this.Steps.Count - 1) && !AbstractEmitterBlock.IsReturnLast(output))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    if (this.IsTaskReturn)
                    {
                        this.Write("$returnTask.setResult(null);");
                        this.WriteNewLine();
                    }

                    this.Write("return;");
                }

                this.WriteNewLine();
                this.EndBlock();
            }

            this.WriteNewLine();
            this.Write("default: ");
            this.BeginBlock();

            if (this.IsTaskReturn)
            {
                this.Write("$returnTask.setResult(null);");
                this.WriteNewLine();
            }

            this.Write("return;");
            this.WriteNewLine();
            this.EndBlock();
        }
Пример #22
0
 public bool IsOnlyWhitespaceOnPenultimateLine(bool lastTwoLines = true, string output = null)
 {
     return(AbstractEmitterBlock.IsOnlyWhitespaceOnPenultimateLine(output ?? this.Emitter.Output.ToString(), lastTwoLines));
 }
Пример #23
0
 public static bool IsJumpStatementLast(string str)
 {
     str = str.TrimEnd();
     return(str.EndsWith("continue;") || str.EndsWith("break;") || AbstractEmitterBlock.IsReturnLast(str));
 }
Пример #24
0
 public virtual void WriteThis()
 {
     this.Write(AbstractEmitterBlock.GetThisAlias(this.Emitter));
     this.Emitter.ThisRefCounter++;
 }
Пример #25
0
 public int GetNumberOfEmptyLinesAtEnd()
 {
     return(AbstractEmitterBlock.GetNumberOfEmptyLinesAtEnd(this.Emitter.Output));
 }
Пример #26
0
        public static string ToJavaScript(object value, IEmitter emitter)
        {
            string s = null;

            if (value is double)
            {
                double d = (double)value;
                if (double.IsNaN(d))
                {
                    s = JS.Types.Number.NaN;
                }
                else if (double.IsPositiveInfinity(d))
                {
                    s = JS.Types.Number.Infinity;
                }
                else if (double.IsNegativeInfinity(d))
                {
                    s = JS.Types.Number.InfinityNegative;
                }
                else
                {
                    s = emitter.ToJavaScript(value);
                }
            }
            else if (value is float)
            {
                float f = (float)value;
                if (float.IsNaN(f))
                {
                    s = JS.Types.Number.NaN;
                }
                else if (float.IsPositiveInfinity(f))
                {
                    s = JS.Types.Number.Infinity;
                }
                else if (float.IsNegativeInfinity(f))
                {
                    s = JS.Types.Number.InfinityNegative;
                }
                else
                {
                    s = emitter.ToJavaScript(value);
                }
            }
            else if (value is char)
            {
                s = emitter.ToJavaScript((int)(char)value);
            }
            else if (value is decimal d)
            {
                var tmp = d.ToString(CultureInfo.InvariantCulture);
                s = JS.Types.SYSTEM_DECIMAL + "(" + AbstractEmitterBlock.DecimalConstant(d, emitter);

                int dot;
                if ((dot = tmp.IndexOf(".")) >= 0)
                {
                    s += ", " + tmp.Substring(dot + 1).Length;
                }

                s += ")";
            }
            else if (value is long)
            {
                s = JS.Types.System.Int64.NAME + "(" + AbstractEmitterBlock.LongConstant((long)value, emitter) + ")";
            }
            else if (value is ulong)
            {
                s = JS.Types.SYSTEM_UInt64 + "(" + AbstractEmitterBlock.ULongConstant((ulong)value, emitter) + ")";
            }
            else
            {
                s = emitter.ToJavaScript(value);
            }
            return(s);
        }
Пример #27
0
        public static string GetInlineInit(KeyValuePair <IMember, ResolveResult> item, AbstractEmitterBlock block)
        {
            string inlineCode = null;
            var    member     = item.Key;

            if (member is IProperty)
            {
                var setter = ((IProperty)member).Setter;
                if (setter != null)
                {
                    inlineCode = block.Emitter.GetInline(setter);
                }
            }
            else
            {
                inlineCode = block.Emitter.GetInline(member);
            }

            if (inlineCode != null)
            {
                bool oldIsAssignment = block.Emitter.IsAssignment;
                bool oldUnary        = block.Emitter.IsUnaryAccessor;
                var  oldWriter       = block.SaveWriter();
                block.NewWriter();
                block.Emitter.IsAssignment    = true;
                block.Emitter.IsUnaryAccessor = false;

                bool hasThis = Helpers.HasThis(inlineCode);
                inlineCode = Helpers.ConvertTokens(block.Emitter, inlineCode, member);
                if (inlineCode.StartsWith("<self>"))
                {
                    hasThis    = true;
                    inlineCode = inlineCode.Substring(6);
                }

                if (hasThis)
                {
                    inlineCode = inlineCode.Replace("{this}", "this");

                    if (member is IProperty)
                    {
                        inlineCode = inlineCode.Replace("{0}", "[[0]]");

                        AttributeCreateBlock.WriteResolveResult(item.Value, block);
                        var value = block.Emitter.Output.ToString();
                        inlineCode = inlineCode.Replace("{value}", value);
                        inlineCode = inlineCode.Replace("[[0]]", "{0}");
                    }
                }
                else
                {
                    if (member.SymbolKind == SymbolKind.Property)
                    {
                        var count = block.Emitter.Writers.Count;
                        block.PushWriter("this." + inlineCode);
                        AttributeCreateBlock.WriteResolveResult(item.Value, block);

                        if (block.Emitter.Writers.Count > count)
                        {
                            inlineCode = block.PopWriter(true);
                        }
                    }
                    else
                    {
                        block.Write("this." + inlineCode);
                    }
                }

                block.Emitter.IsAssignment    = oldIsAssignment;
                block.Emitter.IsUnaryAccessor = oldUnary;
                block.RestoreWriter(oldWriter);
            }

            if (inlineCode != null && !inlineCode.Trim().EndsWith(";"))
            {
                inlineCode += ";";
            }

            return(inlineCode);
        }
Пример #28
0
        public static string GetInlineInit(Expression item, AbstractEmitterBlock block)
        {
            Expression expr = null;

            if (item is NamedExpression)
            {
                var namedExpression = (NamedExpression)item;
                expr = namedExpression.Expression;
            }
            else if (item is NamedArgumentExpression)
            {
                var namedArgumentExpression = (NamedArgumentExpression)item;
                expr = namedArgumentExpression.Expression;
            }

            var    rr         = block.Emitter.Resolver.ResolveNode(item, block.Emitter);
            string inlineCode = null;

            if (expr != null && rr is MemberResolveResult)
            {
                var member = ((MemberResolveResult)rr).Member;

                if (member is IProperty)
                {
                    var setter = ((IProperty)member).Setter;
                    if (setter != null)
                    {
                        inlineCode = block.Emitter.GetInline(setter);
                    }
                }
                else
                {
                    inlineCode = block.Emitter.GetInline(member);
                }

                if (inlineCode != null)
                {
                    bool oldIsAssignment = block.Emitter.IsAssignment;
                    bool oldUnary        = block.Emitter.IsUnaryAccessor;
                    var  oldWriter       = block.SaveWriter();
                    block.NewWriter();
                    block.Emitter.IsAssignment    = true;
                    block.Emitter.IsUnaryAccessor = false;

                    bool hasThis = inlineCode.Contains("{this}");
                    if (inlineCode.StartsWith("<self>"))
                    {
                        hasThis    = true;
                        inlineCode = inlineCode.Substring(6);
                    }

                    if (hasThis)
                    {
                        inlineCode = inlineCode.Replace("{this}", "this");

                        if (member is IProperty)
                        {
                            var argsInfo = new ArgumentsInfo(block.Emitter, item, rr);
                            argsInfo.ArgumentsExpressions = new Expression[] { expr };
                            argsInfo.ArgumentsNames       = new string[] { "value" };
                            argsInfo.ThisArgument         = "this";
                            argsInfo.NamedExpressions     = argsInfo.CreateNamedExpressions(argsInfo.ArgumentsNames, argsInfo.ArgumentsExpressions);

                            inlineCode = inlineCode.Replace("{0}", "[[0]]");
                            new InlineArgumentsBlock(block.Emitter, argsInfo, inlineCode).Emit();
                            inlineCode = block.Emitter.Output.ToString();
                            inlineCode = inlineCode.Replace("[[0]]", "{0}");
                        }
                    }
                    else
                    {
                        if (member.SymbolKind == SymbolKind.Property)
                        {
                            var count = block.Emitter.Writers.Count;
                            block.PushWriter("this." + inlineCode);

                            expr.AcceptVisitor(block.Emitter);

                            if (block.Emitter.Writers.Count > count)
                            {
                                inlineCode = block.PopWriter(true);
                            }
                        }
                        else
                        {
                            block.Write("this." + inlineCode);
                        }
                    }

                    block.Emitter.IsAssignment    = oldIsAssignment;
                    block.Emitter.IsUnaryAccessor = oldUnary;
                    block.RestoreWriter(oldWriter);
                }
            }

            if (inlineCode != null && !inlineCode.Trim().EndsWith(";"))
            {
                inlineCode += ";";
            }

            return(inlineCode);
        }
Пример #29
0
        protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat)
        {
            bool        hasProperties = this.HasProperties(objectName, members);
            int         pos           = 0;
            IWriterInfo writer        = null;
            bool        beginBlock    = false;

            if (hasProperties && objectName != null && !this.IsObjectLiteral)
            {
                beginBlock = true;
                pos        = this.Emitter.Output.Length;
                writer     = this.SaveWriter();
                this.EnsureComma();
                this.Write(objectName);

                this.WriteColon();
                this.BeginBlock();
            }

            bool isProperty = JS.Fields.PROPERTIES == objectName;
            bool isField    = JS.Fields.FIELDS == objectName;
            int  count      = 0;

            foreach (var member in members)
            {
                object constValue    = null;
                bool   isPrimitive   = false;
                var    primitiveExpr = member.Initializer as PrimitiveExpression;
                bool   write         = false;
                bool   writeScript   = false;

                if (primitiveExpr != null)
                {
                    //isPrimitive = true;
                    constValue = primitiveExpr.Value;

                    ResolveResult rr = null;
                    if (member.VarInitializer != null)
                    {
                        rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter);
                    }
                    else
                    {
                        rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter);
                    }

                    if (rr != null && rr.Type.Kind == TypeKind.Enum)
                    {
                        constValue  = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue);
                        writeScript = true;
                    }
                }

                if (constValue is RawValue)
                {
                    constValue  = constValue.ToString();
                    write       = true;
                    writeScript = false;
                }

                var isNull = member.Initializer.IsNull || member.Initializer is NullReferenceExpression || member.Initializer.Parent == null;

                if (!isNull && !isPrimitive)
                {
                    var constrr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter);
                    if (constrr != null && constrr.IsCompileTimeConstant)
                    {
                        //isPrimitive = true;
                        constValue = constrr.ConstantValue;

                        var expectedType = this.Emitter.Resolver.Resolver.GetExpectedType(member.Initializer);
                        if (!expectedType.Equals(constrr.Type) && expectedType.Kind != TypeKind.Dynamic)
                        {
                            try
                            {
                                constValue = Convert.ChangeType(constValue, ReflectionHelper.GetTypeCode(expectedType));
                            }
                            catch (Exception)
                            {
                                this.Emitter.Log.Warn($"FieldBlock: Convert.ChangeType is failed. Value type: {constrr.Type.FullName}, Target type: {expectedType.FullName}");
                            }
                        }

                        if (constrr.Type.Kind == TypeKind.Enum)
                        {
                            constValue = Helpers.GetEnumValue(this.Emitter, constrr.Type, constrr.ConstantValue);
                        }

                        writeScript = true;
                    }
                }

                var isNullable = false;

                if (isPrimitive && constValue is AstType)
                {
                    var itype = this.Emitter.Resolver.ResolveNode((AstType)constValue, this.Emitter);

                    if (NullableType.IsNullable(itype.Type))
                    {
                        isNullable = true;
                    }
                }

                string              tpl            = null;
                IMember             templateMember = null;
                MemberResolveResult init_rr        = null;
                if (isField && member.VarInitializer != null)
                {
                    init_rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter) as MemberResolveResult;
                    tpl     = init_rr != null?this.Emitter.GetInline(init_rr.Member) : null;

                    if (tpl != null)
                    {
                        templateMember = init_rr.Member;
                    }
                }

                bool isAutoProperty = false;

                if (isProperty)
                {
                    var member_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult;
                    var property  = (IProperty)member_rr.Member;
                    isAutoProperty = Helpers.IsAutoProperty(property);
                }

                bool written = false;
                if (!isNull && (!isPrimitive || constValue is AstType || tpl != null) && !(isProperty && !IsObjectLiteral && !isAutoProperty))
                {
                    string value        = null;
                    bool   needContinue = false;
                    string defValue     = "";
                    if (!isPrimitive)
                    {
                        var oldWriter = this.SaveWriter();
                        this.NewWriter();
                        member.Initializer.AcceptVisitor(this.Emitter);
                        value = this.Emitter.Output.ToString();
                        this.RestoreWriter(oldWriter);

                        ResolveResult rr      = null;
                        AstType       astType = null;
                        if (member.VarInitializer != null)
                        {
                            rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter);
                        }
                        else
                        {
                            astType = member.Entity.ReturnType;
                            rr      = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter);
                        }

                        constValue = Inspector.GetDefaultFieldValue(rr.Type, astType);
                        if (rr.Type.Kind == TypeKind.Enum)
                        {
                            constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue);
                        }
                        isNullable   = NullableType.IsNullable(rr.Type);
                        needContinue = constValue is IType;
                        writeScript  = true;

                        /*if (needContinue && !(member.Initializer is ObjectCreateExpression))
                         * {
                         *  defValue = " || " + Inspector.GetStructDefaultValue((IType)constValue, this.Emitter);
                         * }*/
                    }
                    else if (constValue is AstType)
                    {
                        value = isNullable
                            ? "null"
                            : Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter);
                        constValue   = value;
                        write        = true;
                        needContinue = !isProperty && !isNullable;
                    }

                    var name = member.GetName(this.Emitter);

                    bool isValidIdentifier = Helpers.IsValidIdentifier(name);

                    if (isProperty && isPrimitive)
                    {
                        constValue = "null";

                        if (this.IsObjectLiteral)
                        {
                            written = true;
                            if (isValidIdentifier)
                            {
                                this.Write(string.Format("this.{0} = {1};", name, value));
                            }
                            else
                            {
                                this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                            }

                            this.WriteNewLine();
                        }
                        else
                        {
                            this.Injectors.Add(string.Format(name.StartsWith("\"") || !isValidIdentifier ? "this[{0}] = {1};" : "this.{0} = {1};", isValidIdentifier ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                        }
                    }
                    else
                    {
                        if (this.IsObjectLiteral)
                        {
                            written = true;
                            if (isValidIdentifier)
                            {
                                this.Write(string.Format("this.{0} = {1};", name, value + defValue));
                            }
                            else
                            {
                                this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue));
                            }
                            this.WriteNewLine();
                        }
                        else if (tpl != null)
                        {
                            if (!tpl.Contains("{0}"))
                            {
                                tpl = tpl + " = {0};";
                            }

                            string v = null;
                            if (!isNull && (!isPrimitive || constValue is AstType))
                            {
                                v = value + defValue;
                            }
                            else
                            {
                                if (write)
                                {
                                    v = constValue != null?constValue.ToString() : "";
                                }
                                else if (writeScript)
                                {
                                    v = AbstractEmitterBlock.ToJavaScript(constValue, this.Emitter);
                                }
                                else
                                {
                                    var oldWriter = this.SaveWriter();
                                    this.NewWriter();
                                    member.Initializer.AcceptVisitor(this.Emitter);
                                    v = this.Emitter.Output.ToString();
                                    this.RestoreWriter(oldWriter);
                                }
                            }

                            tpl = Helpers.ConvertTokens(this.Emitter, tpl, templateMember);
                            tpl = tpl.Replace("{this}", "this").Replace("{0}", v);

                            if (!tpl.EndsWith(";"))
                            {
                                tpl += ";";
                            }
                            this.Injectors.Add(tpl);
                        }
                        else
                        {
                            var  rr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter) as CSharpInvocationResolveResult;
                            bool isDefaultInstance = rr != null &&
                                                     rr.Member.SymbolKind == SymbolKind.Constructor &&
                                                     rr.Arguments.Count == 0 &&
                                                     rr.InitializerStatements.Count == 0 &&
                                                     rr.Type.Kind == TypeKind.Struct;

                            if (!isDefaultInstance)
                            {
                                if (isField && !isValidIdentifier)
                                {
                                    this.Injectors.Add(string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue));
                                }
                                else
                                {
                                    this.Injectors.Add(string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value + defValue));
                                }
                            }
                        }
                    }
                }

                count++;

                if (written)
                {
                    continue;
                }
                bool withoutTypeParams   = true;
                MemberResolveResult m_rr = null;
                if (member.Entity != null)
                {
                    m_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult;
                    if (m_rr != null)
                    {
                        withoutTypeParams = OverloadsCollection.ExcludeTypeParameterForDefinition(m_rr);
                    }
                }

                var mname = member.GetName(this.Emitter, withoutTypeParams);

                if (this.TypeInfo.IsEnum && m_rr != null)
                {
                    mname = this.Emitter.GetEntityName(m_rr.Member);
                }

                bool isValid = Helpers.IsValidIdentifier(mname);
                if (!isValid)
                {
                    if (this.IsObjectLiteral)
                    {
                        mname = "[" + AbstractEmitterBlock.ToJavaScript(mname, this.Emitter) + "]";
                    }
                    else
                    {
                        mname = AbstractEmitterBlock.ToJavaScript(mname, this.Emitter);
                    }
                }

                if (this.IsObjectLiteral)
                {
                    this.WriteThis();
                    if (isValid)
                    {
                        this.WriteDot();
                    }
                    this.Write(mname);
                    this.Write(" = ");
                }
                else
                {
                    this.EnsureComma();
                    XmlToJsDoc.EmitComment(this, member.Entity, null, member.Entity is FieldDeclaration ? member.VarInitializer : null);
                    this.Write(mname);
                    this.WriteColon();
                }

                bool close = false;
                if (isProperty && !IsObjectLiteral && !isAutoProperty)
                {
                    var oldTempVars = this.Emitter.TempVariables;
                    this.BeginBlock();
                    new VisitorPropertyBlock(this.Emitter, (PropertyDeclaration)member.Entity).Emit();
                    this.WriteNewLine();
                    this.EndBlock();
                    this.Emitter.Comma         = true;
                    this.Emitter.TempVariables = oldTempVars;
                    continue;
                }

                if (constValue is AstType || constValue is IType)
                {
                    this.Write("null");

                    if (!isNullable)
                    {
                        var  name = member.GetName(this.Emitter);
                        bool isValidIdentifier = Helpers.IsValidIdentifier(name);
                        var  value             = constValue is AstType?Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter) : Inspector.GetStructDefaultValue((IType)constValue, this.Emitter);

                        if (!isValidIdentifier)
                        {
                            this.Injectors.Insert(BeginCounter++, string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                        }
                        else
                        {
                            this.Injectors.Insert(BeginCounter++, string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value));
                        }
                    }
                }
                else if (write)
                {
                    this.Write(constValue);
                }
                else if (writeScript)
                {
                    this.WriteScript(constValue);
                }
                else
                {
                    member.Initializer.AcceptVisitor(this.Emitter);
                }

                if (close)
                {
                    this.Write(" }");
                }

                if (this.IsObjectLiteral)
                {
                    this.WriteSemiColon(true);
                }

                this.Emitter.Comma = true;
            }

            if (count > 0 && objectName != null && !IsObjectLiteral)
            {
                this.WriteNewLine();
                this.EndBlock();
            }
            else if (beginBlock)
            {
                this.Emitter.IsNewLine = writer.IsNewLine;
                this.Emitter.ResetLevel(writer.Level);
                this.Emitter.Comma = writer.Comma;

                this.Emitter.Output.Length = pos;
            }

            return(count > 0);
        }
Пример #30
0
        protected void VisitAsyncForStatement()
        {
            ForStatement forStatement   = this.ForStatement;
            var          oldValue       = this.Emitter.ReplaceAwaiterByVar;
            var          jumpStatements = this.Emitter.JumpStatements;

            this.Emitter.JumpStatements = new List <IJumpInfo>();

            this.PushLocals();

            bool newLine = false;

            foreach (var item in forStatement.Initializers)
            {
                if (newLine)
                {
                    this.WriteNewLine();
                }

                item.AcceptVisitor(this.Emitter);
                newLine = true;
            }

            this.RemovePenultimateEmptyLines(true);
            this.WriteNewLine();
            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");

            IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep();

            this.WriteAwaiters(forStatement.Condition);
            this.Emitter.ReplaceAwaiterByVar = true;
            var lastConditionStep = this.Emitter.AsyncBlock.Steps.Last();

            this.WriteIf();
            this.WriteOpenParentheses(true);

            if (!forStatement.Condition.IsNull)
            {
                forStatement.Condition.AcceptVisitor(this.Emitter);
            }
            else
            {
                this.Write("true");
            }

            this.WriteCloseParentheses(true);
            this.Emitter.ReplaceAwaiterByVar = oldValue;

            this.WriteSpace();
            this.BeginBlock();
            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");

            this.EmittedAsyncSteps = this.Emitter.AsyncBlock.EmittedAsyncSteps;
            this.Emitter.AsyncBlock.EmittedAsyncSteps = new List <IAsyncStep>();
            var writer = this.SaveWriter();

            this.Emitter.AsyncBlock.AddAsyncStep();
            this.Emitter.IgnoreBlock = forStatement.EmbeddedStatement;
            var startCount = this.Emitter.AsyncBlock.Steps.Count;

            forStatement.EmbeddedStatement.AcceptVisitor(this.Emitter);
            IAsyncStep loopStep = null;

            if (this.Emitter.AsyncBlock.Steps.Count > startCount)
            {
                loopStep = this.Emitter.AsyncBlock.Steps.Last();
            }

            this.RestoreWriter(writer);

            if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString()))
            {
                this.WriteNewLine();
                this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
                this.WriteNewLine();
                this.Write("continue;");
                this.WriteNewLine();
                this.EndBlock();
                this.WriteSpace();
            }
            else
            {
                this.WriteNewLine();
                this.EndBlock();
                this.WriteSpace();
            }

            if (this.Emitter.IsAsync)
            {
                this.Emitter.AsyncBlock.EmittedAsyncSteps = this.EmittedAsyncSteps;
            }

            IAsyncStep iteratorsStep = this.Emitter.AsyncBlock.AddAsyncStep();

            /*foreach (var item in forStatement.Iterators)
             * {
             *  this.WriteAwaiters(item);
             * }*/

            var lastIteratorStep = this.Emitter.AsyncBlock.Steps.Last();

            if (loopStep != null)
            {
                loopStep.JumpToStep = iteratorsStep.Step;
            }

            lastIteratorStep.JumpToStep      = conditionStep.Step;
            this.Emitter.ReplaceAwaiterByVar = true;

            var beforeStepsCount = this.Emitter.AsyncBlock.Steps.Count;

            foreach (var item in forStatement.Iterators)
            {
                item.AcceptVisitor(this.Emitter);

                if (this.Emitter.Output.ToString().TrimEnd().Last() != ';')
                {
                    this.WriteSemiColon();
                }

                this.WriteNewLine();
            }

            if (beforeStepsCount < this.Emitter.AsyncBlock.Steps.Count)
            {
                this.Emitter.AsyncBlock.Steps.Last().JumpToStep = conditionStep.Step;
            }

            this.Emitter.ReplaceAwaiterByVar = oldValue;

            this.PopLocals();
            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            lastConditionStep.JumpToStep = nextStep.Step;

            if (this.Emitter.JumpStatements.Count > 0)
            {
                this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position));
                foreach (var jump in this.Emitter.JumpStatements)
                {
                    jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : iteratorsStep.Step);
                }
            }

            this.Emitter.JumpStatements = jumpStatements;
        }
Пример #31
0
        protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat)
        {
            bool hasProperties = this.HasProperties(objectName, members);

            if (hasProperties && objectName != null && !this.IsObjectLiteral)
            {
                this.EnsureComma();
                this.Write(objectName);

                this.WriteColon();
                this.BeginBlock();
            }

            bool isProperty = JS.Fields.PROPERTIES == objectName;
            bool isField    = objectName == null;
            int  count      = 0;

            foreach (var member in members)
            {
                object constValue    = null;
                bool   isPrimitive   = false;
                var    primitiveExpr = member.Initializer as PrimitiveExpression;
                bool   write         = false;
                bool   writeScript   = false;

                if (primitiveExpr != null)
                {
                    isPrimitive = true;
                    constValue  = primitiveExpr.Value;

                    ResolveResult rr = null;
                    if (member.VarInitializer != null)
                    {
                        rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter);
                    }
                    else
                    {
                        rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter);
                    }

                    if (rr != null && rr.Type.Kind == TypeKind.Enum)
                    {
                        constValue  = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue);
                        writeScript = true;
                    }
                }

                if (constValue is RawValue)
                {
                    constValue  = constValue.ToString();
                    write       = true;
                    writeScript = false;
                }

                var isNull = member.Initializer.IsNull || member.Initializer is NullReferenceExpression;

                if (!isNull && !isPrimitive)
                {
                    var constrr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter);
                    if (constrr != null && constrr.IsCompileTimeConstant)
                    {
                        isPrimitive = true;
                        constValue  = constrr.ConstantValue;

                        if (constrr.Type.Kind == TypeKind.Enum)
                        {
                            constValue = Helpers.GetEnumValue(this.Emitter, constrr.Type, constrr.ConstantValue);
                        }

                        writeScript = true;
                    }
                }

                var isNullable = false;

                if (isPrimitive && constValue is AstType)
                {
                    var itype = this.Emitter.Resolver.ResolveNode((AstType)constValue, this.Emitter);

                    if (NullableType.IsNullable(itype.Type))
                    {
                        isNullable = true;
                    }
                }

                string tpl = null;
                MemberResolveResult init_rr = null;
                if (isField && member.VarInitializer != null)
                {
                    init_rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter) as MemberResolveResult;
                    tpl     = init_rr != null?this.Emitter.GetInline(init_rr.Member) : null;
                }

                bool written = false;
                if (!isNull && (!isPrimitive || constValue is AstType || tpl != null))
                {
                    string value        = null;
                    bool   needContinue = false;
                    string defValue     = "";
                    if (!isPrimitive)
                    {
                        var oldWriter = this.SaveWriter();
                        this.NewWriter();
                        member.Initializer.AcceptVisitor(this.Emitter);
                        value = this.Emitter.Output.ToString();
                        this.RestoreWriter(oldWriter);

                        ResolveResult rr      = null;
                        AstType       astType = null;
                        if (member.VarInitializer != null)
                        {
                            rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter);
                        }
                        else
                        {
                            astType = member.Entity.ReturnType;
                            rr      = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter);
                        }

                        constValue = Inspector.GetDefaultFieldValue(rr.Type, astType);
                        if (rr.Type.Kind == TypeKind.Enum)
                        {
                            constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue);
                        }
                        isNullable   = NullableType.IsNullable(rr.Type);
                        needContinue = constValue is IType;
                        writeScript  = true;

                        if (needContinue && !(member.Initializer is ObjectCreateExpression))
                        {
                            defValue = " || " + Inspector.GetStructDefaultValue((IType)constValue, this.Emitter);
                        }
                    }
                    else if (constValue is AstType)
                    {
                        value = isNullable
                            ? "null"
                            : Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter);
                        constValue   = value;
                        write        = true;
                        needContinue = !isProperty && !isNullable;
                    }

                    var name = member.GetName(this.Emitter);

                    bool isValidIdentifier = Helpers.IsValidIdentifier(name);

                    if (isProperty && isPrimitive)
                    {
                        constValue = "null";

                        if (this.IsObjectLiteral)
                        {
                            written = true;
                            if (isValidIdentifier)
                            {
                                this.Write(string.Format("this.{0} = {1};", name, value));
                            }
                            else
                            {
                                this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                            }

                            this.WriteNewLine();
                        }
                        else
                        {
                            this.Injectors.Add(string.Format(name.StartsWith("\"") || !isValidIdentifier ? "this[{0}] = {1};" : "this.{0} = {1};", isValidIdentifier ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value));
                        }
                    }
                    else
                    {
                        if (this.IsObjectLiteral)
                        {
                            written = true;
                            if (isValidIdentifier)
                            {
                                this.Write(string.Format("this.{0} = {1};", name, value + defValue));
                            }
                            else
                            {
                                this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue));
                            }
                            this.WriteNewLine();
                        }
                        else if (tpl != null)
                        {
                            if (!tpl.Contains("{0}"))
                            {
                                tpl = tpl + " = {0};";
                            }

                            string v = null;
                            if (!isNull && (!isPrimitive || constValue is AstType))
                            {
                                v = value + defValue;
                            }
                            else
                            {
                                if (write)
                                {
                                    v = constValue != null?constValue.ToString() : "";
                                }
                                else if (writeScript)
                                {
                                    v = AbstractEmitterBlock.ToJavaScript(constValue, this.Emitter);
                                }
                                else
                                {
                                    var oldWriter = this.SaveWriter();
                                    this.NewWriter();
                                    member.Initializer.AcceptVisitor(this.Emitter);
                                    v = this.Emitter.Output.ToString();
                                    this.RestoreWriter(oldWriter);
                                }
                            }

                            tpl = tpl.Replace("{this}", "this").Replace("{0}", v);

                            if (!tpl.EndsWith(";"))
                            {
                                tpl += ";";
                            }
                            this.Injectors.Add(tpl);
                        }
                        else
                        {
                            if (isField && !isValidIdentifier)
                            {
                                this.Injectors.Add(string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue));
                            }
                            else
                            {
                                this.Injectors.Add(string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value + defValue));
                            }
                        }
                    }

                    if (needContinue || tpl != null)
                    {
                        continue;
                    }
                }

                count++;

                if (written)
                {
                    continue;
                }

                var mname = member.GetName(this.Emitter, true);

                bool isValid = Helpers.IsValidIdentifier(mname);
                if (!isValid)
                {
                    if (this.IsObjectLiteral)
                    {
                        mname = "[" + AbstractEmitterBlock.ToJavaScript(mname, this.Emitter) + "]";
                    }
                    else
                    {
                        mname = AbstractEmitterBlock.ToJavaScript(mname, this.Emitter);
                    }
                }

                if (this.IsObjectLiteral)
                {
                    this.WriteThis();
                    if (isValid)
                    {
                        this.WriteDot();
                    }
                    this.Write(mname);
                    this.Write(" = ");
                }
                else
                {
                    this.EnsureComma();
                    XmlToJsDoc.EmitComment(this, member.Entity);
                    this.Write(mname);
                    this.WriteColon();
                }

                if (constValue is AstType)
                {
                    if (isNullable)
                    {
                        this.Write("null");
                    }
                    else
                    {
                        this.Write(Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter));
                    }
                }
                else if (constValue is IType)
                {
                    if (isNullable)
                    {
                        this.Write("null");
                    }
                    else
                    {
                        this.Write(Inspector.GetStructDefaultValue((IType)constValue, this.Emitter));
                    }
                }
                else if (write)
                {
                    this.Write(constValue);
                }
                else if (writeScript)
                {
                    this.WriteScript(constValue);
                }
                else
                {
                    member.Initializer.AcceptVisitor(this.Emitter);
                }

                if (this.IsObjectLiteral)
                {
                    this.WriteSemiColon(true);
                }

                this.Emitter.Comma = true;
            }

            if (count > 0 && objectName != null)
            {
                this.WriteNewLine();
                this.EndBlock();
            }

            return(count > 0);
        }
Пример #32
0
        protected void InjectSteps()
        {
            foreach (var label in this.JumpLabels)
            {
                var tostep = this.Steps.First(s => s.Node == label.Node);
                label.Output.Replace(Helpers.PrefixDollar("{", label.Node.GetHashCode(), "}"), tostep.Step.ToString());
            }

            for (int i = 0; i < this.Steps.Count; i++)
            {
                var step = this.Steps[i];

                if (i != 0)
                {
                    this.WriteNewLine();
                }

                var output = step.Output.ToString();

                if (string.IsNullOrWhiteSpace(output) && step.JumpToStep == (i + 1) && step.FromTaskNumber < 0)
                {
                    continue;
                }

                this.Write("case " + i + ": ");

                this.BeginBlock();

                bool addNewLine = false;

                if (step.FromTaskNumber > -1)
                {
                    var expression = this.AwaitExpressions[step.FromTaskNumber - 1];

                    if (this.IsTaskResult(expression))
                    {
                        this.Write(string.Format("{0}{1} = {2}{1}.{3}();", JS.Vars.ASYNC_TASK_RESULT, step.FromTaskNumber, JS.Vars.ASYNC_TASK, JS.Funcs.GET_AWAITED_RESULT));
                    }
                    else
                    {
                        this.Write(string.Format("{0}{1}.{2}();", JS.Vars.ASYNC_TASK, step.FromTaskNumber, JS.Funcs.GET_AWAITED_RESULT));
                    }

                    addNewLine = true;
                }

                if (!string.IsNullOrWhiteSpace(output))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write(this.WriteIndentToString(output.TrimEnd()));
                }

                if (!this.IsOnlyWhitespaceOnPenultimateLine(false))
                {
                    addNewLine = true;
                }

                if (step.JumpToStep > -1 && !AbstractEmitterBlock.IsJumpStatementLast(output))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write(JS.Vars.ASYNC_STEP + " = " + step.JumpToStep + ";");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else if (step.JumpToNode != null && !AbstractEmitterBlock.IsJumpStatementLast(output))
                {
                    var tostep = this.Steps.First(s => s.Node == step.JumpToNode);

                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write(JS.Vars.ASYNC_STEP + " = " + tostep.Step + ";");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else if (i == (this.Steps.Count - 1) && !AbstractEmitterBlock.IsReturnLast(output))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    if (this.IsTaskReturn)
                    {
                        this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_RESULT + "(null);");
                        this.WriteNewLine();
                    }

                    this.Write("return;");
                }

                this.WriteNewLine();
                this.EndBlock();
            }

            this.WriteNewLine();
            this.Write("default: ");
            this.BeginBlock();

            if (this.IsTaskReturn)
            {
                this.Write(JS.Vars.ASYNC_TCS + "." + JS.Funcs.SET_RESULT + "(null);");
                this.WriteNewLine();
            }

            this.Write("return;");
            this.WriteNewLine();
            this.EndBlock();
        }
Пример #33
0
        protected void InjectSteps()
        {
            foreach (var label in this.JumpLabels)
            {
                var tostep = this.Steps.First(s => s.Node == label.Node);
                label.Output.Replace(Helpers.PrefixDollar("{", label.Node.GetHashCode(), "}"), tostep.Step.ToString());
            }

            for (int i = 0; i < this.Steps.Count; i++)
            {
                var step = this.Steps[i];

                if (i != 0)
                {
                    this.WriteNewLine();
                }

                var output      = step.Output.ToString();
                var cleanOutput = this.RemoveTokens(output);

                this.Write("case " + i + ": ");

                this.BeginBlock();

                bool addNewLine = false;

                if (!string.IsNullOrWhiteSpace(cleanOutput))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write(this.WriteIndentToString(output.TrimEnd()));
                }

                if (!this.IsOnlyWhitespaceOnPenultimateLine(false))
                {
                    addNewLine = true;
                }

                if (step.JumpToStep > -1 && !AbstractEmitterBlock.IsJumpStatementLast(cleanOutput))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write(JS.Vars.ASYNC_STEP + " = " + step.JumpToStep + ";");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else if (step.JumpToNode != null && !AbstractEmitterBlock.IsJumpStatementLast(cleanOutput))
                {
                    var tostep = this.Steps.First(s => s.Node == step.JumpToNode);

                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }

                    this.Write(JS.Vars.ASYNC_STEP + " = " + tostep.Step + ";");
                    this.WriteNewLine();
                    this.Write("continue;");
                }
                else if (i == (this.Steps.Count - 1) && !AbstractEmitterBlock.IsReturnLast(cleanOutput))
                {
                    if (addNewLine)
                    {
                        this.WriteNewLine();
                    }
                }

                this.WriteNewLine();
                this.EndBlock();
            }

            this.WriteNewLine();
            this.Write("default: ");
            this.BeginBlock();

            this.Write("return false;");
            this.WriteNewLine();
            this.EndBlock();
        }
Пример #34
0
        protected void VisitAsyncForeachStatement()
        {
            ForeachStatement foreachStatement = this.ForeachStatement;

            if (foreachStatement.EmbeddedStatement is EmptyStatement)
            {
                return;
            }

            var oldValue       = this.Emitter.ReplaceAwaiterByVar;
            var jumpStatements = this.Emitter.JumpStatements;

            this.Emitter.JumpStatements = new List <IJumpInfo>();
            this.WriteAwaiters(foreachStatement.InExpression);

            bool containsAwaits = false;
            var  awaiters       = this.GetAwaiters(foreachStatement.EmbeddedStatement);

            if (awaiters != null && awaiters.Length > 0)
            {
                containsAwaits = true;
            }

            this.Emitter.ReplaceAwaiterByVar = true;

            if (!containsAwaits)
            {
                this.VisitForeachStatement(oldValue);
                return;
            }

            //var iteratorName = this.GetNextIteratorName();
            var iteratorName = this.AddLocal(this.GetTempVarName(), null, AstType.Null);

            //this.WriteVar();
            this.Write(iteratorName, " = ", JS.Funcs.BRIDGE_GET_ENUMERATOR);

            this.WriteOpenParentheses();
            foreachStatement.InExpression.AcceptVisitor(this.Emitter);
            this.Emitter.ReplaceAwaiterByVar = oldValue;
            this.WriteCloseParentheses();
            this.WriteSemiColon();
            this.WriteNewLine();
            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");
            this.WriteNewLine();

            IAsyncStep conditionStep = this.Emitter.AsyncBlock.AddAsyncStep();

            this.WriteIf();
            this.WriteOpenParentheses();
            this.Write(iteratorName);
            this.WriteDot();
            this.Write(JS.Funcs.MOVE_NEXT);
            this.WriteOpenCloseParentheses();
            this.WriteCloseParentheses();
            this.WriteSpace();
            this.BeginBlock();

            this.PushLocals();
            var varName = this.AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType);

            this.WriteVar();
            this.Write(varName, " = ", iteratorName);

            this.WriteDot();
            this.Write(JS.Funcs.GET_CURRENT);

            this.WriteOpenCloseParentheses();
            this.WriteSemiColon();
            this.WriteNewLine();

            this.Write(JS.Vars.ASYNC_STEP + " = " + this.Emitter.AsyncBlock.Step + ";");
            this.WriteNewLine();
            this.Write("continue;");

            BlockStatement block = foreachStatement.EmbeddedStatement as BlockStatement;

            var writer = this.SaveWriter();

            this.Emitter.AsyncBlock.AddAsyncStep();
            this.Emitter.IgnoreBlock = foreachStatement.EmbeddedStatement;
            var startCount = this.Emitter.AsyncBlock.Steps.Count;

            if (block != null)
            {
                block.AcceptChildren(this.Emitter);
            }
            else
            {
                foreachStatement.EmbeddedStatement.AcceptVisitor(this.Emitter);
            }

            IAsyncStep loopStep = null;

            if (this.Emitter.AsyncBlock.Steps.Count > startCount)
            {
                loopStep            = this.Emitter.AsyncBlock.Steps.Last();
                loopStep.JumpToStep = conditionStep.Step;
            }

            this.RestoreWriter(writer);

            if (!AbstractEmitterBlock.IsJumpStatementLast(this.Emitter.Output.ToString()))
            {
                this.Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";");
                this.WriteNewLine();
                this.Write("continue;");
                this.WriteNewLine();
            }

            this.PopLocals();

            this.WriteNewLine();
            this.EndBlock();
            this.WriteNewLine();

            var nextStep = this.Emitter.AsyncBlock.AddAsyncStep();

            conditionStep.JumpToStep = nextStep.Step;

            if (this.Emitter.JumpStatements.Count > 0)
            {
                this.Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position));
                foreach (var jump in this.Emitter.JumpStatements)
                {
                    jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step);
                }
            }

            this.Emitter.JumpStatements = jumpStatements;
        }