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); }
private void CompileImpls(JsClass klass, IType type) { var isEnumOrStruct = type.TypeKind == TypeKind.Struct || type.TypeKind == TypeKind.Enum; List <ObjectMethodId> objectMethods = null; if (isEnumOrStruct) { objectMethods = new List <ObjectMethodId> { ObjectMethodId.Equals, ObjectMethodId.GetHashCode, ObjectMethodId.ToString }; } foreach (var method in type.Methods) { if (isEnumOrStruct) { var id = method.GetObjectMethodId(); if (id != ObjectMethodId.Unknown) { objectMethods.Remove(id); } } if (IsCompilableImpl(method)) { CompileMethod(method); } } if (isEnumOrStruct) { foreach (var id in objectMethods.Where(id => ObjectMethods.Find(SystemTypes.Object, id).Data != null)) { CompileMethod(klass, id); } } }