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); } }
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); }