예제 #1
0
        protected override Expression VisitMember(MemberExpression node)
        {
            if (node.Expression == null)
            {
                var decl = node.Member.DeclaringType;
                if (decl == typeof(string))
                {
                    if (node.Member.Name == "Empty")
                    {
                        using (this.result.Operation(JavascriptOperationTypes.Literal))
                            this.result.Write("\"\"");
                        return(node);
                    }
                }
            }

            using (this.result.Operation(node))
            {
                var metadataProvider = this.Options.GetMetadataProvider();
                var pos = this.result.Length;
                if (node.Expression == null)
                {
                    var decl = node.Member.DeclaringType;
                    if (decl != null)
                    {
                        // TODO: there should be a way to customize the name of types through metadata
                        this.result.Write(decl.FullName);
                        this.result.Write('.');
                        this.result.Write(decl.Name);
                    }
                }
                else if (node.Expression != this.contextParameter)
                {
                    this.Visit(node.Expression);
                }
                else
                {
                    this.usedScopeMembers = this.usedScopeMembers ?? new List <string>();
                    var meta = metadataProvider.GetMemberMetadata(node.Member);
                    Debug.Assert(!string.IsNullOrEmpty(meta?.MemberName), "!string.IsNullOrEmpty(meta?.MemberName)");
                    this.usedScopeMembers.Add(meta?.MemberName ?? node.Member.Name);
                }

                if (this.result.Length > pos)
                {
                    this.result.Write('.');
                }

                var propInfo = node.Member as PropertyInfo;
                if (propInfo?.DeclaringType != null &&
                    node.Type == typeof(int) &&
                    node.Member.Name == "Count" &&
                    TypeHelpers.IsListType(propInfo.DeclaringType))
                {
                    this.result.Write("length");
                }
                else
                {
                    var meta = metadataProvider.GetMemberMetadata(node.Member);
                    Debug.Assert(!string.IsNullOrEmpty(meta?.MemberName), "!string.IsNullOrEmpty(meta?.MemberName)");
                    this.result.Write(meta?.MemberName);
                }

                return(node);
            }
        }
예제 #2
0
        protected override Expression VisitListInit(ListInitExpression node)
        {
            // Detecting a new dictionary
            if (TypeHelpers.IsDictionaryType(node.Type))
            {
                using (this.result.Operation(0))
                {
                    this.result.Write('{');

                    var posStart = this.result.Length;
                    foreach (var init in node.Initializers)
                    {
                        if (this.result.Length > posStart)
                        {
                            this.result.Write(',');
                        }

                        if (init.Arguments.Count != 2)
                        {
                            throw new NotSupportedException(
                                      "Objects can only be initialized with methods that receive pairs: key -> name");
                        }

                        var nameArg = init.Arguments[0];
                        if (nameArg.NodeType != ExpressionType.Constant || nameArg.Type != typeof(string))
                        {
                            throw new NotSupportedException("The key of an object must be a constant string value");
                        }

                        var name = (string)((ConstantExpression)nameArg).Value;
                        if (Regex.IsMatch(name, @"^\w[\d\w]*$"))
                        {
                            this.result.Write(name);
                        }
                        else
                        {
                            this.WriteStringLiteral(name);
                        }

                        this.result.Write(':');
                        this.Visit(init.Arguments[1]);
                    }

                    this.result.Write('}');
                }

                return(node);
            }

            // Detecting a new dictionary
            if (TypeHelpers.IsListType(node.Type))
            {
                using (this.result.Operation(0))
                {
                    this.result.Write('[');

                    var posStart = this.result.Length;
                    foreach (var init in node.Initializers)
                    {
                        if (this.result.Length > posStart)
                        {
                            this.result.Write(',');
                        }

                        if (init.Arguments.Count != 1)
                        {
                            throw new Exception(
                                      "Arrays can only be initialized with methods that receive a single parameter for the value");
                        }

                        this.Visit(init.Arguments[0]);
                    }

                    this.result.Write(']');
                }

                return(node);
            }

            return(node);
        }