public override string VisitInvocationResolveResult(InvocationResolveResult rr, object data) { var type = rr.Member.DeclaringType as AnonymousType; if (type != null) { if (!this._emitter.AnonymousTypes.ContainsKey(type)) { var config = new AnonymousTypeCreateBlock(this._emitter, null).CreateAnonymousType(type); this._emitter.AnonymousTypes.Add(type, config); } } if (rr.Member.DeclaringType.Kind == TypeKind.Delegate && rr.Member.Name == "Invoke") { return(CompileFactoryCall("Invoke", new[] { typeof(Type), typeof(Expression), typeof(Expression[]) }, new[] { ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter), VisitResolveResult(rr.TargetResult, null), this._emitter.ToJavaScript(rr.GetArgumentsForCall().Select(a => new JRaw(VisitResolveResult(a, null)))) })); } else if (rr.Member is IMethod && ((IMethod)rr.Member).IsConstructor) { if (rr.Member.DeclaringType.Kind == TypeKind.Anonymous) { var args = new List <JRaw>(); var members = new List <JRaw>(); foreach (var init in rr.InitializerStatements) { var assign = init as OperatorResolveResult; if (assign == null || assign.OperatorType != ExpressionType.Assign || !(assign.Operands[0] is MemberResolveResult) || !(((MemberResolveResult)assign.Operands[0]).Member is IProperty)) { throw new Exception("Invalid anonymous type initializer " + init); } args.Add(new JRaw(VisitResolveResult(assign.Operands[1], null))); members.Add(new JRaw(this.GetMember(((MemberResolveResult)assign.Operands[0]).Member))); } return(CompileFactoryCall("New", new[] { typeof(ConstructorInfo), typeof(Expression[]), typeof(MemberInfo[]) }, new[] { this.GetMember(rr.Member), this._emitter.ToJavaScript(args), this._emitter.ToJavaScript(members) })); } else { var result = CompileFactoryCall("New", new[] { typeof(ConstructorInfo), typeof(Expression[]) }, new[] { this.GetMember(rr.Member), this._emitter.ToJavaScript(rr.GetArgumentsForCall().Select(a => new JRaw(VisitResolveResult(a, null)))) }); if (rr.InitializerStatements.Count > 0) { if (rr.InitializerStatements[0] is InvocationResolveResult && ((InvocationResolveResult)rr.InitializerStatements[0]).TargetResult is InitializedObjectResolveResult) { var elements = new List <JRaw>(); foreach (var stmt in rr.InitializerStatements) { var irr = stmt as InvocationResolveResult; if (irr == null) { throw new Exception("Expected list initializer, was " + stmt); } elements.Add(new JRaw(CompileFactoryCall("ElementInit", new[] { typeof(MethodInfo), typeof(Expression[]) }, new[] { this.GetMember(irr.Member), this._emitter.ToJavaScript(irr.Arguments.Select(i => new JRaw(VisitResolveResult(i, null)))) }))); } result = CompileFactoryCall("ListInit", new[] { typeof(NewExpression), typeof(ElementInit[]) }, new[] { result, this._emitter.ToJavaScript(elements) }); } else { var map = BuildAssignmentMap(rr.InitializerStatements); using (IEnumerator <Tuple <List <IMember>, IList <ResolveResult>, IMethod> > enm = map.GetEnumerator()) { enm.MoveNext(); var bindings = GenerateMemberBindings(enm, 0); result = CompileFactoryCall("MemberInit", new[] { typeof(NewExpression), typeof(MemberBinding[]) }, new[] { result, this._emitter.ToJavaScript(bindings.Item1) }); } } } return(result); } } else { var member = rr.Member is IProperty ? ((IProperty)rr.Member).Getter : rr.Member; // If invoking a property (indexer), use the get method. return(CompileFactoryCall("Call", new[] { typeof(Expression), typeof(MethodInfo), typeof(Expression[]) }, new[] { member.IsStatic ? "null" : VisitResolveResult(rr.TargetResult, null), this.GetMember(member), this._emitter.ToJavaScript(rr.GetArgumentsForCall().Select(a => new JRaw(VisitResolveResult(a, null)))) })); } }
public override JsExpression VisitInvocationResolveResult(InvocationResolveResult rr, object data) { if (rr.Member.DeclaringType.Kind == TypeKind.Delegate && rr.Member.Name == "Invoke") { return CompileFactoryCall("Invoke", new[] { typeof(Type), typeof(Expression), typeof(Expression[]) }, new[] { _instantiateType(rr.Type), VisitResolveResult(rr.TargetResult, null), JsExpression.ArrayLiteral(rr.GetArgumentsForCall().Select(a => VisitResolveResult(a, null))) }); } else if (rr.Member is IMethod && ((IMethod)rr.Member).IsConstructor) { if (rr.Member.DeclaringType.Kind == TypeKind.Anonymous) { var args = new List<JsExpression>(); var members = new List<JsExpression>(); foreach (var init in rr.InitializerStatements) { var assign = init as OperatorResolveResult; if (assign == null || assign.OperatorType != ExpressionType.Assign || !(assign.Operands[0] is MemberResolveResult) || !(((MemberResolveResult)assign.Operands[0]).Member is IProperty)) throw new Exception("Invalid anonymous type initializer " + init); args.Add(VisitResolveResult(assign.Operands[1], null)); members.Add(_getMember(((MemberResolveResult)assign.Operands[0]).Member)); } return CompileFactoryCall("New", new[] { typeof(ConstructorInfo), typeof(Expression[]), typeof(MemberInfo[]) }, new[] { _getMember(rr.Member), JsExpression.ArrayLiteral(args), JsExpression.ArrayLiteral(members) }); } else { var result = CompileFactoryCall("New", new[] { typeof(ConstructorInfo), typeof(Expression[]) }, new[] { _getMember(rr.Member), JsExpression.ArrayLiteral(rr.GetArgumentsForCall().Select(a => VisitResolveResult(a, null))) }); if (rr.InitializerStatements.Count > 0) { if (rr.InitializerStatements[0] is InvocationResolveResult && ((InvocationResolveResult)rr.InitializerStatements[0]).TargetResult is InitializedObjectResolveResult) { var elements = new List<JsExpression>(); foreach (var stmt in rr.InitializerStatements) { var irr = stmt as InvocationResolveResult; if (irr == null) throw new Exception("Expected list initializer, was " + stmt); elements.Add(CompileFactoryCall("ElementInit", new[] { typeof(MethodInfo), typeof(Expression[]) }, new[] { _getMember(irr.Member), JsExpression.ArrayLiteral(irr.Arguments.Select(i => VisitResolveResult(i, null))) })); } result = CompileFactoryCall("ListInit", new[] { typeof(NewExpression), typeof(ElementInit[]) }, new[] { result, JsExpression.ArrayLiteral(elements) }); } else { var map = BuildAssignmentMap(rr.InitializerStatements); using (IEnumerator<Tuple<List<IMember>, IList<ResolveResult>, IMethod>> enm = map.GetEnumerator()) { enm.MoveNext(); var bindings = GenerateMemberBindings(enm, 0); result = CompileFactoryCall("MemberInit", new[] { typeof(NewExpression), typeof(MemberBinding[]) }, new[] { result, JsExpression.ArrayLiteral(bindings.Item1) }); } } } return result; } } else { var member = rr.Member is IProperty ? ((IProperty)rr.Member).Getter : rr.Member; // If invoking a property (indexer), use the get method. return CompileFactoryCall("Call", new[] { typeof(Expression), typeof(MethodInfo), typeof(Expression[]) }, new[] { member.IsStatic ? JsExpression.Null : VisitResolveResult(rr.TargetResult, null), _getMember(member), JsExpression.ArrayLiteral(rr.GetArgumentsForCall().Select(a => VisitResolveResult(a, null))) }); } }