Exemple #1
0
        public void VisitNode(JSPropertyAccess pa)
        {
            var targetType = pa.Target.GetActualType(TypeSystem);

            if (IsNullable(targetType))
            {
                var @null = JSLiteral.Null(targetType);

                switch (pa.Property.Property.Member.Name)
                {
                case "HasValue":
                    var replacement = new JSBinaryOperatorExpression(
                        JSOperator.NotEqual, pa.Target, @null, TypeSystem.Boolean
                        );
                    ParentNode.ReplaceChild(pa, replacement);
                    VisitReplacement(replacement);

                    break;

                case "Value":
                    ParentNode.ReplaceChild(pa, pa.Target);
                    VisitReplacement(pa.Target);

                    break;

                default:
                    throw new NotImplementedException(pa.Property.Property.Member.FullName);
                }

                return;
            }

            VisitChildren(pa);
        }
Exemple #2
0
        public void VisitNode(JSPropertyAccess pa)
        {
            var targetType = pa.Target.GetActualType(TypeSystem);

            if (IsNullable(targetType))
            {
                var @null = JSLiteral.Null(targetType);

                switch (pa.Property.Property.Member.Name)
                {
                case "HasValue": {
                    var replacement = JSIL.NullableHasValue(pa.Target);
                    ParentNode.ReplaceChild(pa, replacement);
                    VisitReplacement(replacement);

                    break;
                }

                case "Value": {
                    var replacement = JSIL.ValueOfNullable(pa.Target);
                    ParentNode.ReplaceChild(pa, replacement);
                    VisitReplacement(replacement);

                    break;
                }

                default:
                    throw new NotImplementedException(pa.Property.Property.Member.FullName);
                }

                return;
            }

            VisitChildren(pa);
        }
Exemple #3
0
 public bool IsPropertyAccess(
     JSBinaryOperatorExpression boe, out JSPropertyAccess pa
     )
 {
     pa = boe.Left as JSPropertyAccess;
     return(pa != null);
 }
 public bool IsPropertyAccess(
     JSBinaryOperatorExpression boe, out JSPropertyAccess pa
 )
 {
     pa = boe.Left as JSPropertyAccess;
     return pa != null;
 }
        public void VisitNode(JSPropertyAccess pa)
        {
            if (IsPropertyGetterInvocation(pa)) {
                // getter
                var replacement = ConstructInvocation(pa);

                ParentNode.ReplaceChild(pa, replacement);
                VisitReplacement(replacement);
            } else {
                VisitChildren(pa);
            }
        }
 public void VisitNode(JSPropertyAccess pa)
 {
     if (pa.ThisReference.Equals(ThisReference) && pa.Property.Equals(Property))
     {
         ParentNode.ReplaceChild(pa, Replacement);
         VisitReplacement(Replacement);
     }
     else
     {
         VisitChildren(pa);
     }
 }
        public static bool IsPropertySetterInvocation(JSNode parentNode, JSBinaryOperatorExpression boe, out JSPropertyAccess pa)
        {
            var isValidParent =
                (parentNode is JSExpressionStatement);

            pa = boe.Left as JSPropertyAccess;

            return (pa != null) &&
                pa.IsWrite &&
                (boe.Operator == JSOperator.Assignment) &&
                isValidParent &&
                CanConvertToInvocation(pa);
        }
        public static bool CanConvertToInvocation (JSPropertyAccess pa) {
            var prop = pa.Property.Property;

            if (prop.IsAutoProperty &&
                !prop.IsVirtual &&
                !prop.DeclaringType.IsInterface
            ) {
                return false;
            } else {
                return
                    !prop.Metadata.HasAttribute("JSIL.Meta.JSAlwaysAccessAsProperty");
            }
        }
        public bool IsPropertySetterInvocation(JSBinaryOperatorExpression boe, out JSPropertyAccess pa)
        {
            var isValidParent =
                (ParentNode is JSExpressionStatement) ||
                (ParentNode is JSCommaExpression);

            pa = boe.Left as JSPropertyAccess;

            return((pa != null) &&
                   pa.IsWrite &&
                   (boe.Operator == JSOperator.Assignment) &&
                   isValidParent &&
                   CanConvertToInvocation(pa));
        }
Exemple #10
0
        public void VisitNode(JSPropertyAccess pa)
        {
            if (pa.IsWrite)
            {
                throw new Exception("Unhandled property write: " + pa);
            }

            var method     = pa.OriginalMethod;
            var memberName = WasmUtil.FormatMemberName(method.Reference.Resolve());

            Formatter.WriteSExpr("call", (_) => {
                _.WriteRaw("${0}", memberName);
            });
        }
        public void VisitNode(JSPropertyAccess pa)
        {
            if (IsPropertyGetterInvocation(pa))
            {
                // getter
                var replacement = ConstructInvocation(pa);

                ParentNode.ReplaceChild(pa, replacement);
                VisitReplacement(replacement);
            }
            else
            {
                VisitChildren(pa);
            }
        }
        public static bool CanConvertToInvocation(JSPropertyAccess pa)
        {
            var prop = pa.Property.Property;

            if (prop.IsAutoProperty &&
                !prop.IsVirtual &&
                !prop.DeclaringType.IsInterface
                )
            {
                return(false);
            }
            else
            {
                return
                    (!prop.Metadata.HasAttribute("JSIL.Meta.JSAlwaysAccessAsProperty"));
            }
        }
        public bool IsPropertyGetterInvocation(JSPropertyAccess pa)
        {
            if (Stack.OfType<JSBinaryOperatorExpression>().Any(
                (boe) =>
                    (boe.Operator is JSAssignmentOperator) &&
                    (boe.Left.SelfAndChildrenRecursive.Contains(pa))
            ))
                return false;
            else if (Stack.OfType<JSUnaryOperatorExpression>().Any(
                (uoe) =>
                    uoe.Operator is JSUnaryMutationOperator
            ))
                return false;

            return !pa.IsWrite &&
                CanConvertToInvocation(pa);
        }
        public static bool IsPropertyGetterInvocation(JSNode parentNode, JSPropertyAccess pa)
        {
            var parentBoe = parentNode as JSBinaryOperatorExpression;
            var parentUoe = parentNode as JSUnaryOperatorExpression;

            bool isMutation = (
                    (parentUoe != null) &&
                    (parentUoe.Operator is JSUnaryMutationOperator)
                ) || (
                    (parentBoe != null) &&
                    (parentBoe.Operator is JSAssignmentOperator) &&
                    (pa == parentBoe.Left)
                );

            return !pa.IsWrite &&
                !isMutation &&
                CanConvertToInvocation(pa);
        }
        public bool IsPropertyGetterInvocation(JSPropertyAccess pa)
        {
            if (Stack.OfType <JSBinaryOperatorExpression>().Any(
                    (boe) =>
                    (boe.Operator is JSAssignmentOperator) &&
                    (boe.Left.SelfAndChildrenRecursive.Contains(pa))
                    ))
            {
                return(false);
            }
            else if (Stack.OfType <JSUnaryOperatorExpression>().Any(
                         (uoe) =>
                         uoe.Operator is JSUnaryMutationOperator
                         ))
            {
                return(false);
            }

            return(!pa.IsWrite &&
                   CanConvertToInvocation(pa));
        }
Exemple #16
0
        public void VisitNode(JSPropertyAccess prop)
        {
            var parentBoe = ParentNode as JSBinaryOperatorExpression;
            var v         = ExtractAffectedVariable(prop.Target);
            var p         = prop.Property.Property;

            if (prop.HasGlobalStateDependency)
            {
                State.StaticReferences.Add(new FunctionAnalysis1stPass.StaticReference(
                                               GetParentNodeIndices(), StatementIndex, NodeIndex, p.DeclaringType
                                               ));
            }

            if (
                (parentBoe != null) &&
                (parentBoe.Operator is JSAssignmentOperator) &&
                (parentBoe.Left == prop)
                )
            {
                // Setter
                if (v != null)
                {
                    State.SideEffects.Add(new FunctionAnalysis1stPass.SideEffect(
                                              GetParentNodeIndices(), StatementIndex, NodeIndex, v, "property set"
                                              ));
                }

                /*
                 * State.Invocations.Add(new FunctionAnalysis1stPass.Invocation(
                 *  StatementIndex, NodeIndex,
                 */
            }
            else
            {
                // Getter
            }

            VisitChildren(prop);
        }
        private JSExpression ConstructInvocation (
            JSPropertyAccess pa, JSExpression argument = null
        ) {
            JSExpression[] arguments;

            if (argument == null)
                arguments = new JSExpression[0];
            else
                arguments = new JSExpression[] { argument };

            var originalMethod = pa.OriginalMethod;
            var declaringType = originalMethod.Reference.DeclaringType;
            var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType);
            var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem);
            var isSelf = TypeUtil.TypesAreAssignable(
                TypeInfo, thisReferenceType, declaringType
            );

            // ILSpy converts compound assignments from:
            //  x.set_Value(x.get_Value + n)
            // to
            //  x.get_Value += n;
            // so we have to detect this and reconstruct the correct method
            //  references.
            var actualMethod = originalMethod;
            var correctName = String.Format(
                "{0}_{1}", pa.IsWrite ? "set" : "get",
                pa.Property.Property.ShortName
            );

            if (!actualMethod.Reference.Name.Contains(correctName)) {
                var dt = originalMethod.Method.DeclaringType;

                var actualMethodInfo = dt.Members.Values
                    .OfType<MethodInfo>().FirstOrDefault(
                        (m) => (
                            m.Name.Contains(correctName) &&
                            m.DeclaringType == originalMethod.Method.DeclaringType
                        )
                    );

                MethodReference actualMethodReference = actualMethodInfo.Member;
                if (originalMethod.Reference is GenericInstanceMethod) {
                    throw new InvalidDataException("Reconstructing an invocation of a generic instance method? Shouldn't be possible.");
                } else if (declaringType is GenericInstanceType) {
                    var declaringGit = (GenericInstanceType)declaringType;
                    var returnType = actualMethodReference.ReturnType;

                    if (TypeUtil.IsOpenType(returnType)) {
                        var actualReturnType = JSExpression.SubstituteTypeArgs(TypeInfo, actualMethodReference.ReturnType, actualMethodReference);
                        returnType = actualReturnType;
                    }

                    actualMethodReference = new MethodReference(
                        actualMethodReference.Name, returnType, declaringGit
                    );
                }

                actualMethod = new JSMethod(
                    actualMethodReference, actualMethodInfo,
                    originalMethod.MethodTypes, originalMethod.GenericArguments
                );
            }

            bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis(
                declaringType, declaringTypeDef,
                originalMethod.Method.DeclaringType,
                isSelf, thisReferenceType,
                originalMethod.Method
            );
                
            JSInvocationExpressionBase invocation;
            if (pa.Property.Property.IsStatic)
                invocation = JSInvocationExpression.InvokeStatic(
                    actualMethod.Reference.DeclaringType,
                    actualMethod, 
                    arguments
                );
            else if (needsExplicitThis)
                invocation = JSInvocationExpression.InvokeBaseMethod(
                    actualMethod.Reference.DeclaringType,
                    actualMethod, pa.ThisReference,
                    arguments
                );
            else
                invocation = JSInvocationExpression.InvokeMethod(
                    pa.OriginalType, actualMethod, pa.ThisReference, arguments
                );

            JSExpression replacement;
            if (TypeUtil.IsStruct(pa.Property.Property.ReturnType))
                replacement = new JSResultReferenceExpression(invocation);
            else
                replacement = invocation;

            return replacement;
        }
        private JSExpression ConstructInvocation(
            JSPropertyAccess pa, JSExpression argument = null
            )
        {
            JSExpression[] arguments;

            if (argument == null)
            {
                arguments = new JSExpression[0];
            }
            else
            {
                arguments = new JSExpression[] { argument }
            };

            var originalMethod    = pa.OriginalMethod;
            var declaringType     = originalMethod.Reference.DeclaringType;
            var declaringTypeDef  = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType);
            var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem);
            var isSelf            = TypeUtil.TypesAreAssignable(
                TypeInfo, thisReferenceType, declaringType
                );

            // ILSpy converts compound assignments from:
            //  x.set_Value(x.get_Value + n)
            // to
            //  x.get_Value += n;
            // so we have to detect this and reconstruct the correct method
            //  references.
            var actualMethod = originalMethod;
            var correctName  = String.Format(
                "{0}_{1}", pa.IsWrite ? "set" : "get",
                pa.Property.Property.ShortName
                );

            if (!actualMethod.Reference.Name.Contains(correctName))
            {
                var dt = originalMethod.Method.DeclaringType;

                var actualMethodInfo = dt.Members.Values
                                       .OfType <MethodInfo>().FirstOrDefault(
                    (m) => (
                        m.Name.Contains(correctName) &&
                        m.DeclaringType == originalMethod.Method.DeclaringType
                        )
                    );

                MethodReference actualMethodReference = actualMethodInfo.Member;
                if (originalMethod.Reference is GenericInstanceMethod)
                {
                    throw new InvalidDataException("Reconstructing an invocation of a generic instance method? Shouldn't be possible.");
                }
                else if (declaringType is GenericInstanceType)
                {
                    var declaringGit = (GenericInstanceType)declaringType;
                    var returnType   = actualMethodReference.ReturnType;

                    if (TypeUtil.IsOpenType(returnType))
                    {
                        var actualReturnType = JSExpression.SubstituteTypeArgs(TypeInfo, actualMethodReference.ReturnType, actualMethodReference);
                        returnType = actualReturnType;
                    }

                    actualMethodReference = new MethodReference(
                        actualMethodReference.Name, returnType, declaringGit
                        );
                }

                actualMethod = new JSMethod(
                    actualMethodReference, actualMethodInfo,
                    originalMethod.MethodTypes, originalMethod.GenericArguments
                    );
            }

            bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis(
                declaringType, declaringTypeDef,
                originalMethod.Method.DeclaringType,
                isSelf, thisReferenceType,
                originalMethod.Method
                );

            JSInvocationExpressionBase invocation;

            if (pa.Property.Property.IsStatic)
            {
                invocation = JSInvocationExpression.InvokeStatic(
                    actualMethod.Reference.DeclaringType,
                    actualMethod,
                    arguments
                    );
            }
            else if (needsExplicitThis)
            {
                invocation = JSInvocationExpression.InvokeBaseMethod(
                    actualMethod.Reference.DeclaringType,
                    actualMethod, pa.ThisReference,
                    arguments
                    );
            }
            else
            {
                invocation = JSInvocationExpression.InvokeMethod(
                    pa.OriginalType, actualMethod, pa.ThisReference, arguments
                    );
            }

            JSExpression replacement;

            if (TypeUtil.IsStruct(pa.Property.Property.ReturnType))
            {
                replacement = new JSResultReferenceExpression(invocation);
            }
            else
            {
                replacement = invocation;
            }

            return(replacement);
        }
        private JSExpression ConstructInvocation(
            JSPropertyAccess pa, JSExpression argument = null
        )
        {
            JSExpression[] arguments;

            if (argument == null)
                arguments = new JSExpression[0];
            else
                arguments = new JSExpression[] { argument };

            var originalMethod = pa.OriginalMethod;
            var declaringType = originalMethod.Reference.DeclaringType;
            var declaringTypeDef = TypeUtil.GetTypeDefinition(originalMethod.Reference.DeclaringType);
            var thisReferenceType = pa.ThisReference.GetActualType(TypeSystem);
            var isSelf = TypeUtil.TypesAreAssignable(
                TypeInfo, thisReferenceType, declaringType
            );

            bool needsExplicitThis = !pa.IsVirtualCall && ILBlockTranslator.NeedsExplicitThis(
                declaringType, declaringTypeDef,
                originalMethod.Method.DeclaringType,
                isSelf, thisReferenceType,
                originalMethod.Method
            );

            JSInvocationExpressionBase invocation;
            if (pa.Property.Property.IsStatic)
                invocation = JSInvocationExpression.InvokeStatic(
                    pa.OriginalMethod.Reference.DeclaringType,
                    pa.OriginalMethod,
                    arguments
                );
            else if (needsExplicitThis)
                invocation = JSInvocationExpression.InvokeBaseMethod(
                    pa.OriginalMethod.Reference.DeclaringType,
                    pa.OriginalMethod, pa.ThisReference,
                    arguments
                );
            else
                invocation = JSInvocationExpression.InvokeMethod(
                    pa.OriginalMethod, pa.ThisReference, arguments
                );

            JSExpression replacement;
            if (TypeUtil.IsStruct(pa.Property.Property.ReturnType))
                replacement = new JSResultReferenceExpression(invocation);
            else
                replacement = invocation;

            return replacement;
        }
 public void VisitNode(JSPropertyAccess pa)
 {
     if (pa.ThisReference.Equals(ThisReference) && pa.Property.Equals(Property)) {
         ParentNode.ReplaceChild(pa, Replacement);
         VisitReplacement(Replacement);
     } else {
         VisitChildren(pa);
     }
 }
        public void VisitNode(JSPropertyAccess pa)
        {
            var targetType = pa.Target.GetExpectedType(TypeSystem);

            if (targetType.FullName.StartsWith("System.Nullable")) {
                var @null = JSLiteral.Null(targetType);

                switch (pa.Property.Property.Member.Name) {
                    case "HasValue":
                        var replacement = new JSBinaryOperatorExpression(
                            JSOperator.NotEqual, pa.Target, @null, TypeSystem.Boolean
                        );
                        ParentNode.ReplaceChild(pa, replacement);
                        VisitReplacement(replacement);

                        break;
                    case "Value":
                        ParentNode.ReplaceChild(pa, pa.Target);
                        VisitReplacement(pa.Target);

                        break;
                    default:
                        throw new NotImplementedException(pa.Property.Property.Member.FullName);
                }

                return;
            }

            VisitChildren(pa);
        }
Exemple #22
0
 public void VisitNode(JSPropertyAccess pa)
 {
     VisitDotExpression(pa);
 }