Author: martin
Date: 2005-08-03 11:50:23 -0400 (Wed, 03 Aug 2005)
New Revision: 47969
Modified:
trunk/mcs/gmcs/ChangeLog
trunk/mcs/gmcs/class.cs
trunk/mcs/gmcs/decl.cs
trunk/mcs/gmcs/generic.cs
trunk/mcs/gmcs/iterators.cs
trunk/mcs/gmcs/statement.cs
Log:
2005-08-03 Martin Baulig <[EMAIL PROTECTED]>
Make iterators in generic methods work; see gtest-191.cs.
* generic.cs
(Constraints.Resolve): Protect against being called twice.
* class.cs
(TypeContainer.GetClassBases): Make this `protected virtual'.
* iterator.cs (Iterator.ctor): Added `GenericMethod' argument.
(Iterator.GetClassBases): Override this and compute the base
classes here.
(Iterator.DefineNestedTypes): If we're a generic method, all our
method type parameters become class type parameters on the proxy
class.
* statement.cs
(ToplevelBlock.Parameters): Make this a property, not a field.
(ToplevelBlock.ResolveMeta): Update the `parameters' from the `ip'.
Modified: trunk/mcs/gmcs/ChangeLog
===================================================================
--- trunk/mcs/gmcs/ChangeLog 2005-08-03 15:45:25 UTC (rev 47968)
+++ trunk/mcs/gmcs/ChangeLog 2005-08-03 15:50:23 UTC (rev 47969)
@@ -1,5 +1,26 @@
2005-08-03 Martin Baulig <[EMAIL PROTECTED]>
+ Make iterators in generic methods work; see gtest-191.cs.
+
+ * generic.cs
+ (Constraints.Resolve): Protect against being called twice.
+
+ * class.cs
+ (TypeContainer.GetClassBases): Make this `protected virtual'.
+
+ * iterator.cs (Iterator.ctor): Added `GenericMethod' argument.
+ (Iterator.GetClassBases): Override this and compute the base
+ classes here.
+ (Iterator.DefineNestedTypes): If we're a generic method, all our
+ method type parameters become class type parameters on the proxy
+ class.
+
+ * statement.cs
+ (ToplevelBlock.Parameters): Make this a property, not a field.
+ (ToplevelBlock.ResolveMeta): Update the `parameters' from the `ip'.
+
+2005-08-03 Martin Baulig <[EMAIL PROTECTED]>
+
* typemanager.cs (TypeManager.IsSubclassOf): Use
`TypeManager.IsEqual' instead of `Type.Equals'; fixes gtest-190.cs.
(TypeManager.GetFullName_recursed): Improved.
Modified: trunk/mcs/gmcs/class.cs
===================================================================
--- trunk/mcs/gmcs/class.cs 2005-08-03 15:45:25 UTC (rev 47968)
+++ trunk/mcs/gmcs/class.cs 2005-08-03 15:50:23 UTC (rev 47969)
@@ -1054,7 +1054,7 @@
/// The @base_class argument is set to the base object or null
/// if this is `System.Object'.
/// </summary>
- TypeExpr [] GetClassBases (out TypeExpr base_class)
+ protected virtual TypeExpr [] GetClassBases (out TypeExpr
base_class)
{
int i;
@@ -4199,7 +4199,7 @@
//
if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
Iterator iterator = new Iterator (
- this, Parent, ParameterInfo, ModFlags);
+ this, Parent, GenericMethod,
ParameterInfo, ModFlags);
if (!iterator.DefineIterator ())
return false;
@@ -6516,8 +6516,8 @@
// Setup iterator if we are one
//
if (yields) {
- Iterator iterator = new Iterator (this,
- Parent, method.ParameterInfo,
ModFlags);
+ Iterator iterator = new Iterator (
+ this, Parent, null,
method.ParameterInfo, ModFlags);
if (!iterator.DefineIterator ())
return null;
@@ -7620,7 +7620,7 @@
//
if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
Iterator iterator = new Iterator (
- Get, Parent, Get.ParameterInfo,
ModFlags);
+ Get, Parent, null,
Get.ParameterInfo, ModFlags);
if (!iterator.DefineIterator ())
return false;
Modified: trunk/mcs/gmcs/decl.cs
===================================================================
--- trunk/mcs/gmcs/decl.cs 2005-08-03 15:45:25 UTC (rev 47968)
+++ trunk/mcs/gmcs/decl.cs 2005-08-03 15:50:23 UTC (rev 47969)
@@ -1252,6 +1252,8 @@
Constraints constraints = null;
if (constraints_list != null) {
foreach (Constraints constraint in
constraints_list) {
+ if (constraint == null)
+ continue;
if (constraint.TypeParameter ==
name) {
constraints =
constraint;
break;
Modified: trunk/mcs/gmcs/generic.cs
===================================================================
--- trunk/mcs/gmcs/generic.cs 2005-08-03 15:45:25 UTC (rev 47968)
+++ trunk/mcs/gmcs/generic.cs 2005-08-03 15:50:23 UTC (rev 47969)
@@ -156,9 +156,13 @@
Type class_constraint_type;
Type[] iface_constraint_types;
Type effective_base_type;
+ bool resolved;
public bool Resolve (EmitContext ec)
{
+ if (resolved)
+ return true;
+
iface_constraints = new ArrayList ();
type_param_constraints = new ArrayList ();
@@ -245,6 +249,7 @@
num_constraints++;
}
+ resolved = true;
return true;
}
Modified: trunk/mcs/gmcs/iterators.cs
===================================================================
--- trunk/mcs/gmcs/iterators.cs 2005-08-03 15:45:25 UTC (rev 47968)
+++ trunk/mcs/gmcs/iterators.cs 2005-08-03 15:50:23 UTC (rev 47969)
@@ -124,7 +124,7 @@
protected ToplevelBlock original_block;
protected ToplevelBlock block;
- Type iterator_type;
+ Type original_iterator_type;
TypeExpr iterator_type_expr;
bool is_enumerable;
public readonly bool IsStatic;
@@ -139,10 +139,12 @@
//
// Context from the original method
//
+ GenericMethod generic_method;
TypeContainer container;
TypeExpr current_type;
Type this_type;
InternalParameters parameters;
+ InternalParameters original_parameters;
IMethodData orig_method;
MethodInfo dispose_method;
@@ -334,30 +336,48 @@
point.Define (ig);
}
- private static MemberName MakeProxyName (string name)
+ private static MemberName MakeProxyName (string name,
GenericMethod generic, Location loc)
{
int pos = name.LastIndexOf ('.');
if (pos > 0)
name = name.Substring (pos + 1);
- return new MemberName ("<" + name + ">__" +
(proxy_count++));
+ string proxy_name = "<" + name + ">__" +
(proxy_count++);
+
+ if (generic != null) {
+ TypeArguments args = new TypeArguments (loc);
+ foreach (TypeParameter tparam in
generic.CurrentTypeParameters)
+ args.Add (new SimpleName (tparam.Name,
loc));
+ return new MemberName (proxy_name, args);
+ } else
+ return new MemberName (proxy_name);
}
//
// Our constructor
//
- public Iterator (IMethodData m_container, TypeContainer
container,
+ public Iterator (IMethodData m_container, TypeContainer
container, GenericMethod generic,
InternalParameters parameters, int modifiers)
- : base (container.NamespaceEntry, container,
MakeProxyName (m_container.MethodName.Name),
+ : base (container.NamespaceEntry, container,
+ MakeProxyName (m_container.MethodName.Name,
generic, m_container.Location),
(modifiers & Modifiers.UNSAFE) |
Modifiers.PRIVATE, null, m_container.Location)
{
this.orig_method = m_container;
+ this.generic_method = generic;
this.container = container;
- this.parameters = parameters;
+ this.original_parameters = parameters;
this.original_block = orig_method.Block;
this.block = new ToplevelBlock (orig_method.Block,
parameters.Parameters, orig_method.Location);
+ if (generic != null) {
+ ArrayList constraints = new ArrayList ();
+ foreach (TypeParameter tparam in
generic.TypeParameters)
+ constraints.Add (tparam.Constraints);
+
+ SetParameterInfo (constraints);
+ }
+
IsStatic = (modifiers & Modifiers.STATIC) != 0;
}
@@ -367,7 +387,7 @@
public bool DefineIterator ()
{
- ec = new EmitContext (this, Mono.CSharp.Location.Null,
null, null, ModFlags);
+ ec = new EmitContext (this, Location, null, null,
ModFlags);
ec.CurrentAnonymousMethod = move_next_method;
ec.InIterator = true;
@@ -378,8 +398,8 @@
return false;
}
- for (int i = 0; i < parameters.Count; i++){
- Parameter.Modifier mod =
parameters.ParameterModifier (i);
+ for (int i = 0; i < original_parameters.Count; i++){
+ Parameter.Modifier mod =
original_parameters.ParameterModifier (i);
if ((mod & (Parameter.Modifier.REF |
Parameter.Modifier.OUT)) != 0){
Report.Error (
1623, Location,
@@ -392,7 +412,7 @@
return false;
}
- if (parameters.ParameterType (i).IsPointer) {
+ if (original_parameters.ParameterType
(i).IsPointer) {
Report.Error (1637, Location,
"Iterators cannot have unsafe parameters or yield types");
return false;
}
@@ -403,37 +423,8 @@
else
this_type = container.TypeBuilder;
- generic_args = new TypeArguments (Location);
- generic_args.Add (new TypeExpression (iterator_type,
Location));
-
- ArrayList list = new ArrayList ();
- if (is_enumerable) {
- enumerable_type = new TypeExpression (
- TypeManager.ienumerable_type, Location);
- list.Add (enumerable_type);
-
- generic_enumerable_type = new ConstructedType (
- TypeManager.generic_ienumerable_type,
- generic_args, Location);
- list.Add (generic_enumerable_type);
- }
-
- enumerator_type = new TypeExpression (
- TypeManager.ienumerator_type, Location);
- list.Add (enumerator_type);
-
- list.Add (new TypeExpression
(TypeManager.idisposable_type, Location));
-
- generic_enumerator_type = new ConstructedType (
- TypeManager.generic_ienumerator_type,
- generic_args, Location);
- list.Add (generic_enumerator_type);
-
- iterator_type_expr = new TypeExpression (iterator_type,
Location);
-
container.AddIterator (this);
- Bases = list;
orig_method.Block = block;
return true;
}
@@ -477,6 +468,7 @@
ec.InIterator = true;
ec.CurrentAnonymousMethod = move_next_method;
ec.capture_context = cc;
+
ec.TypeContainer = ec.TypeContainer.Parent;
if (ec.TypeContainer.CurrentType != null)
@@ -504,6 +496,95 @@
return true;
}
+ TypeExpr InflateType (Type it)
+ {
+ if (generic_method == null)
+ return new TypeExpression (it, Location);
+
+ if (it.IsGenericParameter && (it.DeclaringMethod !=
null)) {
+ int pos = it.GenericParameterPosition;
+ it = CurrentTypeParameters [pos].Type;
+ } else if (it.IsGenericInstance) {
+ Type[] args = it.GetGenericArguments ();
+
+ TypeArguments inflated = new TypeArguments
(Location);
+ foreach (Type t in args)
+ inflated.Add (InflateType (t));
+
+ return new ConstructedType (it, inflated,
Location);
+ } else if (it.IsArray) {
+ TypeExpr et_expr = InflateType
(it.GetElementType ());
+ int rank = it.GetArrayRank ();
+
+ Type et = et_expr.ResolveAsTypeTerminal
(ec).Type;
+ it = et.MakeArrayType (rank);
+ }
+
+ return new TypeExpression (it, Location);
+ }
+
+ Parameter InflateParameter (Parameter param)
+ {
+ TypeExpr te = InflateType (param.ParameterType);
+ return new Parameter (
+ te, param.Name, param.ModFlags,
param.OptAttributes, param.Location);
+ }
+
+ InternalParameters InflateParameters (Parameters parameters,
EmitContext ec)
+ {
+ Parameter[] fixed_params = null;
+ if (parameters.FixedParameters != null) {
+ fixed_params = new Parameter
[parameters.FixedParameters.Length];
+ for (int i = 0; i < fixed_params.Length; i++)
+ fixed_params [i] = InflateParameter
(parameters.FixedParameters [i]);
+ }
+
+ Parameters new_params;
+ if (parameters.ArrayParameter != null) {
+ Parameter array_param = InflateParameter
(parameters.ArrayParameter);
+ new_params = new Parameters (fixed_params,
array_param);
+ } else
+ new_params = new Parameters (fixed_params,
parameters.HasArglist);
+
+ Type [] types = new_params.GetParameterInfo (ec);
+ return new InternalParameters (types, new_params);
+ }
+
+ protected override TypeExpr [] GetClassBases (out TypeExpr
base_class)
+ {
+ iterator_type_expr = InflateType
(original_iterator_type);
+
+ generic_args = new TypeArguments (Location);
+ generic_args.Add (iterator_type_expr);
+
+ ArrayList list = new ArrayList ();
+ if (is_enumerable) {
+ enumerable_type = new TypeExpression (
+ TypeManager.ienumerable_type, Location);
+ list.Add (enumerable_type);
+
+ generic_enumerable_type = new ConstructedType (
+ TypeManager.generic_ienumerable_type,
+ generic_args, Location);
+ list.Add (generic_enumerable_type);
+ }
+
+ enumerator_type = new TypeExpression (
+ TypeManager.ienumerator_type, Location);
+ list.Add (enumerator_type);
+
+ list.Add (new TypeExpression
(TypeManager.idisposable_type, Location));
+
+ generic_enumerator_type = new ConstructedType (
+ TypeManager.generic_ienumerator_type,
+ generic_args, Location);
+ list.Add (generic_enumerator_type);
+
+ Bases = list;
+
+ return base.GetClassBases (out base_class);
+ }
+
//
// Returns the new block for the method, or null on failure
//
@@ -514,6 +595,8 @@
else
current_type = new TypeExpression (TypeBuilder,
Location);
+ parameters = InflateParameters
(original_parameters.Parameters, ec);
+
Define_Fields ();
Define_Current (false);
Define_Current (true);
@@ -521,10 +604,10 @@
Define_Reset ();
Define_Dispose ();
+ Define_Constructor ();
+
Create_Block ();
- Define_Constructor ();
-
if (is_enumerable) {
Define_GetEnumerator (false);
Define_GetEnumerator (true);
@@ -558,17 +641,31 @@
args.Add (new Argument (new BoolLiteral (false)));
for (int i = 0; i < parameters.Count; i++) {
- Type t = parameters.ParameterType (i);
+ Type t = original_parameters.ParameterType (i);
+ Type inflated = parameters.ParameterType (i);
string name = parameters.ParameterName (i);
args.Add (new Argument (
new SimpleParameterReference (t, first
+ i, Location)));
- cc.AddParameterToContext (move_next_method,
name, t, first + i);
+ cc.AddParameterToContext (move_next_method,
name, inflated, first + i);
}
- Expression new_expr = new New (current_type, args,
Location);
+ TypeExpr proxy_type;
+ if (generic_method != null) {
+ TypeArguments new_args = new TypeArguments
(Location);
+ if (Parent.IsGeneric) {
+ foreach (TypeParameter tparam in
Parent.TypeParameters)
+ new_args.Add (new
TypeParameterExpr (tparam, Location));
+ }
+ foreach (TypeParameter tparam in
generic_method.TypeParameters)
+ new_args.Add (new TypeParameterExpr
(tparam, Location));
+ ConstructedType ct = new ConstructedType
(CurrentType, new_args, Location);
+ proxy_type = ct.ResolveAsTypeTerminal (ec);
+ } else
+ proxy_type = current_type;
+ Expression new_expr = new New (proxy_type, args,
Location);
block.AddStatement (new NoCheckReturn (new_expr,
Location));
}
@@ -607,11 +704,10 @@
Parameter[] fixed_params = new Parameter [list.Count];
list.CopyTo (fixed_params);
- ctor_params = new Parameters (
- fixed_params,
parameters.Parameters.ArrayParameter);
+ ctor_params = new Parameters (fixed_params,
parameters.Parameters.ArrayParameter);
ctor = new Constructor (
- this, Name, Modifiers.PUBLIC, ctor_params,
+ this, MemberName.Name, Modifiers.PUBLIC,
ctor_params,
new ConstructorBaseInitializer (null, Location),
Location);
AddConstructor (ctor);
@@ -1094,7 +1190,7 @@
}
public Type IteratorType {
- get { return iterator_type; }
+ get { return iterator_type_expr.Type; }
}
//
@@ -1133,12 +1229,12 @@
Type ret = orig_method.ReturnType;
if (ret == TypeManager.ienumerable_type) {
- iterator_type = TypeManager.object_type;
+ original_iterator_type =
TypeManager.object_type;
is_enumerable = true;
return true;
}
if (ret == TypeManager.ienumerator_type) {
- iterator_type = TypeManager.object_type;
+ original_iterator_type =
TypeManager.object_type;
is_enumerable = false;
return true;
}
@@ -1152,11 +1248,11 @@
Type gt = ret.GetGenericTypeDefinition ();
if (gt == TypeManager.generic_ienumerable_type) {
- iterator_type = args [0];
+ original_iterator_type = args [0];
is_enumerable = true;
return true;
} else if (gt == TypeManager.generic_ienumerator_type) {
- iterator_type = args [0];
+ original_iterator_type = args [0];
is_enumerable = false;
return true;
}
Modified: trunk/mcs/gmcs/statement.cs
===================================================================
--- trunk/mcs/gmcs/statement.cs 2005-08-03 15:45:25 UTC (rev 47968)
+++ trunk/mcs/gmcs/statement.cs 2005-08-03 15:50:23 UTC (rev 47969)
@@ -2114,8 +2114,11 @@
//
// The parameters for the block.
//
- public readonly Parameters Parameters;
-
+ Parameters parameters;
+ public Parameters Parameters {
+ get { return parameters; }
+ }
+
public void RegisterCaptureContext (CaptureContext cc)
{
if (capture_contexts == null)
@@ -2175,7 +2178,7 @@
public ToplevelBlock (ToplevelBlock container, Flags flags,
Parameters parameters, Location start) :
base (null, flags | Flags.IsToplevel, start,
Location.Null)
{
- Parameters = parameters == null ?
Parameters.EmptyReadOnlyParameters : parameters;
+ this.parameters = parameters == null ?
Parameters.EmptyReadOnlyParameters : parameters;
this.container = container;
if (container != null)
@@ -2270,6 +2273,9 @@
if (top_level_branching != null)
return true;
+ if (ip != null)
+ parameters = ip.Parameters;
+
ResolveMeta (this, ec, ip);
top_level_branching = ec.StartFlowBranching (this);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches