/* * feature -- Comparison */ public static bool is_equal(object Current, object other) // Is `other' attached to an object considered // equal to current object? { bool Result = false; EIFFEL_TYPE_INFO l_current = Current as EIFFEL_TYPE_INFO; #if ASSERTIONS ASSERTIONS.REQUIRE("other_not_void", other != null); #endif if (Current == null) { generate_call_on_void_target_exception(); } else if (l_current != null) { Result = l_current.____is_equal(other); } else { Result = Current.Equals(other); } return(Result); }
public static object clone(object Current, object other) // Void if `other' is void; otherwise new object // equal to `other' // // For non-void `other', `clone' calls `copy'; // to change copying/cloning semantics, redefine `copy'. { object Result = null; if (Current == null) { generate_call_on_void_target_exception(); } else { if (other != null) { Result = twin(other); } } #if ASSERTIONS ASSERTIONS.ENSURE("equal", equal(Current, Result, other)); #endif return(Result); }
public static void copy(object Current, object other) // Update current object using fields of object attached // to `other', so as to yield equal objects. { EIFFEL_TYPE_INFO l_current = Current as EIFFEL_TYPE_INFO; #if ASSERTIONS ASSERTIONS.REQUIRE("other_not_void", other != null); ASSERTIONS.REQUIRE("same_type", same_type(Current, other)); #endif if (Current == null) { generate_call_on_void_target_exception(); } else { if (l_current != null) { l_current.____copy(other); } else { internal_standard_copy(Current, other); } } #if ASSERTIONS ASSERTIONS.ENSURE("is_equal", is_equal(Current, other)); #endif }
/* * feature -- Basic operations */ public virtual void call(object agent, object[] open_operands) // Call associated routine `agent' with open arguments `open_operands'. { #if ASSERTIONS ASSERTIONS.CHECK("open_operands_not_void", open_operands != null); #endif }
public static object deep_twin(object Current) // New object structure recursively duplicated from Current. { object Result = null; Hashtable traversed_objects; if (Current == null) { generate_call_on_void_target_exception(); } else { // `traversed_objects' is a correspondance between processed // objects reachable from `obj' and newly created one that // are reachable from `Result'. traversed_objects = new Hashtable(100, new RT_REFERENCE_COMPARER()); // Create an empty copy of `Current'. Result = GENERIC_CONFORMANCE.create_like_object(Current); // Add `Current' and associates it with `Result' to // resolve future references to `Current' into `Result'. traversed_objects.Add(Current, Result); // Performs deep traversal. internal_deep_twin(Result, Current, traversed_objects); } #if ASSERTIONS ASSERTIONS.ENSURE("deep_equal", deep_equal(Current, Result, Current)); #endif return(Result); }
public static bool standard_is_equal(object Current, object other) // Is `other' attached to an object of the same type // as current object, and field-by-field identical to it? { bool Result = false; FieldInfo [] l_attributes; object l_attr; #if ASSERTIONS ASSERTIONS.REQUIRE("other_not_void", other != null); #endif if (Current == null) { generate_call_on_void_target_exception(); } else { // Optimization: if objects are the same, then they are equal. Result = (Current == other); if (!Result) { if (same_type(Current, other)) { l_attributes = other.GetType().GetFields( BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo attribute in l_attributes) { l_attr = attribute.GetValue(other); if (l_attr is ValueType) { Result = Equals(l_attr, attribute.GetValue(Current)); } else { Result = (l_attr == attribute.GetValue(Current)); if (!Result) { /* Special case here where we check whether or not `l_attr' corresponds * to the special runtime field `$$____type' used to store the generic type * information. If it is the case, we simply ignore it. To identify * it we use the name of the attribute as well as its type which needs * to be of type RT_GENERIC_TYPE. */ Result = (attribute.Name.Equals("$$____type") && typeof(RT_GENERIC_TYPE).Equals(attribute.FieldType)); } } if (!Result) { // Force exit from loop as objects are not identical. return(Result); } } } } } return(Result); }
/* * feature -- Duplication */ public static object standard_clone(object obj) // { #if ASSERTIONS ASSERTIONS.REQUIRE("Valid type", obj is EIFFEL_TYPE_INFO); #endif return(GENERIC_CONFORMANCE.create_like_object((EIFFEL_TYPE_INFO)obj)); }
// Last result of a function call public object item(object agent, object[] open_operands) // Call associated routine `agent' with open arguments `open_operands'. { #if ASSERTIONS ASSERTIONS.CHECK("open_operands_not_void", open_operands != null); #endif call(agent, open_operands); return(last_result); }
public static ulong object_size(object obj) // Physical size of an object. { #if ASSERTIONS ASSERTIONS.REQUIRE("obj not void", obj != null); #endif return((ulong)System.Runtime.InteropServices.Marshal.SizeOf(obj.GetType())); }
/* * feature -- Output */ public static string @out(object Current) // New string containing terse printable representation // of current object { #if ASSERTIONS ASSERTIONS.REQUIRE("Not an Eiffel object", !(Current is EIFFEL_TYPE_INFO)); #endif return(tagged_out(Current)); }
public EIFFEL_EXCEPTION(int a_code, string a_tag) : base(exception_message(a_code, a_tag)) // New instance with `code' set to `a_code' and `tag' with `a_tag'. { code = a_code; tag = a_tag; #if ASSERTIONS ASSERTIONS.ENSURE("code_set", code == a_code); ASSERTIONS.ENSURE("tag_set", tag == a_tag); #endif }
public static bool is_assertion_checked(Type t, ASSERTION_LEVEL_ENUM val, bool saved_caller_supplier_precondition) // Are assertions checked for type `t' for assertion type `val'. // Note that `val' is not a combination. { ASSERTION_LEVEL_ENUM type_assertion_level; object obj; bool Result; #if ASSERTIONS ASSERTIONS.CHECK("Valid val", (val == ASSERTION_LEVEL_ENUM.no) || (val == ASSERTION_LEVEL_ENUM.check) || (val == ASSERTION_LEVEL_ENUM.require) || (val == ASSERTION_LEVEL_ENUM.ensure) || (val == ASSERTION_LEVEL_ENUM.loop) || (val == ASSERTION_LEVEL_ENUM.invariant)); #endif Result = !in_assertion(); if (Result) { if (val == ASSERTION_LEVEL_ENUM.require && saved_caller_supplier_precondition) { Result = true; } else { // Let's extract the specified assertion level for type `t'. // If `is_global_assertion_level_set' is set, then we can return // the global one. if (is_global_assertion_level_set) { return((global_assertion_level & val) == val); } else if ((assertion_levels != null)) { obj = assertion_levels [t]; if (obj != null) { type_assertion_level = (ASSERTION_LEVEL_ENUM)obj; } else { type_assertion_level = ASSERTION_LEVEL_ENUM.no; } } else { type_assertion_level = ASSERTION_LEVEL_ENUM.no; } Result = ((type_assertion_level & val) == val); } } return(Result); }
public EIFFEL_EXCEPTION(int a_code, string a_tag, Exception an_inner_exception) : base(exception_message(a_code, a_tag), an_inner_exception) // New instance with `code' set to `a_code' and `tag' with `a_tag' // and `InnerException' set to `an_inner_exception'. { code = a_code; tag = a_tag; #if ASSERTIONS ASSERTIONS.ENSURE("code_set", code == a_code); ASSERTIONS.ENSURE("tag_set", tag == a_tag); ASSERTIONS.ENSURE("InnerException_set", InnerException == an_inner_exception); #endif }
public static bool same_type(object Current, object other) // Is type of current object identical to type of `other'? { bool Result = false; RT_GENERIC_TYPE l_current_type, l_other_type; EIFFEL_TYPE_INFO l_current; #if ASSERTIONS ASSERTIONS.REQUIRE("other_not_void", other != null); #endif if (Current == null) { generate_call_on_void_target_exception(); } else { Result = Current.GetType().Equals(other.GetType()); if (Result) { l_current = Current as EIFFEL_TYPE_INFO; if (l_current != null) { // We perform generic conformance in case it is needed. l_current_type = l_current.____type(); if (l_current_type != null) { // Because we already know that `Current' and `other' have // the same type, therefore cast to EIFFEL_TYPE_INFO is // going to succeed. l_other_type = ((EIFFEL_TYPE_INFO)other).____type(); #if ASSERTIONS ASSERTIONS.CHECK("has_derivation", l_other_type != null); ASSERTIONS.CHECK("Same base type", l_current_type.type.Equals(l_other_type.type)); #endif Result = l_current_type.Equals(l_other_type); } } else { // It is not generic, then they definitely have the same type. // No need to assign Result again, as it is already holding the true value. } } } #if ASSERTIONS ASSERTIONS.ENSURE("definition", Result == (conforms_to(Current, other) && conforms_to(other, Current))); #endif return(Result); }
public static string tagged_out(object Current) // New string containing terse printable representation // of current object { #if ASSERTIONS ASSERTIONS.REQUIRE("Not an Eiffel object", !(Current is EIFFEL_TYPE_INFO)); #endif string Result = null; if (Current == null) { generate_call_on_void_target_exception(); } else { Result = Current.ToString(); } return(Result); }
//FIXME: to remove when TUPLE is updated not to use this routine anymore. public static Type type_of_generic_parameter(object an_obj, int pos) // Given an Eiffel object `an_obj', find the associated type of generic parameter // at position `pos'. { EIFFEL_TYPE_INFO l_object = an_obj as EIFFEL_TYPE_INFO; RT_GENERIC_TYPE l_gen_type; RT_CLASS_TYPE cl_type; Type Result = null; if (l_object != null) { #if ASSERTIONS ASSERTIONS.REQUIRE("Has generic info", l_object.____type() != null); ASSERTIONS.REQUIRE("Valid position `pos'", (pos > 0) && (pos <= l_object.____type().count)); #endif l_gen_type = l_object.____type(); cl_type = (RT_CLASS_TYPE)l_gen_type.generics [pos - 1]; if (!cl_type.is_basic()) { if (cl_type.type.Value != (System.IntPtr) 0) { Result = interface_type(Type.GetTypeFromHandle(cl_type.type)); } else { /* Generic parameter is of type NONE, so we return an instance * of RT_NONE_TYPE as associated type. It is mostly there to fix * assertions violations in TUPLE when one of the elements of * a manifest tuple is `Void'. */ #if ASSERTIONS ASSERTIONS.CHECK("Is NONE type.", cl_type is RT_NONE_TYPE); #endif Result = typeof(RT_NONE_TYPE); } } else { Result = Type.GetTypeFromHandle(cl_type.type); } } return(Result); }
public static object deep_clone(object Current, object other) // Void if `other' is void: otherwise, new object structure // recursively duplicated from the one attached to `other' { object Result = null; if (Current == null) { generate_call_on_void_target_exception(); } else if (other != null) { Result = deep_twin(other); } #if ASSERTIONS ASSERTIONS.ENSURE("deep_equal", deep_equal(Current, other, Result)); #endif return(Result); }
public static void deep_copy(object Current, object other) // Effect equivalent to that of: // `copy' (`other' . `deep_twin') { #if ASSERTIONS ASSERTIONS.REQUIRE("other_not_void", other != null); #endif if (Current == null) { generate_call_on_void_target_exception(); } else { copy(Current, deep_twin(other)); } #if ASSERTIONS ASSERTIONS.ENSURE("deep_equal", deep_equal(Current, Current, other)); #endif }
public static RT_CLASS_TYPE type_of_generic(object an_obj, int pos) // Given an Eiffel object `an_obj', find the associated type of generic parameter // at position `pos'. { EIFFEL_TYPE_INFO l_object = an_obj as EIFFEL_TYPE_INFO; if (l_object != null) { #if ASSERTIONS ASSERTIONS.REQUIRE("Has generic info", l_object.____type() != null); ASSERTIONS.REQUIRE("Valid position `pos'", (pos > 0) && (pos <= l_object.____type().count)); ASSERTIONS.REQUIRE("valid element type", l_object.____type().generics [pos - 1] is RT_CLASS_TYPE); #endif return((RT_CLASS_TYPE)(l_object.____type().generics [pos - 1])); } else { return(null); } }
public static Type interface_type(Type a_type) // Given a type `a_type' retrieves its associated interface type if any (i.e. only // it is an Eiffel type). // Used for conformance because the .NET routine `GetType()' will always return // the implementation type and it cannot be used for conformance because two implementation // classes do not conform even if their interfaces do. { object [] l_attributes; Type result; #if ASSERTIONS ASSERTIONS.REQUIRE("a_type not null", a_type != null); #endif result = interface_type_mapping [a_type] as Type; if (result == null) { l_attributes = a_type.GetCustomAttributes(typeof(RT_INTERFACE_TYPE_ATTRIBUTE), false); if (l_attributes != null && l_attributes.Length > 0) { result = ((RT_INTERFACE_TYPE_ATTRIBUTE)l_attributes [0]).class_type; } else { l_attributes = a_type.GetCustomAttributes(typeof(INTERFACE_TYPE_ATTRIBUTE), false); if (l_attributes != null && l_attributes.Length > 0) { result = ((INTERFACE_TYPE_ATTRIBUTE)l_attributes [0]).class_type; } else { result = a_type; } } interface_type_mapping [a_type] = result; } return(result); }
public static object standard_twin(object Current) // New object field-by-field identical to `other'. // Always uses default copying semantics. { object Result = null; bool l_check_assert; EIFFEL_TYPE_INFO l_current = Current as EIFFEL_TYPE_INFO; if (Current == null) { generate_call_on_void_target_exception(); } else { if (l_current != null) { // For Eiffel object we can use our efficient implementation // which is using `MemberwiseClone'. Result = l_current.____standard_twin(); } else { // For .NET object, we have to do it the slow way, allocate // a new object, and then copy field by field. l_check_assert = ISE_RUNTIME.check_assert(false); Result = GENERIC_CONFORMANCE.create_like_object(Current); internal_standard_copy(Result, Current); l_check_assert = ISE_RUNTIME.check_assert(l_check_assert); } } #if ASSERTIONS ASSERTIONS.ENSURE("standard_twin_not_void", Result != null); ASSERTIONS.ENSURE("standard_equal", standard_equal(Current, Result, Current)); #endif return(Result); }
public static object standard_clone(object Current, object other) // Void if `other' is void; otherwise new object // field-by-field identical to `other'. // Always uses default copying semantics. { object Result = null; if (Current == null) { generate_call_on_void_target_exception(); } else { if (other != null) { Result = standard_twin(other); } } #if ASSERTIONS ASSERTIONS.ENSURE("standard_equal", standard_equal(Current, Result, other)); #endif return(Result); }
// Tag of last checked assertion public static void assertion_initialize(RuntimeTypeHandle type_handle) // Initializes runtime datastructure for assembly associated with // `type_handle'. { assertion_levels = new Hashtable(100); Assembly a = Type.GetTypeFromHandle(type_handle).Assembly; ASSERTION_LEVEL_ATTRIBUTE level_attribute; ASSERTION_LEVEL_ENUM l_common_level, l_current_level; bool l_computed, l_same_level; #if ASSERTIONS ASSERTIONS.CHECK("There should be an assembly", a != null); #endif try { object [] cas = a.GetCustomAttributes(typeof(ASSERTION_LEVEL_ATTRIBUTE), false); if ((cas != null) && (cas.Length > 0)) { l_same_level = true; l_computed = false; l_common_level = ASSERTION_LEVEL_ENUM.no; foreach (object ca in cas) { level_attribute = (ASSERTION_LEVEL_ATTRIBUTE)ca; l_current_level = level_attribute.assertion_level; assertion_levels.Add( level_attribute.class_type, // key l_current_level); // value if (!l_computed) { l_common_level = l_current_level; l_computed = true; } else { if (l_same_level) { l_same_level = (l_common_level == l_current_level); } } } if (l_same_level) { global_assertion_level = l_common_level; is_global_assertion_level_set = true; } else { is_global_assertion_level_set = false; } } else { global_assertion_level = ASSERTION_LEVEL_ENUM.no; is_global_assertion_level_set = true; } } catch { global_assertion_level = ASSERTION_LEVEL_ENUM.no; is_global_assertion_level_set = true; } }
/* * feature -- Status report */ public static bool conforms_to(object Current, object other) // Does type of current object conform to type // of `other' (as per Eiffel: The Language, chapter 13)? { bool Result = false; RT_GENERIC_TYPE l_current_type, l_other_type; EIFFEL_TYPE_INFO current_info = Current as EIFFEL_TYPE_INFO; EIFFEL_TYPE_INFO other_info = other as EIFFEL_TYPE_INFO; #if ASSERTIONS ASSERTIONS.REQUIRE("other_not_void", other != null); #endif if (Current == null) { generate_call_on_void_target_exception(); } else { if (other_info == null) { // `other' is not an Eiffel object, we simply check for .NET conformance Result = other.GetType().IsAssignableFrom(Current.GetType()); } else if (current_info == null) { // `other' is an Eiffel object, but not `Current', therefore there is // no conformance. We do nothing since `Result' is already initialized to // false. } else { l_current_type = current_info.____type(); l_other_type = other_info.____type(); if (l_other_type == null) { // Parent type represented by the `other' instance // is not generic, therefore `Current' should directly // conform to the parent type. Result = ISE_RUNTIME.interface_type(other_info.GetType()).IsAssignableFrom(Current.GetType()); } else if (l_current_type == null) { // Parent is generic, but not type represented by // `Current', so let's first check if it simply // conforms without looking at the generic parameter. Result = ISE_RUNTIME.interface_type(other_info.GetType()).IsAssignableFrom(Current.GetType()); if (Result) { // It does conform, so now we have to go through // the parents to make sure it has the same generic // derivation. // FIXME: we should use feature `conform_to' from RT_TYPE here. } } else { // Both types are generic. We first check if they // simply conforms. #if ASSERTIONS ASSERTIONS.CHECK("l_current_type_not_void", l_current_type != null); ASSERTIONS.CHECK("l_other_type_not_void", l_other_type != null); #endif Result = ISE_RUNTIME.interface_type(other_info.GetType()).IsAssignableFrom(Current.GetType()); if (Result) { Result = l_current_type.conform_to(l_other_type); } } } } return(Result); }