예제 #1
0
        public string GetExpressionForLocal(string name, string accessor, IType type)
        {
            var scriptType = ExpressionTreeBuilder.GetTypeName(type, this._emitter);

            string getterDefinition = "function () { return " + accessor + "}";
            string setterDefinition = "function ($) { " + accessor + " = $; }";

            /*if (UsesThisVisitor.Analyze(accessor))
             * {
             *  getterDefinition = JsExpression.Invocation(JsExpression.Member(getterDefinition, "bind"), JsExpression.This);
             *  setterDefinition = JsExpression.Invocation(JsExpression.Member(setterDefinition, "bind"), JsExpression.This);
             * }*/

            var obj = new JObject();

            obj["ntype"] = (int)ExpressionType.MemberAccess;
            obj["t"]     = new JRaw(scriptType);

            var expression = new JObject();

            expression["ntype"] = (int)ExpressionType.Constant;
            expression["t"]     = new JRaw(scriptType);
            expression["value"] = new JObject();
            obj["expression"]   = expression;

            var member = new JObject();

            member["td"] = new JRaw("System.Object");
            member["n"]  = name;
            member["t"]  = (int)MemberTypes.Property;
            member["rt"] = new JRaw(scriptType);

            var getter = new JObject();

            getter["td"]  = new JRaw("System.Object");
            getter["n"]   = "get" + name;
            getter["t"]   = (int)MemberTypes.Method;
            getter["rt"]  = new JRaw(scriptType);
            getter["p"]   = new JRaw("[]");
            getter["def"] = new JRaw(getterDefinition);
            member["g"]   = getter;

            var setter = new JObject();

            setter["td"]  = new JRaw("System.Object");
            setter["n"]   = "set" + name;
            setter["t"]   = (int)MemberTypes.Method;
            setter["rt"]  = new JRaw("System.Object");
            setter["p"]   = new JRaw("[" + scriptType + "]");
            setter["def"] = new JRaw(setterDefinition);
            member["s"]   = setter;

            obj["member"] = member;

            return(obj.ToString(Formatting.None));
        }
예제 #2
0
        public string GetMember(IMember member)
        {
            var owner = member is IMethod && ((IMethod)member).IsAccessor ? ((IMethod)member).AccessorOwner : null;

            int index = FindIndexInReflectableMembers(owner ?? member);

            if (index >= 0)
            {
                string result = string.Format("Bridge.getMetadata({0}).m[{1}]", ExpressionTreeBuilder.GetTypeName(member.DeclaringType, this._emitter), index);
                if (owner != null)
                {
                    if (owner is IProperty)
                    {
                        if (ReferenceEquals(member, ((IProperty)owner).Getter))
                        {
                            result = result + ".g";
                        }
                        else if (ReferenceEquals(member, ((IProperty)owner).Setter))
                        {
                            result = result + ".s";
                        }
                        else
                        {
                            throw new ArgumentException("Invalid member " + member);
                        }
                    }
                    else if (owner is IEvent)
                    {
                        if (ReferenceEquals(member, ((IEvent)owner).AddAccessor))
                        {
                            result = result + ".ad";
                        }
                        else if (ReferenceEquals(member, ((IEvent)owner).RemoveAccessor))
                        {
                            result = result + ".r";
                        }
                        else
                        {
                            throw new ArgumentException("Invalid member " + member);
                        }
                    }
                    else
                    {
                        throw new ArgumentException("Invalid owner " + owner);
                    }
                }
                return(result);
            }
            else
            {
                return(MetadataUtils.ConstructMemberInfo(member, this._emitter, true, false, this._syntaxTree).ToString(Formatting.None));
            }
        }
예제 #3
0
        protected override void DoEmit()
        {
            if (this.Emitter.TempVariables == null)
            {
                this.ResetLocals();
            }

            var oldReplaceJump = this.Emitter.ReplaceJump;

            this.Emitter.ReplaceJump = false;

            var rr = this.Emitter.Resolver.ResolveNode(this.Context, this.Emitter);

            if (this.Context is Expression)
            {
                var conversion = this.Emitter.Resolver.Resolver.GetConversion((Expression)this.Context);
                if (conversion.IsAnonymousFunctionConversion)
                {
                    var type = this.Emitter.Resolver.Resolver.GetExpectedType((Expression)this.Context);
                    if (type.FullName == typeof(System.Linq.Expressions.Expression).FullName && type.TypeParameterCount == 1)
                    {
                        var expr = new ExpressionTreeBuilder(this.Emitter.Resolver.Compilation, this.Emitter, this.Context.GetParent <SyntaxTree>(), this).BuildExpressionTree((LambdaResolveResult)rr);
                        this.Write(expr);
                        return;
                    }
                }
            }

            var oldParentVariables = this.Emitter.ParentTempVariables;

            if (this.Emitter.ParentTempVariables == null)
            {
                this.Emitter.ParentTempVariables = new Dictionary <string, bool>(this.Emitter.TempVariables);
            }
            else
            {
                this.Emitter.ParentTempVariables = new Dictionary <string, bool>(this.Emitter.ParentTempVariables);
                foreach (var item in this.Emitter.TempVariables)
                {
                    this.Emitter.ParentTempVariables.Add(item.Key, item.Value);
                }
            }

            var oldVars = this.Emitter.TempVariables;

            this.Emitter.TempVariables = new Dictionary <string, bool>();
            this.PreviousIsAync        = this.Emitter.IsAsync;
            this.Emitter.IsAsync       = this.IsAsync;

            this.PreviousAsyncVariables = this.Emitter.AsyncVariables;
            this.Emitter.AsyncVariables = null;

            this.PreviousAsyncBlock = this.Emitter.AsyncBlock;
            this.Emitter.AsyncBlock = null;

            this.ReplaceAwaiterByVar         = this.Emitter.ReplaceAwaiterByVar;
            this.Emitter.ReplaceAwaiterByVar = false;

            this.EmitLambda(this.Parameters, this.Body, this.Context);

            this.Emitter.IsAsync             = this.PreviousIsAync;
            this.Emitter.AsyncVariables      = this.PreviousAsyncVariables;
            this.Emitter.AsyncBlock          = this.PreviousAsyncBlock;
            this.Emitter.ReplaceAwaiterByVar = this.ReplaceAwaiterByVar;
            this.Emitter.TempVariables       = oldVars;
            this.Emitter.ParentTempVariables = oldParentVariables;
            this.Emitter.ReplaceJump         = oldReplaceJump;
        }
예제 #4
0
        public override string VisitLambdaResolveResult(LambdaResolveResult rr, object data)
        {
            var parameters = new JRaw[rr.Parameters.Count];
            var map        = new Dictionary <string, string>();

            for (int i = 0; i < rr.Parameters.Count; i++)
            {
                var temp = this._block.GetTempVarName();
                _allParameters[rr.Parameters[i]] = temp;
                parameters[i] = new JRaw(temp);

                map.Add(temp, CompileFactoryCall("Parameter", new[] { typeof(Type), typeof(string) }, new[] { ExpressionTreeBuilder.GetTypeName(rr.Parameters[i].Type, this._emitter), this._emitter.ToJavaScript(rr.Parameters[i].Name) }));
            }

            var body   = VisitResolveResult(rr.Body, null);
            var lambda = CompileFactoryCall("Lambda", new[] { typeof(Expression), typeof(ParameterExpression[]) }, new[] { body, this._emitter.ToJavaScript(parameters) });

            if (map.Count > 0)
            {
                StringBuilder sb = new StringBuilder();

                sb.Append("(");

                foreach (var item in map)
                {
                    sb.Append(item.Key);
                    sb.Append(" = ");
                    sb.Append(item.Value);
                    sb.Append(", ");
                }

                sb.Append(lambda);
                sb.Append(")");

                return(sb.ToString());
            }

            return(lambda);
        }
예제 #5
0
 public override string VisitThisResolveResult(ThisResolveResult rr, object data)
 {
     return(CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { AbstractEmitterBlock.GetThisAlias(_emitter), ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter) }));
 }
예제 #6
0
        public override string VisitArrayCreateResolveResult(ArrayCreateResolveResult rr, object data)
        {
            var arrayType = rr.Type as ArrayType;

            if (rr.InitializerElements != null)
            {
                return(CompileFactoryCall("NewArrayInit", new[] { typeof(Type), typeof(Expression[]) }, new[] { ExpressionTreeBuilder.GetTypeName(arrayType != null ? arrayType.ElementType : rr.Type, this._emitter), this._emitter.ToJavaScript(rr.InitializerElements.Select(e => new JRaw(this.VisitResolveResult(e, null))).ToArray()) }));
            }

            return(CompileFactoryCall("NewArrayBounds", new[] { typeof(Type), typeof(Expression[]) }, new[] { ExpressionTreeBuilder.GetTypeName(arrayType != null ? arrayType.ElementType : rr.Type, this._emitter), this._emitter.ToJavaScript(rr.SizeArguments.Select(a => new JRaw(VisitResolveResult(a, null))).ToArray()) }));
        }
예제 #7
0
        public override string VisitArrayAccessResolveResult(ArrayAccessResolveResult rr, object data)
        {
            var array = VisitResolveResult(rr.Array, null);

            if (rr.Indexes.Count == 1)
            {
                return(CompileFactoryCall("ArrayIndex", new[] { typeof(Type), typeof(Expression), typeof(Expression) }, new[] { ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter), array, VisitResolveResult(rr.Indexes[0], null) }));
            }
            else
            {
                return(CompileFactoryCall("ArrayIndex", new[] { typeof(Type), typeof(Expression), typeof(Expression[]) }, new[] { ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter), array, this._emitter.ToJavaScript(rr.Indexes.Select(i => new JRaw(this.VisitResolveResult(i, null))).ToArray()) }));
            }
        }
예제 #8
0
        private string MakeConstant(ResolveResult rr)
        {
            var value = rr.ConstantValue == null?DefaultValueBlock.DefaultValue(rr, this._emitter) : AbstractEmitterBlock.ToJavaScript(rr.ConstantValue, this._emitter);

            return(CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { value, ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter) }));
        }
예제 #9
0
 public override string VisitTypeOfResolveResult(TypeOfResolveResult rr, object data)
 {
     return(CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { ExpressionTreeBuilder.GetTypeName(rr.ReferencedType, this._emitter), ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter) }));
 }
예제 #10
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)))) }));
            }
        }
예제 #11
0
 public override string VisitTypeIsResolveResult(TypeIsResolveResult rr, object data)
 {
     return(CompileFactoryCall("TypeIs", new[] { typeof(Expression), typeof(Type) }, new[] { VisitResolveResult(rr.Input, null), ExpressionTreeBuilder.GetTypeName(rr.TargetType, this._emitter) }));
 }
예제 #12
0
        public override string VisitConversionResolveResult(ConversionResolveResult rr, object data)
        {
            var input = VisitResolveResult(rr.Input, null);

            if (rr.Conversion.IsIdentityConversion)
            {
                return(input);
            }
            else if (rr.Conversion.IsAnonymousFunctionConversion)
            {
                var result = input;
                if (rr.Type.Name == "Expression")
                {
                    result = CompileFactoryCall("Quote", new[] { typeof(Expression) }, new[] { result });
                }
                return(result);
            }
            else if (rr.Conversion.IsNullLiteralConversion)
            {
                return(CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { input, ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter) }));
            }
            else if (rr.Conversion.IsMethodGroupConversion)
            {
                var methodInfo = _compilation.FindType(typeof(MethodInfo));
                return(CompileFactoryCall("Convert", new[] { typeof(Expression), typeof(Type) }, new[] {
                    CompileFactoryCall("Call", new[] { typeof(Expression), typeof(MethodInfo), typeof(Expression[]) }, new[] {
                        CompileFactoryCall("Constant", new[] { typeof(object), typeof(Type) }, new[] { this.GetMember(rr.Conversion.Method), ExpressionTreeBuilder.GetTypeName(methodInfo, this._emitter) }),
                        this.GetMember(methodInfo.GetMethods().Single(m => m.Name == "CreateDelegate" && m.Parameters.Count == 2 && m.Parameters[0].Type.FullName == typeof(Type).FullName && m.Parameters[1].Type.FullName == typeof(object).FullName)),
                        this._emitter.ToJavaScript(new [] {
                            new JRaw(ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter)),
                            new JRaw(rr.Conversion.Method.IsStatic ? "null" : VisitResolveResult(((MethodGroupResolveResult)rr.Input).TargetResult, null))
                        })
                    }),
                    ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter)
                }));
            }
            else
            {
                string methodName;
                if (rr.Conversion.IsTryCast)
                {
                    methodName = "TypeAs";
                }
                else if (rr.CheckForOverflow)
                {
                    methodName = "ConvertChecked";
                }
                else
                {
                    methodName = "Convert";
                }
                if (rr.Conversion.IsUserDefined)
                {
                    return(CompileFactoryCall(methodName, new[] { typeof(Expression), typeof(Type), typeof(MethodInfo) }, new[] { input, ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter), this.GetMember(rr.Conversion.Method) }));
                }
                else
                {
                    return(CompileFactoryCall(methodName, new[] { typeof(Expression), typeof(Type) }, new[] { input, ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter) }));
                }
            }
        }
예제 #13
0
        public override string VisitOperatorResolveResult(OperatorResolveResult rr, object data)
        {
            bool isUserDefined = rr.UserDefinedOperatorMethod != null && !this._emitter.Validator.IsExternalType(rr.UserDefinedOperatorMethod.DeclaringTypeDefinition);
            var  arguments     = new string[rr.Operands.Count + 1];

            for (int i = 0; i < rr.Operands.Count; i++)
            {
                arguments[i] = VisitResolveResult(rr.Operands[i], null);
            }
            arguments[arguments.Length - 1] = isUserDefined ? this.GetMember(rr.UserDefinedOperatorMethod) : ExpressionTreeBuilder.GetTypeName(rr.Type, this._emitter);
            if (rr.OperatorType == ExpressionType.Conditional)
            {
                return(CompileFactoryCall("Condition", new[] { typeof(Expression), typeof(Expression), typeof(Expression), typeof(Type) }, arguments));
            }
            else
            {
                return(CompileFactoryCall(rr.OperatorType.ToString(), rr.Operands.Count == 1 ? new[] { typeof(Expression), isUserDefined ? typeof(MethodInfo) : typeof(Type) } : new[] { typeof(Expression), typeof(Expression), isUserDefined ? typeof(MethodInfo) : typeof(Type) }, arguments));
            }
        }