Exemplo n.º 1
0
        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))) });
			}
		}