예제 #1
0
        protected JSVariable GetConstructedReference(JSPassByReferenceExpression pbr)
        {
            JSVariable   referentVariable;
            JSExpression referent;

            if (!JSReferenceExpression.TryMaterialize(JSIL, pbr.Referent, out referent))
            {
                // If the reference can be dereferenced, but cannot be materialized, it is
                //  a constructed reference.
                if (JSReferenceExpression.TryDereference(JSIL, pbr.Referent, out referent))
                {
                    referentVariable = referent as JSVariable;

                    // Ignore variables we previously transformed.
                    if ((referentVariable != null) && TransformedVariables.Contains(referentVariable.Identifier))
                    {
                        return(null);
                    }

                    return(referentVariable);
                }
                else
                {
                    return(null);
                }
            }

            referentVariable = referent as JSVariable;
            if (referentVariable == null)
            {
                return(null);
            }

            // Ignore variables we previously transformed.
            if (TransformedVariables.Contains(referentVariable.Identifier))
            {
                return(null);
            }

            // If the variable does not match the one in the dictionary, it is a constructed
            //  reference to a parameter.
            if (!referentVariable.Equals(Variables[referentVariable.Identifier]))
            {
                // If the parameter is a reference, we don't care about it.
                if (Variables[referentVariable.Identifier].IsReference)
                {
                    return(null);
                }
                else
                {
                    return(referentVariable);
                }
            }

            return(null);
        }
예제 #2
0
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            JSExpression left;

            if (!JSReferenceExpression.TryDereference(JSIL, boe.Left, out left))
            {
                left = boe.Left;
            }

            var leftVar        = left as JSVariable;
            var leftChangeType = left as JSChangeTypeExpression;

            if (leftChangeType != null)
            {
                leftVar = leftChangeType.Expression as JSVariable;
            }

            if (
                !(ParentNode is JSVariableDeclarationStatement) &&
                (leftVar != null) &&
                (leftVar.Identifier == Variable.Identifier)
                )
            {
                if (boe.Operator is JSAssignmentOperator)
                {
                    var replacement = new JSWriteThroughReferenceExpression(
                        Variable, boe.Right
                        );
                    ParentNode.ReplaceChild(boe, replacement);
                    VisitReplacement(replacement);
                }
                else
                {
                    VisitChildren(boe);
                }
            }
            else if (ParentNode is JSVariableDeclarationStatement)
            {
                // Don't walk through the left-hand side of variable declarations.
                VisitChildren(
                    boe,
                    (node, name) => name != "Left"
                    );
            }
            else
            {
                VisitChildren(boe);
            }
        }
        public void VisitNode(JSUnaryOperatorExpression uoe)
        {
            JSExpression expr;

            if (!JSReferenceExpression.TryDereference(JSIL, uoe.Expression, out expr))
            {
                expr = uoe.Expression;
            }

            var eVar        = expr as JSVariable;
            var eChangeType = expr as JSChangeTypeExpression;

            if (eChangeType != null)
            {
                eVar = eChangeType.Expression as JSVariable;
            }

            var type = uoe.Expression.GetActualType(TypeSystem);

            if (
                (eVar != null) &&
                (eVar.Identifier == Variable.Identifier) &&
                (uoe.Operator is JSUnaryMutationOperator)
                )
            {
                var newValue = DecomposeMutationOperators.DecomposeUnaryMutation(
                    uoe, () => TemporaryVariable.ForFunction(
                        Stack.Last() as JSFunctionExpression, type
                        ), type, TypeSystem
                    );
                var replacement = new JSWriteThroughReferenceExpression(
                    Variable, newValue
                    );
                ParentNode.ReplaceChild(uoe, replacement);
                VisitReplacement(replacement);
            }
            else
            {
                VisitChildren(uoe);
            }
        }
        protected JSVariable GetReferentVariable(JSPassByReferenceExpression pbr)
        {
            JSVariable   referentVariable;
            JSExpression referent;

            if (!JSReferenceExpression.TryMaterialize(JSIL, pbr.Referent, out referent))
            {
                if (JSReferenceExpression.TryDereference(JSIL, pbr.Referent, out referent))
                {
                    referentVariable = referent as JSVariable;
                    return(referentVariable);
                }
                else
                {
                    return(null);
                }
            }

            referentVariable = referent as JSVariable;
            return(referentVariable);
        }
예제 #5
0
        public void VisitNode(JSBinaryOperatorExpression boe)
        {
            JSExpression left, right, nestedLeft;

            if (!JSReferenceExpression.TryDereference(JSIL, boe.Left, out left))
            {
                left = boe.Left;
            }
            if (!JSReferenceExpression.TryDereference(JSIL, boe.Right, out right))
            {
                right = boe.Right;
            }

            var nestedBoe    = right as JSBinaryOperatorExpression;
            var isAssignment = (boe.Operator == JSOperator.Assignment);
            var leftNew      = left as JSNewExpression;
            var rightNew     = right as JSNewExpression;
            var leftVar      = left as JSVariable;

            if (
                isAssignment && (nestedBoe != null) &&
                (left.IsConstant || (leftVar != null) || left is JSDotExpressionBase) &&
                !(ParentNode is JSVariableDeclarationStatement)
                )
            {
                JSUnaryOperator      prefixOperator;
                JSAssignmentOperator compoundOperator;

                if (!JSReferenceExpression.TryDereference(JSIL, nestedBoe.Left, out nestedLeft))
                {
                    nestedLeft = nestedBoe.Left;
                }

                var rightLiteral = nestedBoe.Right as JSIntegerLiteral;
                var areEqual     = left.Equals(nestedLeft);

                if (
                    areEqual &&
                    PrefixOperators.TryGetValue(nestedBoe.Operator, out prefixOperator) &&
                    (rightLiteral != null) && (rightLiteral.Value == 1)
                    )
                {
                    var newUoe = new JSUnaryOperatorExpression(
                        prefixOperator, boe.Left,
                        boe.GetActualType(TypeSystem)
                        );

                    ParentNode.ReplaceChild(boe, newUoe);
                    VisitReplacement(newUoe);

                    return;
                }
                else if (
                    areEqual &&
                    CompoundAssignments.TryGetValue(nestedBoe.Operator, out compoundOperator)
                    )
                {
                    var newBoe = new JSBinaryOperatorExpression(
                        compoundOperator, boe.Left, nestedBoe.Right,
                        boe.GetActualType(TypeSystem)
                        );

                    ParentNode.ReplaceChild(boe, newBoe);
                    VisitReplacement(newBoe);

                    return;
                }
            }
            else if (
                isAssignment && (leftNew != null) &&
                (rightNew != null)
                )
            {
                var rightType = rightNew.Type as JSDotExpressionBase;
                if (
                    (rightType != null) &&
                    (rightType.Member.Identifier == "CollectionInitializer")
                    )
                {
                    var newInitializer = new JSInitializerApplicationExpression(
                        boe.Left, new JSArrayExpression(
                            TypeSystem.Object,
                            rightNew.Arguments.ToArray()
                            )
                        );

                    ParentNode.ReplaceChild(boe, newInitializer);
                    VisitReplacement(newInitializer);

                    return;
                }
            }
            else if (
                isAssignment && (leftVar != null) &&
                leftVar.IsThis
                )
            {
                var leftType = leftVar.GetActualType(TypeSystem);
                if (!TypeUtil.IsStruct(leftType))
                {
                    ParentNode.ReplaceChild(boe, new JSUntranslatableExpression(boe));

                    return;
                }
                else
                {
                    var newInvocation = JSInvocationExpression.InvokeStatic(
                        JSIL.CopyMembers, new[] { boe.Right, leftVar }
                        );

                    ParentNode.ReplaceChild(boe, newInvocation);
                    VisitReplacement(newInvocation);

                    return;
                }
            }

            VisitChildren(boe);
        }