2
0
Эх сурвалжийг харах

2002-10-22 Miguel de Icaza <[email protected]>

	* ecore.cs (PropertyExpr): Do not use PropertyInfo.CanRead,
	CanWrite, because those refer to this particular instance of the
	property, and do not take into account the fact that we can
	override single members of a property.

	Constructor requires an EmitContext.  The resolution process does
	not happen here, but we need to compute the accessors before,
	because the resolution does not always happen for properties.

	* typemanager.cs (RealMemberLookup): Set private_ok if we are a
	subclass, before we did not update this flag, but we did update
	bindingflags.

	(GetAccessors): Drop this routine, as it did not work in the
	presence of partially overwritten set/get methods.

	Notice that this broke the cs1540 detection, but that will require
	more thinking.

svn path=/trunk/mcs/; revision=8485
Miguel de Icaza 23 жил өмнө
parent
commit
4d13319167

+ 21 - 0
mcs/mcs/ChangeLog

@@ -1,3 +1,24 @@
+2002-10-22  Miguel de Icaza  <[email protected]>
+
+	* ecore.cs (PropertyExpr): Do not use PropertyInfo.CanRead,
+	CanWrite, because those refer to this particular instance of the
+	property, and do not take into account the fact that we can
+	override single members of a property.
+
+	Constructor requires an EmitContext.  The resolution process does
+	not happen here, but we need to compute the accessors before,
+	because the resolution does not always happen for properties.
+	
+	* typemanager.cs (RealMemberLookup): Set private_ok if we are a
+	subclass, before we did not update this flag, but we did update
+	bindingflags. 
+
+	(GetAccessors): Drop this routine, as it did not work in the
+	presence of partially overwritten set/get methods. 
+
+	Notice that this broke the cs1540 detection, but that will require
+	more thinking. 
+	
 2002-10-22  Gonzalo Paniagua Javier <[email protected]>
 
 	* class.cs:

+ 42 - 22
mcs/mcs/ecore.cs

@@ -512,7 +512,7 @@ namespace Mono.CSharp {
 			else if (mi is FieldInfo)
 				return new FieldExpr ((FieldInfo) mi, loc);
 			else if (mi is PropertyInfo)
-				return new PropertyExpr ((PropertyInfo) mi, loc);
+				return new PropertyExpr (ec, (PropertyInfo) mi, loc);
 		        else if (mi is Type){
 				return new TypeExpr ((System.Type) mi, loc);
 			}
@@ -4104,29 +4104,21 @@ namespace Mono.CSharp {
 	public class PropertyExpr : ExpressionStatement, IAssignMethod, IMemberExpr {
 		public readonly PropertyInfo PropertyInfo;
 		public bool IsBase;
-		MethodInfo [] Accessors;
+		MethodInfo getter, setter;
 		bool is_static;
 		
 		Expression instance_expr;
 
-		public PropertyExpr (PropertyInfo pi, Location l)
+		public PropertyExpr (EmitContext ec, PropertyInfo pi, Location l)
 		{
 			PropertyInfo = pi;
 			eclass = ExprClass.PropertyAccess;
 			is_static = false;
 			loc = l;
-			Accessors = TypeManager.GetAccessors (pi);
 
-			if (Accessors != null)
-				foreach (MethodInfo mi in Accessors){
-					if (mi != null)
-						if (mi.IsStatic)
-							is_static = true;
-				}
-			else
-				Accessors = new MethodInfo [2];
-			
 			type = TypeManager.TypeToCoreType (pi.PropertyType);
+
+			ResolveAccessors (ec);
 		}
 
 		public string Name {
@@ -4178,9 +4170,39 @@ namespace Mono.CSharp {
 			return true;
 		}
 
+		void ResolveAccessors (EmitContext ec)
+		{
+			BindingFlags flags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance;
+			MemberInfo [] group;
+			
+			group = TypeManager.MemberLookup (ec.ContainerType, PropertyInfo.DeclaringType,
+							      MemberTypes.Method, flags, "get_" + PropertyInfo.Name);
+
+			//
+			// The first method is the closest to us
+			//
+			if (group != null && group.Length > 0){
+				getter = (MethodInfo) group [0];
+
+				if (getter.IsStatic)
+					is_static = true;
+			} 			
+
+			//
+			// The first method is the closest to us
+			//
+			group = TypeManager.MemberLookup (ec.ContainerType, PropertyInfo.DeclaringType,
+							  MemberTypes.Method, flags, "set_" + PropertyInfo.Name);
+			if (group != null && group.Length > 0){
+				setter = (MethodInfo) group [0];
+				if (setter.IsStatic)
+					is_static = true;
+			}
+		}
+
 		override public Expression DoResolve (EmitContext ec)
 		{
-			if (!PropertyInfo.CanRead){
+			if (getter == null){
 				Report.Error (154, loc, 
 					      "The property `" + PropertyInfo.Name +
 					      "' can not be used in " +
@@ -4204,7 +4226,7 @@ namespace Mono.CSharp {
 
 		override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
 		{
-			if (!PropertyInfo.CanWrite){
+			if (setter == null){
 				Report.Error (154, loc, 
 					      "The property `" + PropertyInfo.Name +
 					      "' can not be used in " +
@@ -4223,13 +4245,11 @@ namespace Mono.CSharp {
 
 		override public void Emit (EmitContext ec)
 		{
-			MethodInfo method = Accessors [0];
-
 			//
-			// Special case: length of single dimension array is turned into ldlen
+			// Special case: length of single dimension array property is turned into ldlen
 			//
-			if ((method == TypeManager.system_int_array_get_length) ||
-			    (method == TypeManager.int_array_get_length)){
+			if ((getter == TypeManager.system_int_array_get_length) ||
+			    (getter == TypeManager.int_array_get_length)){
 				Type iet = instance_expr.Type;
 
 				//
@@ -4243,7 +4263,7 @@ namespace Mono.CSharp {
 				}
 			}
 
-			Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, method, null, loc);
+			Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, getter, null, loc);
 			
 		}
 
@@ -4256,7 +4276,7 @@ namespace Mono.CSharp {
 			ArrayList args = new ArrayList ();
 
 			args.Add (arg);
-			Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, Accessors [1], args, loc);
+			Invocation.EmitCall (ec, IsBase, IsStatic, instance_expr, setter, args, loc);
 		}
 
 		override public void EmitStatement (EmitContext ec)

+ 4 - 38
mcs/mcs/typemanager.cs

@@ -1416,37 +1416,6 @@ public class TypeManager {
 		return true;
 	}
 
-	//
-	// FIXME: we need to return the accessors depending on whether
-	// they are visible or not.
-	//
-	static public MethodInfo [] GetAccessors (PropertyInfo pi)
-	{
-		MethodInfo [] ret;
-
-		if (pi is PropertyBuilder){
-			Pair pair = (Pair) properties [pi];
-
-			ret = new MethodInfo [2];
-			ret [0] = (MethodInfo) pair.First;
-			ret [1] = (MethodInfo) pair.Second;
-
-			return ret;
-		} else {
-			MethodInfo [] mi = new MethodInfo [2];
-
-			//
-			// Why this and not pi.GetAccessors?
-			// Because sometimes index 0 is the getter
-			// sometimes it is 1
-			//
-			mi [0] = pi.GetGetMethod (true);
-			mi [1] = pi.GetSetMethod (true);
-
-			return mi;
-		}
-	}
-
 	static public MethodInfo GetPropertyGetter (PropertyInfo pi)
 	{
 		if (pi is PropertyBuilder){
@@ -2003,12 +1972,6 @@ public class TypeManager {
 				if (!IsSubclassOrNestedChildOf (closure_invocation_type, mb.DeclaringType))
 					return false;
 
-				// Although a derived class can access protected members of its base class
-				// it cannot do so through an instance of the base class (CS1540).
-				if ((closure_invocation_type != closure_start_type) &&
-				    closure_invocation_type.IsSubclassOf (closure_start_type))
-					return false;
-
 				return true;
 			}
 
@@ -2147,7 +2110,10 @@ public class TypeManager {
 				} else
 					private_ok = always_ok_flag;
 
-				if (private_ok || invocation_type.IsSubclassOf (current_type))
+				if (invocation_type.IsSubclassOf (current_type))
+					private_ok = true;
+				
+				if (private_ok)
 					bf = original_bf | BindingFlags.NonPublic;
 			} else {
 				private_ok = false;