Ver código fonte

2001-12-27 Miguel de Icaza <[email protected]>

	* statement.cs (Foreach.GetEnumeratorFilter): Do not compare
	against IEnumerator, test whether the return value is a descendant
	of the IEnumerator interface.

	* class.cs (Indexer.Define): Use an auxiliary method to implement
	the other bits of the method definition.  Begin support for
	explicit interface implementation.

	(Property.DefineMethod): Use TypeManager.void_type instead of null
	for an empty return value.

svn path=/trunk/mcs/; revision=1720
Miguel de Icaza 24 anos atrás
pai
commit
ffe4df2dfa

+ 42 - 0
mcs/mcs/ChangeLog

@@ -1,3 +1,45 @@
+2001-12-27  Miguel de Icaza  <[email protected]>
+
+	* statement.cs (Foreach.GetEnumeratorFilter): Do not compare
+	against IEnumerator, test whether the return value is a descendant
+	of the IEnumerator interface.
+
+	* class.cs (Indexer.Define): Use an auxiliary method to implement
+	the other bits of the method definition.  Begin support for
+	explicit interface implementation.
+
+	(Property.DefineMethod): Use TypeManager.void_type instead of null
+	for an empty return value.
+
+2001-12-26  Miguel de Icaza  <[email protected]>
+
+	* expression.cs (MemberAccess.ResolveMemberAccess): if we are
+	dealing with a FieldExpr which is composed of a FieldBuilder, in
+	the code path we did extract the constant, but we should have
+	obtained the underlying value to be able to cast it (otherwise we
+	end up in an infinite loop, this is what Ravi was running into).
+
+	(ArrayCreation.UpdateIndices): Arrays might be empty.
+
+	(MemberAccess.ResolveMemberAccess): Add support for section
+	14.5.4.1 that deals with the special case of E.I when E is a type
+	and something else, that I can be a reference to a static member.
+
+	(ArrayCreation.MakeByteBlob): It is not an error to not be able to
+	handle a particular array type to create byte blobs, it is just
+	something we dont generate byteblobs for.
+
+	* cs-tokenizer.cs (get_cmd_arg): Ignore \r in commands and
+	arguments. 
+
+	* location.cs (Push): remove the key from the hashtable that we
+	are about to add.   This happens for empty files.
+
+	* driver.cs: Dispose files after we have parsed them.
+
+	(tokenize): new function that only runs the tokenizer on its
+	input, for speed testing.
+
 2001-12-26  Ravi Pratap  <[email protected]>
 
 	* class.cs (Event.Define): Define the private field only if there

+ 6 - 1
mcs/mcs/TODO

@@ -262,6 +262,12 @@ OPTIMIZATIONS
 
 * Add a cache for the various GetArrayMethod operations.
 
+* Optimization:
+
+	Do not use StatementCollections, use ArrayLists of Statements,
+	and then "copy" it out to arrays.  Then reuse the existing
+	Statement structures.
+
 RECOMMENDATIONS
 ---------------
 
@@ -302,7 +308,6 @@ RECOMMENDATIONS
 
 	Maybe keep a pool of constants/literals (zero, 1)?
 
-
 ************
 Potential bug:
 

+ 98 - 19
mcs/mcs/class.cs

@@ -1327,7 +1327,7 @@ namespace Mono.CSharp {
 		{
 			if (pending_implementations == null)
 				return null;
-			
+
 			foreach (TypeAndMethods tm in pending_implementations){
 				if (!(t == null || tm.type == t))
 					continue;
@@ -1338,7 +1338,7 @@ namespace Mono.CSharp {
 						i++;
 						continue;
 					}
-					
+
 					if (Name != m.Name){
 						i++;
 						continue;
@@ -1458,7 +1458,7 @@ namespace Mono.CSharp {
 		/// </summary>
 		public void Emit ()
 		{
-			Console.WriteLine ("Emitting code for: " + TypeBuilder.FullName);
+//			Console.WriteLine ("Emitting code for: " + TypeBuilder.FullName);
 			if (constructors != null)
 				foreach (Constructor c in constructors)
 					c.Emit (this);
@@ -2562,7 +2562,7 @@ namespace Mono.CSharp {
 				name = "set_" + short_name;
 				parameters = new Type [1];
 				parameters [0] = PropertyType;
-				fn_type = null;
+				fn_type = TypeManager.void_type;
 			}
 
 			implementing = parent.IsInterfaceMethod (
@@ -3124,9 +3124,80 @@ namespace Mono.CSharp {
 			OptAttributes = attrs;
 		}
 
-		public override bool Define (TypeContainer parent)
+		void DefineMethod (TypeContainer parent, Type iface_type,
+				   Type ret_type, string name,
+				   Type [] parameters, bool is_get)
 		{
 			MethodAttributes attr = Modifiers.MethodAttr (ModFlags);
+			MethodInfo implementing;
+
+			implementing = parent.IsInterfaceMethod (
+				iface_type, name, ret_type, parameters, false);
+
+			//
+			// Setting null inside this block will trigger a more
+			// verbose error reporting for missing interface implementations
+			//
+			// The "candidate" function has been flagged already
+			// but it wont get cleared
+			//
+			if (implementing != null){
+				if (iface_type == null){
+					if ((ModFlags & Modifiers.PUBLIC) == 0)
+						implementing = null;
+					if ((ModFlags & Modifiers.STATIC) != 0)
+						implementing = null;
+				} else {
+					if((ModFlags&(Modifiers.PUBLIC | Modifiers.ABSTRACT)) != 0){
+						Report.Error (
+							106, Location,
+							"`public' or `abstract' modifiers are not "+
+							"allowed in explicit interface declarations"
+							);
+						implementing = null;
+					}
+				}
+			}
+			if (implementing != null){
+				attr |=
+					MethodAttributes.Virtual |
+					MethodAttributes.NewSlot |
+					MethodAttributes.HideBySig;
+				
+				// If not abstract, then we can set Final.
+				if ((attr & MethodAttributes.Abstract) == 0)
+					attr |= MethodAttributes.Final;
+				
+				//
+				// clear the pending flag
+				//
+				parent.IsInterfaceMethod (
+					iface_type, name, ret_type, parameters, true);
+			}
+
+			if (is_get){
+				GetBuilder = parent.TypeBuilder.DefineMethod (
+					"get_Item", attr, IndexerType, parameters);
+
+				if (implementing != null)
+					parent.TypeBuilder.DefineMethodOverride (
+						GetBuilder, implementing);
+
+				PropertyBuilder.SetGetMethod (GetBuilder);
+			} else {
+				SetBuilder = parent.TypeBuilder.DefineMethod (
+					"set_Item", attr, null, parameters);
+
+				if (implementing != null)
+					parent.TypeBuilder.DefineMethodOverride (
+						SetBuilder, implementing);
+					
+				PropertyBuilder.SetSetMethod (SetBuilder);
+			}
+		}
+			
+		public override bool Define (TypeContainer parent)
+		{
 			PropertyAttributes prop_attr =
 				PropertyAttributes.RTSpecialName |
 				PropertyAttributes.SpecialName;
@@ -3156,10 +3227,13 @@ namespace Mono.CSharp {
 				TypeManager.IndexerPropertyName (parent.TypeBuilder),
 				prop_attr, IndexerType, parameters);
 
+			//
+			// FIXME: Implement explicit implementation
+			//
+			Type iface_type = null;
+			
 			if (Get != null){
-				GetBuilder = parent.TypeBuilder.DefineMethod (
-					"get_Item", attr, IndexerType, parameters);
-
+				DefineMethod (parent, iface_type, IndexerType, "get_Item", parameters, true);
                                 InternalParameters pi = new InternalParameters (parent, FormalParameters);
 				if (!TypeManager.RegisterMethod (GetBuilder, pi, parameters)) {
 					Report.Error (111, Location,
@@ -3169,7 +3243,6 @@ namespace Mono.CSharp {
 						      "'get' indexer");
 					return false;
 				}
-				PropertyBuilder.SetGetMethod (GetBuilder);
 			}
 			
 			if (Set != null){
@@ -3183,26 +3256,32 @@ namespace Mono.CSharp {
 				Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
 
 				fixed_parms.CopyTo (tmp, 0);
-				tmp [fixed_parms.Length] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
+				tmp [fixed_parms.Length] = new Parameter (
+					Type, "value", Parameter.Modifier.NONE, null);
 
 				Parameters set_formal_params = new Parameters (tmp, null, Location);
 				
-				SetBuilder = parent.TypeBuilder.DefineMethod (
-					"set_Item", attr, null, set_pars);
+				DefineMethod (
+					parent, iface_type, TypeManager.void_type,
+					"set_Item", set_pars, false);
+
 				InternalParameters ip = new InternalParameters (parent, set_formal_params);
 				
 				if (!TypeManager.RegisterMethod (SetBuilder, ip, set_pars)) {
-					Report.Error (111, Location,
-					       "Class `" + parent.Name + "' already contains a definition with the " +
-					       "same return value and parameter types for the " +
-					       "'set' indexer");
+					Report.Error (
+						111, Location,
+						"Class `" + parent.Name + "' already contains a " +
+						"definition with the " +
+						"same return value and parameter types for the " +
+						"'set' indexer");
 					return false;
 				}
-				PropertyBuilder.SetSetMethod (SetBuilder);
 			}
 
+			//
+			// Now name the parameters
+			//
 			Parameter [] p = FormalParameters.FixedParameters;
-
 			if (p != null) {
 				int i;
 				
@@ -3407,7 +3486,7 @@ namespace Mono.CSharp {
 						"object type");
 					return false;
 				}
-				
+
 				if (first_arg_type.IsInterface || return_type.IsInterface){
 					Report.Error (
 						552, Location,

+ 2 - 1
mcs/mcs/codegen.cs

@@ -180,7 +180,8 @@ namespace Mono.CSharp {
 		public void EmitTopBlock (Block block, Location loc)
 		{
 			bool has_ret = false;
-			
+
+//			Console.WriteLine ("Emitting: " + loc);
 			if (block != null){
 				int errors = Report.Errors;
 				

+ 9 - 3
mcs/mcs/cs-tokenizer.cs

@@ -790,8 +790,11 @@ namespace Mono.CSharp
 			arg = "";
 			static_cmd_arg.Length = 0;
 				
-			while ((c = getChar ()) != -1 && (c != '\n') && (c != ' '))
+			while ((c = getChar ()) != -1 && (c != '\n') && (c != ' ')){
+				if (c == '\r')
+					continue;
 				static_cmd_arg.Append ((char) c);
+			}
 
 			cmd = static_cmd_arg.ToString ();
 
@@ -814,8 +817,11 @@ namespace Mono.CSharp
 			static_cmd_arg.Length = 0;
 			static_cmd_arg.Append ((char) c);
 			
-			while ((c = getChar ()) != -1 && (c != '\n'))
+			while ((c = getChar ()) != -1 && (c != '\n')){
+				if (c == '\r')
+					continue;
 				static_cmd_arg.Append ((char) c);
+			}
 
 			if (c == '\n'){
 				line++;
@@ -1047,7 +1053,7 @@ namespace Mono.CSharp
 				}
 			}
 			
-			Report.Error (1024, "Preprocessor directive expected");
+			Report.Error (1024, "Preprocessor directive expected (got: " + cmd + ")");
 			return true;
 		}
 		

+ 1 - 1
mcs/mcs/delegate.cs

@@ -532,7 +532,7 @@ namespace Mono.CSharp {
 				return null;
 			
 			Expression e = a.Expr;
-			
+
 			if (e is MethodGroupExpr) {
 				MethodGroupExpr mg = (MethodGroupExpr) e;
 

+ 44 - 2
mcs/mcs/driver.cs

@@ -34,8 +34,12 @@ namespace Mono.CSharp
 		// Lookup paths
 		static ArrayList link_paths;
 
+		// Whether we want Yacc to output its progress
 		static bool yacc_verbose = false;
 
+		// Whether we want to only run the tokenizer
+		static bool tokenize = false;
+		
 		static int error_count = 0;
 
 		static string first_source;
@@ -46,6 +50,31 @@ namespace Mono.CSharp
 		static bool parse_only = false;
 
 		static ArrayList defines;
+
+		static int tokenize_file (string input_file)
+		{
+			Stream input;
+
+			try {
+				input = File.OpenRead (input_file);
+
+			} catch {
+				Report.Error (2001, "Source file '" + input_file + "' could not be opened");
+				return 1;
+			}
+
+			using (input){
+				Tokenizer lexer = new Tokenizer (input, input_file, defines);
+				int token, tokens = 0;
+
+				while ((token = lexer.token ()) != Token.EOF){
+					Location l = lexer.Location;
+					tokens++;
+				}
+			}
+			
+			return 0;
+		}
 		
 		static int parse (string input_file)
 		{
@@ -63,11 +92,13 @@ namespace Mono.CSharp
 			parser = new CSharpParser (input_file, input, defines);
 			parser.yacc_verbose = yacc_verbose;
 			try {
-				errors = parser.parse ();
+				errors = parser.parse ();
 			} catch (Exception ex) {
 				Console.WriteLine (ex);
 				Console.WriteLine ("Compilation aborted");
 				return 1;
+			} finally {
+				input.Close ();
 			}
 			
 			return errors;
@@ -312,6 +343,11 @@ namespace Mono.CSharp
 						continue;
 					}
 
+					case "--tokenize": {
+						tokenize = true;
+						continue;
+					}
+					
 					case "-o": case "--output":
 						if ((i + 1) >= argc){
 							Usage (true);
@@ -442,10 +478,16 @@ namespace Mono.CSharp
 						errors++;
 						continue;
 					}
-					errors += parse (f);
+					if (tokenize)
+						tokenize_file (f);
+					else 
+						errors += parse (f);
 				}
 			}
 
+			if (tokenize)
+				return;
+			
 			if (first_source == null){
 				Report.Error (2008, "No files to compile were specified");
 				return;

+ 1 - 1
mcs/mcs/ecore.cs

@@ -2773,7 +2773,7 @@ namespace Mono.CSharp {
 					if (instance_expr != null)
 						instance_expr = instance_expr.Resolve (ec);
 					
-					return MemberAccess.ResolveMemberAccess (ec, ml, instance_expr, Location);
+					return MemberAccess.ResolveMemberAccess (ec, ml, instance_expr, Location, null);
 				}
 			}
 				

+ 48 - 14
mcs/mcs/expression.cs

@@ -3345,6 +3345,7 @@ namespace Mono.CSharp {
 		public override void Emit (EmitContext ec)
 		{
 			MethodGroupExpr mg = (MethodGroupExpr) this.expr;
+
 			EmitCall (ec, method.IsStatic, mg.InstanceExpression, method, Arguments);
 		}
 		
@@ -3673,8 +3674,7 @@ namespace Mono.CSharp {
 		{
 			int i = 0;
 			for (ArrayList probe = Initializers; probe != null;) {
-				
-				if (probe [0] is ArrayList) {
+				if (probe.Count > 0 && probe [0] is ArrayList) {
 					Expression e = new IntConstant (probe.Count);
 					Arguments.Add (new Argument (e, Argument.AType.Expression));
 
@@ -3863,10 +3863,8 @@ namespace Mono.CSharp {
 				 underlying_type == TypeManager.char_type ||
 				 underlying_type == TypeManager.ushort_type)
 				factor = 2;
-			else {
-				Report.Error (-100, loc, "Unhandled type in MakeByteBlob!!");
+			else
 				return null;
-			}
 
 			data = new byte [count * factor];
 			int idx = 0;
@@ -4247,8 +4245,26 @@ namespace Mono.CSharp {
 		}
 
 #if USE_OLD
+		static bool IdenticalNameAndTypeName (EmitContext ec, Expression left_original, Location loc)
+		{
+			if (left_original == null)
+				return false;
+
+			if (!(left_original is SimpleName))
+				return false;
+
+			SimpleName sn = (SimpleName) left_original;
+
+			Type t = RootContext.LookupType (ec.TypeContainer, sn.Name, true, loc);
+			if (t != null)
+				return true;
+
+			return false;
+		}
+		
 		public static Expression ResolveMemberAccess (EmitContext ec, Expression member_lookup,
-							      Expression left, Location loc)
+							      Expression left, Location loc,
+							      Expression left_original)
 		{
 			//
 			// Method Groups
@@ -4272,6 +4288,14 @@ namespace Mono.CSharp {
 				// Instance.MethodGroup
 				//
 				if (!mg.RemoveStaticMethods ()){
+					if (IdenticalNameAndTypeName (ec, left_original, loc)){
+						if (!mg.RemoveInstanceMethods ()){
+							SimpleName.Error120 (loc, mg.Methods [0].Name);
+							return null;
+						}
+						return member_lookup;
+					}
+					
 					error176 (loc, mg.Methods [0].Name);
 					return null;
 				}
@@ -4290,7 +4314,8 @@ namespace Mono.CSharp {
 					
 					if (c != null) {
 						object o = c.LookupConstantValue (ec);
-						return Constantify (o, fi.FieldType);
+						object real_value = ((Constant) c.Expr).GetValue ();
+						return Constantify (real_value, fi.FieldType);
 					}
 				}
 
@@ -4305,8 +4330,8 @@ namespace Mono.CSharp {
 						o = fi.GetValue (fi);
 					
 					if (decl_type.IsSubclassOf (TypeManager.enum_type)) {
-						Expression enum_member = MemberLookup (ec, decl_type, "value__",
-										       false, loc); 
+						Expression enum_member = MemberLookup (
+							ec, decl_type, "value__", false, loc); 
 
 						Enum en = TypeManager.LookupEnum (decl_type);
 
@@ -4330,6 +4355,7 @@ namespace Mono.CSharp {
 				}
 				
 				if (left is TypeExpr){
+					// and refers to a type name or an 
 					if (!fe.FieldInfo.IsStatic){
 						error176 (loc, fe.FieldInfo.Name);
 						return null;
@@ -4337,6 +4363,9 @@ namespace Mono.CSharp {
 					return member_lookup;
 				} else {
 					if (fe.FieldInfo.IsStatic){
+						if (IdenticalNameAndTypeName (ec, left_original, loc))
+							return member_lookup;
+
 						error176 (loc, fe.FieldInfo.Name);
 						return null;
 					}
@@ -4357,6 +4386,8 @@ namespace Mono.CSharp {
 					return pe;
 				} else {
 					if (pe.IsStatic){
+						if (IdenticalNameAndTypeName (ec, left_original, loc))
+							return member_lookup;
 						error176 (loc, pe.PropertyInfo.Name);
 						return null;
 					}
@@ -4397,8 +4428,7 @@ namespace Mono.CSharp {
 						Report.Error (-200, loc, "Internal error!!");
 						return null;
 					}
-					
-					return ResolveMemberAccess (ec, ml, left, loc);
+					return ResolveMemberAccess (ec, ml, left, loc, left_original);
 				}
 
 				if (left is TypeExpr) {
@@ -4411,6 +4441,9 @@ namespace Mono.CSharp {
 
 				} else {
 					if (ee.IsStatic) {
+						if (IdenticalNameAndTypeName (ec, left_original, loc))
+							return ee;
+						    
 						error176 (loc, ee.EventInfo.Name);
 						return null;
 					}
@@ -4438,6 +4471,7 @@ namespace Mono.CSharp {
 			// We are the sole users of ResolveWithSimpleName (ie, the only
 			// ones that can cope with it
 			//
+			Expression original = expr;
 			expr = expr.ResolveWithSimpleName (ec);
 
 			if (expr == null)
@@ -4473,12 +4507,12 @@ namespace Mono.CSharp {
 				}
 			}
 
-			member_lookup = MemberLookup (ec, expr.Type, Identifier, false, loc);
+			member_lookup = MemberLookup (ec, expr_type, Identifier, false, loc);
 
 			if (member_lookup == null)
 				return null;
 
-			return ResolveMemberAccess (ec, member_lookup, expr, loc);
+			return ResolveMemberAccess (ec, member_lookup, expr, loc, original);
 		}
 
 #else
@@ -5264,7 +5298,7 @@ namespace Mono.CSharp {
 			else
 				left = new This (loc).Resolve (ec);
 			
-			return MemberAccess.ResolveMemberAccess (ec, member_lookup, left, loc);
+			return MemberAccess.ResolveMemberAccess (ec, member_lookup, left, loc, null);
 		}
 
 		public override void Emit (EmitContext ec)

+ 1 - 0
mcs/mcs/location.cs

@@ -40,6 +40,7 @@ namespace Mono.CSharp {
 	
 		static public void Push (string name)
 		{
+			map.Remove (global_count);
 			map.Add (global_count, name);
 			list.Add (global_count);
 			module_base = global_count;

+ 12 - 4
mcs/mcs/statement.cs

@@ -911,15 +911,21 @@ namespace Mono.CSharp {
 					b.UsageWarning ();
 		}
 
+//		static int count;
+		
 		public override bool Emit (EmitContext ec)
 		{
 			bool is_ret = false;
 			Block prev_block = ec.CurrentBlock;
 
+//			count++;
 			ec.CurrentBlock = this;
+//			if (count == 40)
+//				throw new Exception ();
 			foreach (Statement s in Statements)
 				is_ret = s.Emit (ec);
-
+//			count--;
+			
 			ec.CurrentBlock = prev_block;
 			return is_ret;
 		}
@@ -1831,9 +1837,11 @@ namespace Mono.CSharp {
 				return false;
 			
 			MethodInfo mi = (MethodInfo) m;
-			
-			if (mi.ReturnType != TypeManager.ienumerator_type)
-				return false;
+
+			if (mi.ReturnType != TypeManager.ienumerator_type){
+				if (!TypeManager.ienumerator_type.IsAssignableFrom (mi.ReturnType))
+					return false;
+			}
 			
 			Type [] args = TypeManager.GetArgumentTypes (mi);
 			if (args == null)