Exemplo n.º 1
0
        private JsFunction CreateCallFunc(MethodContext context, IMethod method, CallInfo info)
        {
            var obj  = "o".Id();
            var args = "a".Id();
            var func = new JsFunction(null, obj.Value, args.Value);

            InitClass(context, func, method);

            JsNode call = null;

            //TODO: inplace inline calls
            if (method.DeclaringType.Is(SystemTypeCode.Boolean) && method.IsToString())
            {
                call = obj.Ternary("True", "False");
            }

            //to detect stackoverflows
            //func.Body.Add("console.log".Id().Call(method.JsFullName()).AsStatement());

            if (call == null && info != null)
            {
                if (info.ReceiverType != null && (info.Flags & CallFlags.Basecall) != 0)
                {
                    call = method.JsFullName(info.ReceiverType).Id().Apply(obj, args);
                }
                else if (IsSuperCall(context, method, info.Flags))
                {
                    var baseType = context.Method.DeclaringType.BaseType;
                    call = method.JsFullName(baseType).Id().Apply(obj, args);
                    //TODO: remove $base if it is not needed
                    //call = obj.Get("$base").Get(method.JsName()).Apply(obj, args);
                }
            }

            if (call == null)
            {
                if (!method.IsStatic && !method.IsConstructor && method.DeclaringType.IsBoxableType())
                {
                    new BoxingImpl(this).BoxUnboxed(context, method.DeclaringType, func, obj);
                }

                call = method.Apply(obj, args);
            }

            func.Body.Add(method.IsVoid() ? call.AsStatement() : call.Return());

            return(func);
        }
Exemplo n.º 2
0
        private static void CompileEquals(JsCompiler compiler, JsClass klass)
        {
            var other = "o".Id();

            var func = new JsFunction(null, other.Value);

            func.Body.Add(new JsText("if (o === null || o === undefined) return false;"));

            //TODO: check object type

            JsNode result = null;

            foreach (var field in GetInstanceFields(klass))
            {
                var name  = field.JsName();
                var left  = "this".Id().Get(name);
                var right = other.Get(name);

                JsNode e;
                // primitive and ref types
                if (field.Type.TypeKind != TypeKind.Struct && !field.Type.IsInt64Based())
                {
                    e = left.Op(right, BinaryOperator.Equality);
                }
                else                 // value types, int64 based
                {
                    var objectType = compiler.SystemTypes.Object;
                    var eq         = objectType.Methods.Find("Equals", objectType, objectType);
                    compiler.CompileMethod(eq);
                    e = eq.JsFullName().Id().Call(left, right);
                }

                result = result == null ? e : result.And(e);
            }

            func.Body.Add(result == null ? "false".Id().Return() : result.Return());

            var methodName = ObjectMethods.Find(compiler.SystemTypes.Object, ObjectMethodId.Equals).JsName();

            klass.ExtendPrototype(func, methodName);
        }