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); }
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); }