コード例 #1
0
        void ExportNamespace(JsUnit unit, string ns)
        {
            var Writer = new StringWriter();

            if (ns.IsNotNullOrEmpty())
            {
                var tokens = ns.Split('.');
                for (var i = 0; i < tokens.Length; i++)
                {
                    var         ns2 = tokens.Take(i + 1).StringJoin(".");
                    JsStatement st;
                    if (i == 0)
                    {
                        st = Js.Var(ns2, Js.Json()).Statement();
                    }
                    else
                    {
                        st = Js.Member(ns2).Assign(Js.Json()).Statement();
                    }
                    var st2 = Js.If(Js.Typeof(Js.Member(ns2)).Equal(Js.String("undefined"))).Then(st);
                    unit.Statements.Add(st2);
                    st2.AddAnnotation(new NamespaceVerificationAnnotation {
                        Namespace = ns2
                    });                                                                        //.Ex(true).NamespaceVerification = ns2;
                }
            }
        }
コード例 #2
0
        public override void VisitIfStatement(IfStatementSyntax node)
        {
            var afterIfState = GetNextState();
            var ifTrueState  = GetNextState();
            var ifFalseState = node.Else != null?GetNextState() : null;

            var newIfStatement = Js.If(
                (JsExpression)node.Condition.Accept(Transformer),
                GotoStateBlock(ifTrueState));

            if (node.Else != null)
            {
                newIfStatement.IfFalse = GotoStateBlock(ifFalseState);
            }

            CurrentState.Add(newIfStatement);
            GotoState(afterIfState);

            CurrentState = ifTrueState;
            AcceptStatement(node.Statement);
            GotoState(afterIfState);

            if (ifFalseState != null)
            {
                CurrentState = ifFalseState;
                AcceptStatement(node.Else.Statement);
                GotoState(afterIfState);
            }

            CurrentState = afterIfState;
        }
コード例 #3
0
        public void TestMethod1()
        {
            var x = Js.Variable("x");
            var y = Js.Variable("y");

            var t = Js.Assign(
                Js.Variable("fn"),
                Js.Function(new [] {
                Js.If(
                    Js.Equality(x, y),
                    Js.MultiplyAssign(x, y))
            }, "x", "y")
                );
        }
コード例 #4
0
            public override JsNode VisitAwaitExpression(AwaitExpressionSyntax node)
            {
                var operand = (JsExpression)node.Expression.Accept(this);

/*
 *              var expressionInfo = stateGenerator.Transformer.model.GetAwaitExpressionInfo(node);
 *              if (expressionInfo.GetResultMethod == null)
 *              {
 *                  var classText = node.FirstAncestorOrSelf<ClassDeclarationSyntax>().NormalizeWhitespace().ToString();
 *                  var diagnostics = model.GetDiagnostics().Select(x => x.ToString()).ToArray();
 *              }
 *
 *              var returnsVoid = expressionInfo.GetResultMethod.ReturnsVoid;
 */
                var expressionInfo    = stateGenerator.Transformer.model.GetTypeInfo(node).ConvertedType;
                var returnsVoid       = expressionInfo.SpecialType == SpecialType.System_Void;
                var operandType       = model.GetTypeInfo(node.Expression).ConvertedType;
                var awaiterMethodName = ((INamedTypeSymbol)operandType).GetMethodByName("GetAwaiter").GetMemberName();

                // Store the awaiter in a field
                var awaiterIdentifier = stateGenerator.HoistVariable(new LiftedVariableKey("$awaiter"));
                var awaiter           = awaiterIdentifier.GetReference();

                stateGenerator.CurrentState.Add(awaiter.Assign(operand.Member(awaiterMethodName).Invoke()).Express());

                var nextState = stateGenerator.InsertState();

                JsExpression result = null;

                if (!returnsVoid)
                {
                    // If the await returns a value, store it in a field
                    var resultIdentifier = stateGenerator.HoistVariable(new LiftedVariableKey("$result"));
                    result = resultIdentifier.GetReference();

                    // Make sure the field gets set from the awaiter at the beginning of the next state.
                    nextState.Add(result.Assign(awaiter.Member("GetResult").Invoke()).Express());
                }
                else
                {
                    // We still need to call GetResult even if void in order to propagate exceptions
                    nextState.Add(awaiter.Member("GetResult").Invoke().Express());
                }

                // Set the state to the next state
                stateGenerator.CurrentState.Add(stateGenerator.ChangeState(nextState));

                stateGenerator.CurrentState.Add(Js.If(
                                                    awaiter.Member("get_IsCompleted").Invoke(),

                                                    // If the awaiter is already completed, go to the next state
                                                    stateGenerator.GotoTop(),

                                                    // Otherwise await for completion
                                                    Js.Block(
                                                        // Start the async process
                                                        Js.Reference(builder)
                                                        .Member("TrueAwaitOnCompleted")
                                                        .Invoke(awaiterIdentifier.GetReference(), Js.Reference(stateMachine))
                                                        .Express(),
                                                        Js.Return()
                                                        )
                                                    ));

                stateGenerator.CurrentState = nextState;

                return(result ?? Js.Null());
            }
コード例 #5
0
 public MemberConverter_Clr()
 {
     VerifyJsTypesArrayStatement = Js.If(Js.Typeof(Js.Member("JsTypes")).Equal(Js.String("undefined"))).Then(Js.Var("JsTypes", Js.NewJsonArray()).Statement());
     VerifyJsTypesArrayStatement.AddAnnotation(new VerifyJsTypesArrayStatementAnnotation());
 }
コード例 #6
0
        public override void VisitUsingStatement(UsingStatementSyntax node)
        {
            var afterTry        = GetNextState();
            var newTryStatement = Js.Try();

            // Keep track of exception, if any, so we can rethrow
            var exceptionIdentifier = HoistVariable(new LiftedVariableKey("$usingex"));

            // Identifier for caught exception
            var caughtExceptionIdentifier = UniqueName("$caughtex");

            // Hoist the variable into a field
            var disposables = new List <JsExpression>();

            if (node.Declaration != null)
            {
                foreach (var variable in node.Declaration.Variables)
                {
                    var symbol     = (ILocalSymbol)Transformer.Model.GetDeclaredSymbol(variable);
                    var identifier = HoistVariable(new LiftedVariableKey(variable.Identifier, symbol));
                    var name       = identifier.GetReference();
                    disposables.Add(name);
                    CurrentState.Add(name.Assign((JsExpression)variable.Initializer.Value.Accept(Transformer)).Express());
                }
            }
            if (node.Expression != null)
            {
                var identifier = Js.Reference(UniqueName("$using"));
                disposables.Add(identifier);
                CurrentState.Add(identifier.Assign((JsExpression)node.Expression.Accept(Transformer)).Express());
            }

            var tryState = NewSubstate();

            GotoState(tryState);

            var finallyState = GetNextState();

            CurrentState = finallyState;
            foreach (var disposable in disposables)
            {
                CurrentState.Add(disposable.Member("Dispose").Invoke().Express());
            }
            CurrentState.Add(Js.If(exceptionIdentifier.GetReference().NotEqualTo(Js.Null()), Js.Throw(exceptionIdentifier.GetReference())));
            GotoState(afterTry);
            newTryStatement.Catch      = Js.Catch(Js.Variable(caughtExceptionIdentifier));
            newTryStatement.Catch.Body = Js.Block(
                new[] { exceptionIdentifier.GetReference().Assign(Js.Reference(caughtExceptionIdentifier)).Express() }
                .Concat(GotoStateStatements(finallyState))
                .ToArray()
                );

            tryState.Wrap = switchStatement =>
            {
                newTryStatement.Body = Js.Block(switchStatement);
                return(newTryStatement);
            };

            StartSubstate(tryState);
            AcceptStatement(node.Statement);
            GotoState(finallyState);
            EndSubstate();

            CurrentState = afterTry;
        }
コード例 #7
0
        public override void VisitTryStatement(TryStatementSyntax node)
        {
            var afterTry        = GetNextState();
            var newTryStatement = Js.Try();

            var tryState = NewSubstate();

            GotoState(tryState);

            // Keep track of exception, if any, so we can rethrow
            var exceptionIdentifier = HoistVariable(new LiftedVariableKey("$ex"));
            var exceptionVariable   = UniqueName("$caughtex");

            State finallyState = node.Finally == null ? null : GetNextState();

            // Declare a block to store all the catch statements the try statement's only catch clause. (No
            // type-specific catch clauses in Javascript
            var catchBlock = Js.Block();

            // Make sure that the exception is stored in a variable accessible to the entire state machine.
            catchBlock.Express(exceptionIdentifier.GetReference().Assign(Js.Reference(exceptionVariable)));

            foreach (var catchClause in node.Catches)
            {
                // Get the symbol that represents the exception declaration (identifier and type)
                var symbol        = Transformer.Model.GetDeclaredSymbol(catchClause.Declaration);
                var exceptionType = symbol == null ? null : symbol.Type;
                if (exceptionType == null && catchClause.Declaration != null && catchClause.Declaration.Type != null)
                {
                    exceptionType = (ITypeSymbol)Transformer.Model.GetSymbolInfo(catchClause.Declaration.Type).Symbol;
                }

                // True if it is actually declaring the variable (as opposed to a catch clause that specifies
                // merely an exception type
                var hasDeclaration = catchClause.Declaration.Identifier.Kind() != SyntaxKind.None;

                // A variable to store the new unique identifier to store the exception
                IJsDeclaration newIdentifier;

                // Hoist the variable into a field
                if (hasDeclaration)
                {
                    newIdentifier = HoistVariable(new LiftedVariableKey(catchClause.Declaration.Identifier, symbol));
                }
                else
                {
                    newIdentifier = HoistVariable(new LiftedVariableKey(SyntaxFactory.Identifier("ex")));
                }

                // Collect all the catch statements into the catchState by making that state current
                var catchState = GetNextState();
                CurrentState = catchState;
                AcceptStatement(catchClause.Block);

                // Add onto the catch state some commands to go to the next state.
                if (finallyState != null)
                {
                    GotoState(finallyState);
                }
                else
                {
                    GotoState(afterTry);
                }

                // Create the statements that will live in the actual catch handler, which directs the logic
                // to the actual catch state and also stores the exception in the correct identifier.
                var thisCatchStatements = Js.Block();
                thisCatchStatements.Express(newIdentifier.SetReference().Assign(exceptionIdentifier.GetReference()));

                // Apply filter if present
                if (catchClause.Filter != null)
                {
                    var filter = (JsExpression)catchClause.Filter.FilterExpression.Accept(Transformer);
                    thisCatchStatements.Add(Js.If(filter, Js.Block(GotoStateStatements(catchState))));
                }
                else
                {
                    thisCatchStatements.AddRange(GotoStateStatements(catchState));
                }

                // Only do the above if the current exception is of the type expected by the catch handler.
                var condition = Idioms.Is(exceptionIdentifier.GetReference(), exceptionType);
                catchBlock.Add(Js.If(condition, thisCatchStatements));
            }
            if (node.Finally != null)
            {
                // Collect the statements of the finally block into the finally state
                CurrentState = finallyState;
                AcceptStatement(node.Finally.Block);

                // If the exception object is not null, then rethrow it.  In other words, if this is a finally
                // clause that has responded to an exception, we need to propagate the exception rather than
                // continue after the try statement.  Otherwise, go to the code after the try block.
                CurrentState.Add(Js.If(exceptionIdentifier.GetReference().NotEqualTo(Js.Null()),
                                       Js.Throw(exceptionIdentifier.GetReference()),
                                       Js.Block(GotoStateStatements(afterTry))));

                // Finally, at the very end of the catch clause (and we can only get here if the logic didn't break
                // out as it would with the logic in the catch handlers) go to the finally state.
                catchBlock.AddRange(GotoStateStatements(finallyState).ToArray());
            }
            catchBlock.Add(Js.Throw(exceptionIdentifier.GetReference()));

            newTryStatement.Catch      = Js.Catch(Js.Variable(exceptionVariable));
            newTryStatement.Catch.Body = catchBlock;
            tryState.Wrap = switchStatement =>
            {
                newTryStatement.Body = Js.Block(switchStatement);
                return(newTryStatement);
            };

            StartSubstate(tryState);
            AcceptStatement(node.Block);
            if (node.Finally != null)
            {
                GotoState(finallyState);
            }
            else
            {
                GotoState(afterTry);
            }
            EndSubstate();

            CurrentState = afterTry;
        }