public static AnonymousTypeClass Create (CompilerContext ctx, TypeContainer parent, IList<AnonymousTypeParameter> parameters, Location loc)
{
string name = ClassNamePrefix + types_counter++;
ParametersCompiled all_parameters;
TypeParameterName[] t_params;
SimpleName[] t_args;
if (parameters.Count == 0) {
all_parameters = ParametersCompiled.EmptyReadOnlyParameters;
t_params = new TypeParameterName[0];
t_args = null;
} else {
t_args = new SimpleName[parameters.Count];
t_params = new TypeParameterName[parameters.Count];
Parameter[] ctor_params = new Parameter[parameters.Count];
for (int i = 0; i < parameters.Count; ++i) {
AnonymousTypeParameter p = parameters[i];
t_args[i] = new SimpleName ("<" + p.Name + ">__T", p.Location);
t_params[i] = new TypeParameterName (t_args[i].Name, null, p.Location);
ctor_params[i] = new GeneratedParameter (t_args[i], p);
}
all_parameters = new ParametersCompiled (ctor_params);
}
//
// Create generic anonymous type host with generic arguments
// named upon properties names
//
AnonymousTypeClass a_type = new AnonymousTypeClass (parent.NamespaceEntry.SlaveDeclSpace,
new MemberName (name, new TypeArguments (t_params), loc), parameters, loc);
if (parameters.Count > 0)
a_type.SetParameterInfo (null);
Constructor c = new Constructor (a_type, name, Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN,
null, all_parameters, null, loc);
c.Block = new ToplevelBlock (ctx, c.ParameterInfo, loc);
//
// Create fields and contructor body with field initialization
//
bool error = false;
for (int i = 0; i < parameters.Count; ++i) {
AnonymousTypeParameter p = parameters [i];
Field f = new Field (a_type, t_args [i], Modifiers.PRIVATE | Modifiers.READONLY,
new MemberName ("<" + p.Name + ">", p.Location), null);
if (!a_type.AddField (f)) {
error = true;
continue;
}
c.Block.AddStatement (new StatementExpression (
new SimpleAssign (new MemberAccess (new This (p.Location), f.Name),
c.Block.GetParameterReference (i, p.Location))));
ToplevelBlock get_block = new ToplevelBlock (ctx, p.Location);
get_block.AddStatement (new Return (
new MemberAccess (new This (p.Location), f.Name), p.Location));
Property prop = new Property (a_type, t_args [i], Modifiers.PUBLIC,
new MemberName (p.Name, p.Location), null);
prop.Get = new Property.GetMethod (prop, 0, null, p.Location);
prop.Get.Block = get_block;
a_type.AddProperty (prop);
}
if (error)
return null;
a_type.AddConstructor (c);
return a_type;
}