Example #1
0
        public static Expr IndexOfString(ICall call)
        {
            var ctx  = call.Ctx;
            var expr = new ExprJsResolvedMethod(ctx, ctx.Int32, call.Obj, "indexOf", call.Args);

            return(expr);
        }
Example #2
0
        public static Expr IndexOfChar(ICall call)
        {
            var ctx  = call.Ctx;
            var args = call.Args.Select((x, i) => i != 0 ? x : new ExprJsResolvedMethod(ctx, ctx.Char, null, "String.fromCharCode", x));
            var expr = new ExprJsResolvedMethod(ctx, ctx.Int32, call.Obj, "indexOf", args);

            return(expr);
        }
Example #3
0
        public static Stmt GetHashCode(Ctx ctx)
        {
            var toString    = new ExprJsResolvedMethod(ctx, ctx.String, ctx.This, "toExponential");
            var getHashCode = new ExprCall(ctx, typeof(string).GetMethod("GetHashCode"), toString);
            var stmt        = new StmtReturn(ctx, getHashCode);

            return(stmt);
        }
Example #4
0
        public static Expr Join(ICall call)
        {
            var ctx       = call.Ctx;
            var separator = call.Arg(0, "separator");
            var values    = call.Arg(1);
            var sepExpr   = new ExprJsExplicit(ctx, "separator || \"\"", ctx.String, separator);
            var expr      = new ExprJsResolvedMethod(ctx, ctx.String, values, "join", sepExpr);

            return(expr);
        }
Example #5
0
        public static Stmt IsWhiteSpace(Ctx ctx)
        {
            // See http://msdn.microsoft.com/en-us/library/t809ektx.aspx for list
            var whiteSpace = " \u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d\u0085\u00a0";
            var arg0       = ctx.MethodParameter(0);
            var c          = new ExprJsResolvedMethod(ctx, ctx.String, null, "String.fromCharCode", arg0);
            var indexOf    = new ExprJsResolvedMethod(ctx, ctx.Boolean, ctx.Literal(whiteSpace), "indexOf", c);

            return(new StmtReturn(ctx,
                                  new ExprBinary(ctx, BinaryOp.GreaterThanOrEqual, ctx.Boolean, indexOf, ctx.Literal(0))));
        }
Example #6
0
        public static Expr Copy(ICall call)
        {
            // d = arg[0].slice(arg[1],arg[4]+arg[1])
            // Array.prototype.splice.apply(arg[2], [arg[3], arg[4]].concat(d))
            var ctx             = call.Ctx;
            var src             = call.Args.ElementAt(0);
            var srcIdx          = call.Args.ElementAt(1);
            var dst             = call.Args.ElementAt(2);
            var dstIdx          = call.Args.ElementAt(3);
            var length          = call.Args.ElementAt(4);
            var arrayPart       = new ExprJsResolvedMethod(ctx, src.Type, src, "slice", srcIdx, ctx.ExprGen.Add(srcIdx, length));
            var spliceFixedArgs = new ExprJsArrayLiteral(ctx, ctx.Object, dstIdx, length);
            var spliceArgs      = new ExprJsResolvedMethod(ctx, spliceFixedArgs.Type, spliceFixedArgs, "concat", arrayPart);
            var copy            = new ExprJsResolvedMethod(ctx, ctx.Void, null, "Array.prototype.splice.apply", dst, spliceArgs);

            return(copy);
        }
 protected override ICode VisitJsResolvedMethod(ExprJsResolvedMethod e)
 {
     if (e.Obj != null)
     {
         this.code.Append(e.Obj);
         this.code.Append(".");
     }
     this.code.Append(e.MethodName);
     this.code.Append("(");
     if (e.Args.Any())
     {
         foreach (var arg in e.Args)
         {
             this.Visit(arg);
             this.code.Append(", ");
         }
         this.code.Length -= 2;
     }
     this.code.Append(")");
     return(e);
 }
Example #8
0
        /// <summary>
        /// If a call/newobj requires translating to an Expr that is not a call/newobj, then it is done here.
        /// </summary>
        /// <param name="call"></param>
        /// <returns></returns>
        public static Expr ResolveCallSite(ICall call)
        {
            var ctx      = call.Ctx;
            var mRef     = call.CallMethod;
            var tRefDecl = mRef.DeclaringType;
            var mDef     = mRef.Resolve();
            // A call to a method in a "JsClass" class - all external methods/properties require translating to JS
            var tDefDecl    = mDef.DeclaringType;
            var jsClassAttr = tDefDecl.GetCustomAttribute <JsClassAttribute>() ?? tDefDecl.GetCustomAttribute <JsAbstractClassAttribute>();

            if (jsClassAttr != null)
            {
                if (mDef.IsExternal())
                {
                    var jsDetail               = mDef.GetCustomAttribute <JsDetailAttribute>(true);
                    var jsDetailName           = jsDetail.NullThru(x => (string)x.Properties.FirstOrDefault(y => y.Name == "Name").Argument.Value);
                    var jsDetailIsDomEventProp = jsDetail.NullThru(x => ((bool?)x.Properties.FirstOrDefault(y => y.Name == "IsDomEvent").Argument.Value) ?? false);
                    if (mDef.IsGetter || mDef.IsSetter)
                    {
                        // Property access
                        if (jsDetailIsDomEventProp)
                        {
                            // Special handling of DOM events
                            if (!mDef.IsSetter)
                            {
                                throw new InvalidOperationException("Only setters supported on DOM events");
                            }
                            if (!mDef.Name.StartsWith("set_On"))
                            {
                                throw new InvalidOperationException("DOM event name must start with 'On'");
                            }
                            if (call.Args.Count() != 1)
                            {
                                throw new InvalidOperationException("DOM event setter must have exactly one argument");
                            }
                            var eventName        = jsDetailName ?? mDef.Name.Substring(6).ToLowerInvariant();
                            var eventNameExpr    = ctx.Literal(eventName);
                            var safeCallFunction = (Action <object, string, Delegate>)InternalFunctions.SafeAddEventListener;
                            var safeCall         = new ExprCall(ctx, safeCallFunction, null, call.Obj, eventNameExpr, call.Args.First());
                            return(safeCall);
                        }
                        else
                        {
                            var propertyName = jsDetailName ?? JsCase(mDef.Name.Substring(4));
                            if (mDef.Name.Substring(4) == "Item")
                            {
                                propertyName = null;
                            }
                            else if (mDef.IsStatic)
                            {
                                propertyName = JsCase(mDef.DeclaringType.Name) + "." + propertyName;
                            }
                            var jsProperty = new ExprJsResolvedProperty(ctx, call, propertyName);
                            return(jsProperty);
                        }
                    }
                    else if (mDef.IsConstructor && !mDef.IsStatic)
                    {
                        // Constructor new object call
                        var typeName = jsDetailName ?? (string)jsClassAttr.ConstructorArguments[0].Value;
                        var expr     = new ExprJsResolvedCtor(ctx, typeName, tRefDecl, call.Args);
                        return(expr);
                    }
                    else
                    {
                        // Normal method call
                        var methodName = jsDetailName ?? JsCase(mDef.Name);
                        if (mDef.IsStatic)
                        {
                            methodName = JsCase(mDef.DeclaringType.Name) + "." + methodName;
                        }
                        var expr = new ExprJsResolvedMethod(ctx, call.Type, call.Obj, methodName, call.Args);
                        return(expr);
                    }
                }
                else
                {
                    return(null);
                }
            }
            var jsRedirectAttr = mDef.GetCustomAttribute <JsRedirectAttribute>(true);

            if (jsRedirectAttr != null)
            {
                if (jsRedirectAttr.ConstructorArguments[0].Value == null)
                {
                    return(FindExprReturn(call, call.CallMethod.DeclaringType));
                }
                var redirectToTRef = ((TypeReference)jsRedirectAttr.ConstructorArguments[0].Value).FullResolve(mRef);
                var redirectToMRef = redirectToTRef.EnumResolvedMethods(mRef).First(x => x.MatchMethodOnly(mRef));
                switch (call.ExprType)
                {
                case Expr.NodeType.NewObj:
                    return(new ExprNewObj(ctx, redirectToMRef, call.Args));

                case Expr.NodeType.Call:
                    return(new ExprCall(ctx, redirectToMRef, call.Obj, call.Args, call.IsVirtualCall, null, call.Type));

                default:
                    throw new NotImplementedException("Cannot handle: " + call.ExprType);
                }
            }
            var exprRet = FindExprReturn(call);

            if (exprRet != null)
            {
                return(exprRet);
            }
            return(null);
        }