Ejemplo n.º 1
0
 public void VisitNode(JSExpressionStatement es)
 {
     try {
         VisitChildren(es);
     } catch (Exception exc) {
         Console.WriteLine("// Error in statement");
         Console.WriteLine("// {0}", es);
         throw;
     }
 }
Ejemplo n.º 2
0
        public void BuildLabelGroups(JSFunctionExpression function)
        {
            // If a label is applied to the first statement in a block, hoist it upward
            //  onto the parent block.
            var lh = new LabelHoister();

            do
            {
                lh.HoistedALabel = false;
                lh.Visit(function);
            } while (lh.HoistedALabel);

            // Walk the function to build our list of labels and gotos.
            Visit(function);

            // When a goto crosses block boundaries, we need to move the target label
            //  upwards so that the goto can reach it.
            foreach (var g in Gotos)
            {
                var targetLabel = Labels[g.TargetLabel];

                if (targetLabel.EnclosingBlock.Depth > g.EnclosingBlock.Depth)
                {
                    targetLabel.EnclosingBlock = g.EnclosingBlock;
                }
            }

            foreach (var l in Labels.Values)
            {
                l.EnsureLabelGroupExists(LabelGroups);

                var replacementGoto = new JSExpressionStatement(
                    new JSGotoExpression(l.LabelledStatement.Label)
                    );
                l.EnclosingBlock.Block.ReplaceChildRecursive(l.LabelledStatement, replacementGoto);

                l.LabelGroup.Add(l.LabelledStatement);
            }

            // If a label group only contains one label (plus an entry label),
            //  and it has a parent label group, hoist the label up.
            var lgs = new LabelGroupFlattener();

            do
            {
                lgs.FlattenedAGroup = false;
                lgs.Visit(function);
            } while (lgs.FlattenedAGroup);

            // Remove any labels within a label group that contain no statements (as long
            //  as no goto targets that label directly). This will prune empty entry/exit labels.
            var elr = new EmptyLabelRemover(UsedLabels);

            elr.Visit(function);
        }
Ejemplo n.º 3
0
        public void VisitNode(JSExpressionStatement es)
        {
            var invocationExpression = es.Expression as JSInvocationExpression;

            if (invocationExpression != null)
            {
                var replacement = MaybeReplaceInvocation(invocationExpression);
                if (replacement != null)
                {
                    ParentNode.ReplaceChild(es, replacement);
                    VisitReplacement(replacement);
                    return;
                }
            }

            VisitChildren(es);
        }
Ejemplo n.º 4
0
        public void VisitNode(JSExpressionStatement statement)
        {
            bool isNull = (statement.IsNull ||
                           statement.Expression.IsNull) &&
                          !(statement.Expression is JSUntranslatableExpression) &&
                          !(statement.Expression is JSIgnoredMemberReference);

            Visit(statement.Expression);

            if (!isNull &&
                ((BlockStack.Count == 0) ||
                 (BlockStack.Peek() != BlockType.ForHeader))
                )
            {
                Output.Semicolon();
            }
        }
Ejemplo n.º 5
0
        public void BuildLabelGroups()
        {
            foreach (var g in Gotos)
            {
                var targetLabel = Labels[g.TargetLabel];
                if (targetLabel.EnclosingBlock.Depth > g.EnclosingBlock.Depth)
                {
                    targetLabel.EnclosingBlock = g.EnclosingBlock;
                }
            }

            foreach (var l in Labels.Values)
            {
                l.EnsureLabelGroupExists(LabelGroups);

                var replacementGoto = new JSExpressionStatement(
                    new JSGotoExpression(l.LabelledStatement.Label)
                    );
                l.EnclosingBlock.Block.ReplaceChildRecursive(l.LabelledStatement, replacementGoto);
                l.LabelGroup.Add(l.LabelledStatement);
            }
        }
        protected void TransformVariableIntoReference(JSVariable variable, JSVariableDeclarationStatement statement, int declarationIndex, JSBlockStatement enclosingBlock)
        {
            var oldDeclaration    = statement.Declarations[declarationIndex];
            var valueType         = oldDeclaration.Right.GetActualType(JSIL.TypeSystem);
            var newVariable       = variable.Reference();
            var enclosingFunction = Stack.OfType <JSFunctionExpression>().First();

            JSExpression initialValue;

            // If the declaration was in function scope originally we can hoist the initial value
            //  into our new variable declaration. If not, we need to initialize the ref variable
            //  to the default value for its type. It will get the correct value assigned later.
            if (enclosingBlock == enclosingFunction.Body)
            {
                initialValue = oldDeclaration.Right;
            }
            else
            {
                initialValue = new JSDefaultValueLiteral(valueType);
            }

            var newDeclaration = new JSVariableDeclarationStatement(new JSBinaryOperatorExpression(
                                                                        JSOperator.Assignment,
                                                                        // We have to use a constructed ref to the variable here, otherwise
                                                                        //  the declaration will look like 'var x.value = foo'
                                                                        new JSVariable(variable.Identifier, variable.IdentifierType, variable.Function),
                                                                        JSIL.NewReference(initialValue),
                                                                        newVariable.IdentifierType
                                                                        ));

            if (Tracing)
            {
                Console.WriteLine(String.Format("Transformed {0} into {1} in {2}", variable, newVariable, statement));
            }

            // Insert the new declaration directly before the top-level block containing the original
            //  declaration. This ensures that if its initial value has a dependency on external state,
            //  the declaration will not precede the values it depends on.
            // Note that for declarations that were hoisted out of inner blocks (conditionals, loops)
            //  it doesn't actually matter where the insert occurs, since we initialize with a default
            //  value in that case.
            enclosingFunction.Body.InsertNearChildRecursive(
                statement, newDeclaration, 0
                );

            // If the reference is being declared in function scope, it doesn't need a separate assignment
            //  for its initialization. Otherwise, we need to insert an assignment after the original variable
            //  declaration statement to ensure that the reference variable is initialized to the right value
            //  at the exact right point in the function's execution.
            if (enclosingBlock != enclosingFunction.Body)
            {
                var newAssignment = new JSExpressionStatement(
                    new JSBinaryOperatorExpression(
                        JSOperator.Assignment, newVariable, oldDeclaration.Right, valueType
                        )
                    );
                var insertLocation = enclosingBlock.Statements.IndexOf(statement) + 1;
                enclosingBlock.Statements.Insert(insertLocation, newAssignment);
            }

            Variables[variable.Identifier] = newVariable;
            statement.Declarations.RemoveAt(declarationIndex);
            TransformedVariables.Add(variable.Identifier);
        }
Ejemplo n.º 7
0
 public void VisitNode(JSExpressionStatement es)
 {
     base.VisitNode(es);
 }