public void VisitNode(JSNewExpression newexp)
        {
            var type = newexp.GetActualType(TypeSystem);

            var isStruct         = TypeUtil.IsStruct(type);
            var isInsideLoop     = (Stack.Any((node) => node is JSLoopStatement));
            var parentInvocation = ParentNode as JSInvocationExpression;
            var doesValueEscape  = DoesValueEscapeFromInvocation(parentInvocation, newexp, false);

            if (isStruct &&
                isInsideLoop &&
                (parentInvocation != null) &&
                !doesValueEscape
                )
            {
                var replacement = CreateHoistedVariable(
                    (hoistedVariable) => new JSCommaExpression(
                        JSInvocationExpression.InvokeMethod(
                            type, new JSMethod(newexp.ConstructorReference, newexp.Constructor, MethodTypes, null), hoistedVariable,
                            newexp.Arguments.ToArray(), false
                            ),
                        hoistedVariable
                        ),
                    type
                    );

                ParentNode.ReplaceChild(newexp, replacement);
                VisitReplacement(replacement);
            }
            else
            {
                VisitChildren(newexp);
            }
        }
예제 #2
0
        public void VisitNode(JSNewExpression ne)
        {
            var expectedType = ne.GetActualType(TypeSystem);

            if (
                IsNullable(expectedType)
                )
            {
                if (ne.Arguments.Count == 0)
                {
                    ParentNode.ReplaceChild(
                        ne, JSLiteral.Null(expectedType)
                        );
                }
                else
                {
                    ParentNode.ReplaceChild(
                        ne, ne.Arguments[0]
                        );
                    VisitReplacement(ne.Arguments[0]);
                }
            }
            else
            {
                VisitChildren(ne);
            }
        }
예제 #3
0
        public void VisitNode(JSNewExpression newexp)
        {
            var type = newexp.GetActualType(TypeSystem);

            var isStruct = TypeUtil.IsStruct(type);
            var isInsideLoop = (Stack.Any((node) => node is JSLoopStatement));
            var parentInvocation = ParentNode as JSInvocationExpression;

            var doesValueEscape = true;
            if (
                isStruct &&
                (parentInvocation != null) &&
                (parentInvocation.JSMethod != null) &&
                (parentInvocation.JSMethod.Reference != null)
            ) {
                var methodDef = parentInvocation.JSMethod.Reference.Resolve();
                var secondPass = FunctionSource.GetSecondPass(parentInvocation.JSMethod, Function.Method.QualifiedIdentifier);
                if ((secondPass != null) && (methodDef != null)) {
                    // HACK
                    var argumentIndex = parentInvocation.Arguments.Select(
                        (a, i) => new { argument = a, index = i })
                        .FirstOrDefault((_) => _.argument.SelfAndChildrenRecursive.Contains(newexp));

                    if (argumentIndex != null) {
                        var argumentName = methodDef.Parameters[argumentIndex.index].Name;

                        doesValueEscape = secondPass.EscapingVariables.Contains(argumentName);
                    }
                }
            }

            if (isStruct &&
                isInsideLoop &&
                (parentInvocation != null) &&
                !doesValueEscape
            ) {
                string id;
                var hoistedVariable = MakeTemporaryVariable(type, out id);
                var constructorInvocation = JSInvocationExpression.InvokeMethod(
                    type, new JSMethod(newexp.ConstructorReference, newexp.Constructor, MethodTypes, null), hoistedVariable, newexp.Arguments.ToArray(), false
                );
                var replacement = new JSCommaExpression(
                    constructorInvocation, hoistedVariable
                );

                ToDeclare.Add(new PendingDeclaration(id, type, hoistedVariable));

                ParentNode.ReplaceChild(newexp, replacement);
                VisitReplacement(replacement);
            } else {
                VisitChildren(newexp);
            }
        }
        public void VisitNode (JSNewExpression ne) {
            var parentBoe = ParentNode as JSBinaryOperatorExpression;

            var thisReferenceType = ne.GetActualType(TypeSystem);
            if (TypeUtil.IsStruct(thisReferenceType) && (parentBoe != null))
                Initializations.Add(new InitializationInfo {
                    Type = thisReferenceType,
                    NewExpression = ne,
                    ParentBinaryExpression = parentBoe,
                    BinaryExpressionParent = Stack.Skip(2).First()
                });

            VisitChildren(ne);
        }
예제 #5
0
        public void VisitNode(JSNewExpression ne)
        {
            var parentBoe = ParentNode as JSBinaryOperatorExpression;

            var thisReferenceType = ne.GetActualType(TypeSystem);

            if (TypeUtil.IsStruct(thisReferenceType) && (parentBoe != null))
            {
                Initializations.Add(new InitializationInfo {
                    Type                   = thisReferenceType,
                    NewExpression          = ne,
                    ParentBinaryExpression = parentBoe,
                    BinaryExpressionParent = Stack.Skip(2).First()
                });
            }

            VisitChildren(ne);
        }
예제 #6
0
 public void VisitNode (JSNewExpression ne) {
     var expectedType = ne.GetActualType(TypeSystem);
     if (
         IsNullable(expectedType)
     ) {
         if (ne.Arguments.Count == 0) {
             ParentNode.ReplaceChild(
                 ne, JSLiteral.Null(expectedType)
             );
         } else {
             ParentNode.ReplaceChild(
                 ne, ne.Arguments[0]
             );
             VisitReplacement(ne.Arguments[0]);
         }
     } else {
         VisitChildren(ne);
     }
 }
예제 #7
0
        public void VisitNode (JSNewExpression newexp) {
            var type = newexp.GetActualType(TypeSystem);

            var isStruct = TypeUtil.IsStruct(type);
            var isInsideLoop = (Stack.Any((node) => node is JSLoopStatement));
            var parentInvocation = ParentNode as JSInvocationExpression;
            var doesValueEscape = DoesValueEscapeFromInvocation(parentInvocation, newexp, false);

            if (isStruct && 
                isInsideLoop && 
                (parentInvocation != null) &&
                !doesValueEscape
            ) {
                var replacement = CreateHoistedVariable(
                    (hoistedVariable) => new JSCommaExpression(
                        JSInvocationExpression.InvokeMethod(
                            type, new JSMethod(newexp.ConstructorReference, newexp.Constructor, MethodTypes, null), hoistedVariable,
                            newexp.Arguments.ToArray(), false
                        ), 
                        hoistedVariable
                    ),
                    type
                );

                ParentNode.ReplaceChild(newexp, replacement);
                VisitReplacement(replacement);
            } else {
                VisitChildren(newexp);
            }
        }