public JsExpression GetMember(IMember member, IRuntimeContext context)
        {
            var owner = member is IMethod && ((IMethod)member).IsAccessor ? ((IMethod)member).AccessorOwner : null;

            int index = FindIndexInReflectableMembers(owner ?? member);

            if (index >= 0)
            {
                JsExpression result = JsExpression.Index(
                    JsExpression.Member(
                        JsExpression.Member(
                            TypeOf(member.DeclaringType, context),
                            "__metadata"),
                        "members"),
                    JsExpression.Number(index));
                if (owner != null)
                {
                    if (owner is IProperty)
                    {
                        if (ReferenceEquals(member, ((IProperty)owner).Getter))
                        {
                            result = JsExpression.MemberAccess(result, "getter");
                        }
                        else if (ReferenceEquals(member, ((IProperty)owner).Setter))
                        {
                            result = JsExpression.MemberAccess(result, "setter");
                        }
                        else
                        {
                            throw new ArgumentException("Invalid member " + member);
                        }
                    }
                    else if (owner is IEvent)
                    {
                        if (ReferenceEquals(member, ((IEvent)owner).AddAccessor))
                        {
                            result = JsExpression.MemberAccess(result, "adder");
                        }
                        else if (ReferenceEquals(member, ((IEvent)owner).RemoveAccessor))
                        {
                            result = JsExpression.MemberAccess(result, "remover");
                        }
                        else
                        {
                            throw new ArgumentException("Invalid member " + member);
                        }
                    }
                    else
                    {
                        throw new ArgumentException("Invalid owner " + owner);
                    }
                }
                return(result);
            }
            else
            {
                return(MetadataUtils.ConstructMemberInfo(member, _compilation, _metadataImporter, _namer, this, _errorReporter, t => TypeOf(t, context), includeDeclaringType: true));
            }
        }
 public void ExpressionStatementIsParenthesizedWhenItStartsWithAnObjectLiteral()
 {
     AssertCorrect((JsStatement)JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0))), "({ a: 0 });\n");
     AssertCorrect((JsStatement)JsExpression.Invocation(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0)))), "({ a: 0 }());\n");
     AssertCorrect((JsStatement)JsExpression.Member(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0))), "a"), "({ a: 0 }.a);\n");
     AssertCorrect((JsStatement)JsExpression.Comma(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0))), JsExpression.Null), "({ a: 0 }, null);\n");
     AssertCorrect((JsStatement)JsExpression.Conditional(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0))), JsExpression.Number(0), JsExpression.Number(1)), "({ a: 0 } ? 0 : 1);\n");
     AssertCorrect((JsStatement)JsExpression.PrefixPlusPlus(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0)))), "++{ a: 0 };\n");
     AssertCorrect((JsStatement)JsExpression.PostfixPlusPlus(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0)))), "({ a: 0 }++);\n");
     AssertCorrect((JsStatement)JsExpression.PostfixMinusMinus(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0)))), "({ a: 0 }--);\n");
     AssertCorrect((JsStatement)JsExpression.Index(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0))), JsExpression.Number(0)), "({ a: 0 }[0]);\n");
     AssertCorrect((JsStatement)JsExpression.Member(JsExpression.Invocation(JsExpression.Member(JsExpression.ObjectLiteral(new JsObjectLiteralProperty("a", JsExpression.Number(0))), "a")), "b"), "({ a: 0 }.a().b);\n");
 }
 public void IndexingDoesNotCauseUnnecessaryParentheses()
 {
     AssertCorrect(JsExpression.Member(
                       JsExpression.Index(
                           JsExpression.Member(
                               JsExpression.Index(
                                   JsExpression.Identifier("a"),
                                   JsExpression.Identifier("b")
                                   ),
                               "c"
                               ),
                           JsExpression.Identifier("d")
                           ),
                       "e"
                       ), "a[b].c[d].e");
 }
Example #4
0
        public JsInvocationExpression CreateMulticastDelegate(JsExpression target, JsExpression invocationList)
        {
            var delegateBody = new JsBlockStatement();
            var list = Js.Variable("$invocationList", invocationList);
            var i = Js.Variable("$i", Js.Primitive(0));
            delegateBody.Add(
                Js.For(
                    i, 
                    i.GetReference().LessThan(list.GetReference().Member("length")), 
                    i.GetReference().Increment()
                )
                .Body(list.GetReference().Index(i.GetReference()).Member("apply").Invoke(Js.Null(), Js.Reference("arguments")).Express()));

            var delegateExpression = Js.Function();
            delegateExpression.Body(delegateBody);
            var delegateVariable = Js.Variable("$delegate$", delegateExpression);

            var delegateType = invocationList.Index(Js.Primitive(0)).Member(SpecialNames.TypeField);

            var wrapper = new JsBlockStatement();
            wrapper.Local(list);
            wrapper.Local(delegateVariable);
            wrapper.Assign(delegateVariable.GetReference().Member("prototype"), Js.New(Type(Context.Instance.MulticastDelegateType)));
            wrapper.Invoke(Type(Context.Instance.ObjectType).Member(SpecialNames.TypeInitializer), delegateVariable.GetReference(), delegateVariable.GetReference());
            wrapper.Invoke(Type(Context.Instance.DelegateType).Member(SpecialNames.TypeInitializer), delegateVariable.GetReference(), delegateVariable.GetReference());
            wrapper.Invoke(Type(Context.Instance.MulticastDelegateType).Member(SpecialNames.TypeInitializer), delegateVariable.GetReference(), delegateVariable.GetReference());
            wrapper.Invoke(delegateType.Member(SpecialNames.TypeInitializer), delegateVariable.GetReference(), delegateVariable.GetReference());
            wrapper.Express(InvokeMethodAs(
                Context.Instance.MulticastDelegateConstructor, 
                delegateVariable.GetReference(), 
                target, 
                list.GetReference()));
            wrapper.Assign(delegateVariable.GetReference().Member(SpecialNames.TypeField), delegateType);
            wrapper.Return(delegateVariable.GetReference());

            return Wrap(wrapper);
        }