/// <remarks>
/// 7.5.2: Simple Names.
///
/// Local Variables and Parameters are handled at
/// parse time, so they never occur as SimpleNames.
///
/// The `intermediate' flag is used by MemberAccess only
/// and it is used to inform us that it is ok for us to
/// avoid the static check, because MemberAccess might end
/// up resolving the Name as a Type name and the access as
/// a static type access.
///
/// ie: Type Type; .... { Type.GetType (""); }
///
/// Type is both an instance variable and a Type; Type.GetType
/// is the static method not an instance method of type.
/// </remarks>
Expression DoSimpleNameResolve(ResolveContext ec, Expression right_side, bool intermediate)
{
Expression e = null;
//
// Stage 1: Performed by the parser (binding to locals or parameters).
//
Block current_block = ec.CurrentBlock;
if (current_block != null){
LocalInfo vi = current_block.GetLocalInfo (Name);
if (vi != null){
e = new LocalVariableReference (ec.CurrentBlock, Name, loc);
if (right_side != null) {
e = e.ResolveLValue (ec, right_side);
} else {
if (intermediate) {
using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
e = e.Resolve (ec, ResolveFlags.VariableOrValue);
}
} else {
e = e.Resolve (ec, ResolveFlags.VariableOrValue);
}
}
if (HasTypeArguments && e != null)
e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
return e;
}
e = current_block.Toplevel.GetParameterReference (Name, loc);
if (e != null) {
if (right_side != null)
e = e.ResolveLValue (ec, right_side);
else
e = e.Resolve (ec);
if (HasTypeArguments && e != null)
e.Error_TypeArgumentsCannotBeUsed (ec.Report, loc, null, 0);
return e;
}
}
//
// Stage 2: Lookup members
//
int arity = HasTypeArguments ? Arity : -1;
// TypeSpec almost_matched_type = null;
// IList<MemberSpec> almost_matched = null;
for (TypeSpec lookup_ds = ec.CurrentType; lookup_ds != null; lookup_ds = lookup_ds.DeclaringType) {
e = MemberLookup (ec.Compiler, ec.CurrentType, lookup_ds, Name, arity, BindingRestriction.NoOverrides, loc);
if (e != null) {
PropertyExpr pe = e as PropertyExpr;
if (pe != null) {
// since TypeManager.MemberLookup doesn't know if we're doing a lvalue access or not,
// it doesn't know which accessor to check permissions against
if (pe.PropertyInfo.Kind == MemberKind.Property && pe.IsAccessibleFrom (ec.CurrentType, right_side != null))
break;
} else if (e is EventExpr) {
if (((EventExpr) e).IsAccessibleFrom (ec.CurrentType))
break;
} else if (HasTypeArguments && e is TypeExpression) {
e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
break;
} else {
break;
}
e = null;
}
/*
if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = lookup_ds;
almost_matched = new List<MemberSpec>(almost_matched_members);
}
*/
}
if (e == null) {
/*
if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = ec.CurrentType;
//.........这里部分代码省略.........
开发者ID:speier,项目名称:shake,代码行数:101,代码来源:ecore.cs
示例2: CreateSiteType
TypeExpr CreateSiteType(EmitContext ec, Arguments arguments, int dyn_args_count, bool is_statement)
{
int default_args = is_statement ? 1 : 2;
var module = ec.Module;
bool has_ref_out_argument = false;
var targs = new TypeExpression[dyn_args_count + default_args];
targs [0] = new TypeExpression (module.PredefinedTypes.CallSite.TypeSpec, loc);
for (int i = 0; i < dyn_args_count; ++i) {
Argument a = arguments [i];
if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
has_ref_out_argument = true;
var t = a.Type;
// Convert any internal type like dynamic or null to object
if (t.Kind == MemberKind.InternalCompilerType)
t = TypeManager.object_type;
targs [i + 1] = new TypeExpression (t, loc);
}
TypeExpr del_type = null;
if (!has_ref_out_argument) {
string d_name = is_statement ? "Action" : "Func";
TypeExpr te = null;
Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true);
if (type_ns != null) {
te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, true, Location.Null);
}
if (te != null) {
if (!is_statement)
targs [targs.Length - 1] = new TypeExpression (type, loc);
del_type = new GenericTypeExpr (te.Type, new TypeArguments (targs), loc);
}
}
//
// Create custom delegate when no appropriate predefined one is found
//
if (del_type == null) {
TypeSpec rt = is_statement ? TypeManager.void_type : type;
Parameter[] p = new Parameter [dyn_args_count + 1];
p[0] = new Parameter (targs [0], "p0", Parameter.Modifier.NONE, null, loc);
var site = ec.CreateDynamicSite ();
int index = site.Types == null ? 0 : site.Types.Count;
if (site.Mutator != null)
rt = site.Mutator.Mutate (rt);
for (int i = 1; i < dyn_args_count + 1; ++i) {
var t = targs[i];
if (site.Mutator != null)
t.Type = site.Mutator.Mutate (t.Type);
p[i] = new Parameter (t, "p" + i.ToString ("X"), arguments[i - 1].Modifier, null, loc);
}
Delegate d = new Delegate (site.NamespaceEntry, site, new TypeExpression (rt, loc),
Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
new MemberName ("Container" + index.ToString ("X")),
new ParametersCompiled (p), null);
d.CreateType ();
d.DefineType ();
d.Define ();
d.Emit ();
var inflated = site.AddDelegate (d);
del_type = new TypeExpression (inflated, loc);
}
TypeExpr site_type = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type), loc);
return site_type;
}
/// <remarks>
/// 7.5.2: Simple Names.
///
/// Local Variables and Parameters are handled at
/// parse time, so they never occur as SimpleNames.
///
/// The `intermediate' flag is used by MemberAccess only
/// and it is used to inform us that it is ok for us to
/// avoid the static check, because MemberAccess might end
/// up resolving the Name as a Type name and the access as
/// a static type access.
///
/// ie: Type Type; .... { Type.GetType (""); }
///
/// Type is both an instance variable and a Type; Type.GetType
/// is the static method not an instance method of type.
/// </remarks>
Expression DoSimpleNameResolve (EmitContext ec, Expression right_side, bool intermediate)
{
Expression e = null;
//
// Stage 1: Performed by the parser (binding to locals or parameters).
//
Block current_block = ec.CurrentBlock;
if (current_block != null){
LocalInfo vi = current_block.GetLocalInfo (Name);
if (vi != null){
LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
if (right_side != null) {
return var.ResolveLValue (ec, right_side, loc);
} else {
ResolveFlags rf = ResolveFlags.VariableOrValue;
if (intermediate)
rf |= ResolveFlags.DisableFlowAnalysis;
return var.Resolve (ec, rf);
}
}
Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
if (expr != null) {
if (right_side != null)
return expr.ResolveLValue (ec, right_side, loc);
return expr.Resolve (ec);
}
}
//
// Stage 2: Lookup members
//
Type almost_matched_type = null;
ArrayList almost_matched = null;
for (DeclSpace lookup_ds = ec.DeclContainer; lookup_ds != null; lookup_ds = lookup_ds.Parent) {
// either RootDeclSpace or GenericMethod
if (lookup_ds.TypeBuilder == null)
continue;
e = MemberLookup (ec.ContainerType, lookup_ds.TypeBuilder, Name, loc);
if (e != null) {
PropertyExpr pe = e as PropertyExpr;
if (pe != null) {
AParametersCollection param = TypeManager.GetParameterData (pe.PropertyInfo);
// since TypeManager.MemberLookup doesn't know if we're doing a lvalue access or not,
// it doesn't know which accessor to check permissions against
if (param.IsEmpty && pe.IsAccessibleFrom (ec.ContainerType, right_side != null))
break;
} else if (e is EventExpr) {
if (((EventExpr) e).IsAccessibleFrom (ec.ContainerType))
break;
} else if (targs != null && e is TypeExpression) {
e = new GenericTypeExpr (e.Type, targs, loc).ResolveAsTypeStep (ec, false);
break;
} else {
break;
}
e = null;
}
if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = lookup_ds.TypeBuilder;
almost_matched = (ArrayList) almost_matched_members.Clone ();
}
}
if (e == null) {
if (almost_matched == null && almost_matched_members.Count > 0) {
almost_matched_type = ec.ContainerType;
almost_matched = (ArrayList) almost_matched_members.Clone ();
}
e = ResolveAsTypeStep (ec, true);
}
if (e == null) {
if (current_block != null) {
IKnownVariable ikv = current_block.Explicit.GetKnownVariable (Name);
if (ikv != null) {
LocalInfo li = ikv as LocalInfo;
//.........这里部分代码省略.........
protected override bool DoDefineMembers ()
{
if (!base.DoDefineMembers ())
return false;
Location loc = Location;
var equals_parameters = ParametersCompiled.CreateFullyResolved (
new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, loc), "obj", 0, null, loc), Compiler.BuiltinTypes.Object);
Method equals = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Bool, loc),
Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("Equals", loc),
equals_parameters, null);
equals_parameters[0].Resolve (equals, 0);
Method tostring = new Method (this, new TypeExpression (Compiler.BuiltinTypes.String, loc),
Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("ToString", loc),
Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);
ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.ParameterInfo, loc);
TypeExpr current_type;
if (CurrentTypeParameters != null) {
var targs = new TypeArguments ();
for (int i = 0; i < CurrentTypeParameters.Count; ++i) {
targs.Add (new TypeParameterExpr (CurrentTypeParameters[i], Location));
}
current_type = new GenericTypeExpr (Definition, targs, loc);
} else {
current_type = new TypeExpression (Definition, loc);
}
var li_other = LocalVariable.CreateCompilerGenerated (CurrentType, equals_block, loc);
equals_block.AddStatement (new BlockVariableDeclaration (new TypeExpression (li_other.Type, loc), li_other));
var other_variable = new LocalVariableReference (li_other, loc);
MemberAccess system_collections_generic = new MemberAccess (new MemberAccess (
new QualifiedAliasMember ("global", "System", loc), "Collections", loc), "Generic", loc);
Expression rs_equals = null;
Expression string_concat = new StringConstant (Compiler.BuiltinTypes, "{", loc);
Expression rs_hashcode = new IntConstant (Compiler.BuiltinTypes, -2128831035, loc);
for (int i = 0; i < parameters.Count; ++i) {
var p = parameters [i];
var f = (Field) Members [i * 2];
MemberAccess equality_comparer = new MemberAccess (new MemberAccess (
system_collections_generic, "EqualityComparer",
new TypeArguments (new SimpleName (CurrentTypeParameters [i].Name, loc)), loc),
"Default", loc);
Arguments arguments_equal = new Arguments (2);
arguments_equal.Add (new Argument (new MemberAccess (new This (f.Location), f.Name)));
arguments_equal.Add (new Argument (new MemberAccess (other_variable, f.Name)));
Expression field_equal = new Invocation (new MemberAccess (equality_comparer,
"Equals", loc), arguments_equal);
Arguments arguments_hashcode = new Arguments (1);
arguments_hashcode.Add (new Argument (new MemberAccess (new This (f.Location), f.Name)));
Expression field_hashcode = new Invocation (new MemberAccess (equality_comparer,
"GetHashCode", loc), arguments_hashcode);
IntConstant FNV_prime = new IntConstant (Compiler.BuiltinTypes, 16777619, loc);
rs_hashcode = new Binary (Binary.Operator.Multiply,
new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode),
FNV_prime);
Expression field_to_string = new Conditional (new BooleanExpression (new Binary (Binary.Operator.Inequality,
new MemberAccess (new This (f.Location), f.Name), new NullLiteral (loc))),
new Invocation (new MemberAccess (
new MemberAccess (new This (f.Location), f.Name), "ToString"), null),
new StringConstant (Compiler.BuiltinTypes, string.Empty, loc), loc);
if (rs_equals == null) {
rs_equals = field_equal;
string_concat = new Binary (Binary.Operator.Addition,
string_concat,
new Binary (Binary.Operator.Addition,
new StringConstant (Compiler.BuiltinTypes, " " + p.Name + " = ", loc),
field_to_string));
continue;
}
//
// Implementation of ToString () body using string concatenation
//
string_concat = new Binary (Binary.Operator.Addition,
new Binary (Binary.Operator.Addition,
string_concat,
new StringConstant (Compiler.BuiltinTypes, ", " + p.Name + " = ", loc)),
field_to_string);
rs_equals = new Binary (Binary.Operator.LogicalAnd, rs_equals, field_equal);
}
string_concat = new Binary (Binary.Operator.Addition,
string_concat,
//.........这里部分代码省略.........
开发者ID:rabink,项目名称:mono,代码行数:101,代码来源:anonymous.cs
示例9: ResolveNamespaceOrType
public FullNamedExpression ResolveNamespaceOrType (IMemberContext rc, bool silent)
{
FullNamedExpression expr_resolved = expr.ResolveAsTypeStep (rc, silent);
if (expr_resolved == null)
return null;
string LookupIdentifier = MemberName.MakeName (Name, targs);
Namespace ns = expr_resolved as Namespace;
if (ns != null) {
FullNamedExpression retval = ns.Lookup (rc.Compiler, LookupIdentifier, loc);
if (retval == null && !silent)
ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, rc.Compiler.Report);
else if (targs != null)
retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
return retval;
}
TypeExpr tnew_expr = expr_resolved.ResolveAsTypeTerminal (rc, false);
if (tnew_expr == null)
return null;
Type expr_type = tnew_expr.Type;
if (TypeManager.IsGenericParameter (expr_type)) {
rc.Compiler.Report.Error (704, loc, "A nested type cannot be specified through a type parameter `{0}'",
tnew_expr.GetSignatureForError ());
return null;
}
Expression member_lookup = MemberLookup (rc.Compiler,
rc.CurrentType, expr_type, expr_type, LookupIdentifier,
MemberTypes.NestedType, BindingFlags.Public | BindingFlags.NonPublic, loc);
if (member_lookup == null) {
if (silent)
return null;
Error_IdentifierNotFound (rc, expr_resolved, LookupIdentifier);
return null;
}
TypeExpr texpr = member_lookup.ResolveAsTypeTerminal (rc, false);
if (texpr == null)
return null;
TypeArguments the_args = targs;
Type declaring_type = texpr.Type.DeclaringType;
if (TypeManager.HasGenericArguments (declaring_type) && !TypeManager.IsGenericTypeDefinition (expr_type)) {
while (!TypeManager.IsEqual (TypeManager.DropGenericTypeArguments (expr_type), declaring_type)) {
expr_type = expr_type.BaseType;
}
TypeArguments new_args = new TypeArguments ();
foreach (Type decl in TypeManager.GetTypeArguments (expr_type))
new_args.Add (new TypeExpression (TypeManager.TypeToCoreType (decl), loc));
if (targs != null)
new_args.Add (targs);
the_args = new_args;
}
if (the_args != null) {
GenericTypeExpr ctype = new GenericTypeExpr (texpr.Type, the_args, loc);
return ctype.ResolveAsTypeStep (rc, false);
}
return texpr;
}
public override Expression DoResolve (EmitContext ec)
{
AnonymousTypeClass anonymous_type;
if (!ec.IsAnonymousMethodAllowed) {
Report.Error (836, loc, "Anonymous types cannot be used in this expression");
return null;
}
if (parameters == null) {
anonymous_type = CreateAnonymousType (EmptyParameters);
return new New (new TypeExpression (anonymous_type.TypeBuilder, loc),
null, loc).Resolve (ec);
}
bool error = false;
ArrayList arguments = new ArrayList (parameters.Count);
TypeExpression [] t_args = new TypeExpression [parameters.Count];
for (int i = 0; i < parameters.Count; ++i) {
Expression e = ((AnonymousTypeParameter) parameters [i]).Resolve (ec);
if (e == null) {
error = true;
continue;
}
arguments.Add (new Argument (e));
t_args [i] = new TypeExpression (e.Type, e.Location);
}
if (error)
return null;
anonymous_type = CreateAnonymousType (parameters);
if (anonymous_type == null)
return null;
GenericTypeExpr te = new GenericTypeExpr (anonymous_type.TypeBuilder,
new TypeArguments (t_args), loc);
return new New (te, arguments, loc).Resolve (ec);
}
protected bool CheckConstraint (IResolveContext ec, Type ptype, Expression expr,
Type ctype)
{
if (TypeManager.HasGenericArguments (ctype)) {
Type[] types = TypeManager.GetTypeArguments (ctype);
TypeArguments new_args = new TypeArguments ();
for (int i = 0; i < types.Length; i++) {
Type t = types [i];
if (t.IsGenericParameter) {
int pos = t.GenericParameterPosition;
t = atypes [pos];
}
new_args.Add (new TypeExpression (t, loc));
}
TypeExpr ct = new GenericTypeExpr (ctype, new_args, loc);
if (ct.ResolveAsTypeStep (ec, false) == null)
return false;
ctype = ct.Type;
} else if (ctype.IsGenericParameter) {
int pos = ctype.GenericParameterPosition;
if (ctype.DeclaringMethod == null) {
// FIXME: Implement
return true;
} else {
ctype = atypes [pos];
}
}
if (Convert.ImplicitStandardConversionExists (expr, ctype))
return true;
Report_SymbolRelatedToPreviousError ();
Report.SymbolRelatedToPreviousError (expr.Type);
if (TypeManager.IsNullableType (expr.Type) && ctype.IsInterface) {
Report.Error (313, loc,
"The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. " +
"The nullable type `{0}' never satisfies interface constraint of type `{3}'",
TypeManager.CSharpName (expr.Type), TypeManager.CSharpName (ptype),
GetSignatureForError (), TypeManager.CSharpName (ctype));
} else {
Report.Error (309, loc,
"The type `{0}' must be convertible to `{1}' in order to " +
"use it as parameter `{2}' in the generic type or method `{3}'",
TypeManager.CSharpName (expr.Type), TypeManager.CSharpName (ctype),
TypeManager.CSharpName (ptype), GetSignatureForError ());
}
return false;
}
protected void EmitCall (EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
{
//
// This method generates all internal infrastructure for a dynamic call. The
// reason why it's quite complicated is the mixture of dynamic and anonymous
// methods. Dynamic itself requires a temporary class (ContainerX) and anonymous
// methods can generate temporary storey as well (AnonStorey). Handling MVAR
// type parameters rewrite is non-trivial in such case as there are various
// combinations possible therefore the mutator is not straightforward. Secondly
// we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit
// correct Site field type and its access from EmitContext.
//
int dyn_args_count = arguments == null ? 0 : arguments.Count;
int default_args = isStatement ? 1 : 2;
var module = ec.Module;
bool has_ref_out_argument = false;
var targs = new TypeExpression[dyn_args_count + default_args];
targs[0] = new TypeExpression (module.PredefinedTypes.CallSite.TypeSpec, loc);
TypeExpression[] targs_for_instance = null;
TypeParameterMutator mutator;
var site_container = ec.CreateDynamicSite ();
if (context_mvars != null) {
TypeParameters tparam;
TypeContainer sc = site_container;
do {
tparam = sc.CurrentTypeParameters;
sc = sc.Parent;
} while (tparam == null);
mutator = new TypeParameterMutator (context_mvars, tparam);
if (!ec.IsAnonymousStoreyMutateRequired) {
targs_for_instance = new TypeExpression[targs.Length];
targs_for_instance[0] = targs[0];
}
} else {
mutator = null;
}
for (int i = 0; i < dyn_args_count; ++i) {
Argument a = arguments[i];
if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
has_ref_out_argument = true;
var t = a.Type;
// Convert any internal type like dynamic or null to object
if (t.Kind == MemberKind.InternalCompilerType)
t = ec.BuiltinTypes.Object;
if (targs_for_instance != null)
targs_for_instance[i + 1] = new TypeExpression (t, loc);
if (mutator != null)
t = t.Mutate (mutator);
targs[i + 1] = new TypeExpression (t, loc);
}
TypeExpr del_type = null;
TypeExpr del_type_instance_access = null;
if (!has_ref_out_argument) {
string d_name = isStatement ? "Action" : "Func";
TypeSpec te = null;
Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true);
if (type_ns != null) {
te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc);
}
if (te != null) {
if (!isStatement) {
var t = type;
if (t.Kind == MemberKind.InternalCompilerType)
t = ec.BuiltinTypes.Object;
if (targs_for_instance != null)
targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression (t, loc);
if (mutator != null)
t = t.Mutate (mutator);
targs[targs.Length - 1] = new TypeExpression (t, loc);
}
del_type = new GenericTypeExpr (te, new TypeArguments (targs), loc);
if (targs_for_instance != null)
del_type_instance_access = new GenericTypeExpr (te, new TypeArguments (targs_for_instance), loc);
else
del_type_instance_access = del_type;
}
}
//
// Create custom delegate when no appropriate predefined delegate has been found
//.........这里部分代码省略.........
开发者ID:caomw,项目名称:mono,代码行数:101,代码来源:dynamic.cs
示例14: DefineOverrides
void DefineOverrides ()
{
Location loc = Location;
Method equals = new Method (this, null, TypeManager.system_boolean_expr,
Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("Equals", loc),
Mono.CSharp.ParametersCompiled.CreateFullyResolved (new Parameter (null, "obj", 0, null, loc), TypeManager.object_type), null);
Method tostring = new Method (this, null, TypeManager.system_string_expr,
Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN, new MemberName ("ToString", loc),
Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);
ToplevelBlock equals_block = new ToplevelBlock (Compiler, equals.Parameters, loc);
TypeExpr current_type;
if (IsGeneric)
current_type = new GenericTypeExpr (this, loc);
else
current_type = new TypeExpression (TypeBuilder, loc);
equals_block.AddVariable (current_type, "other", loc);
LocalVariableReference other_variable = new LocalVariableReference (equals_block, "other", loc);
MemberAccess system_collections_generic = new MemberAccess (new MemberAccess (
new QualifiedAliasMember ("global", "System", loc), "Collections", loc), "Generic", loc);
Expression rs_equals = null;
Expression string_concat = new StringConstant ("{", loc);
Expression rs_hashcode = new IntConstant (-2128831035, loc);
for (int i = 0; i < parameters.Count; ++i) {
AnonymousTypeParameter p = (AnonymousTypeParameter) parameters [i];
Field f = (Field) Fields [i];
MemberAccess equality_comparer = new MemberAccess (new MemberAccess (
system_collections_generic, "EqualityComparer",
new TypeArguments (new SimpleName (TypeParameters [i].Name, loc)), loc),
"Default", loc);
Arguments arguments_equal = new Arguments (2);
arguments_equal.Add (new Argument (new MemberAccess (new This (f.Location), f.Name)));
arguments_equal.Add (new Argument (new MemberAccess (other_variable, f.Name)));
Expression field_equal = new Invocation (new MemberAccess (equality_comparer,
"Equals", loc), arguments_equal);
Arguments arguments_hashcode = new Arguments (1);
arguments_hashcode.Add (new Argument (new MemberAccess (new This (f.Location), f.Name)));
Expression field_hashcode = new Invocation (new MemberAccess (equality_comparer,
"GetHashCode", loc), arguments_hashcode);
IntConstant FNV_prime = new IntConstant (16777619, loc);
rs_hashcode = new Binary (Binary.Operator.Multiply,
new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode),
FNV_prime);
Expression field_to_string = new Conditional (new Binary (Binary.Operator.Inequality,
new MemberAccess (new This (f.Location), f.Name), new NullLiteral (loc)),
new Invocation (new MemberAccess (
new MemberAccess (new This (f.Location), f.Name), "ToString"), null),
new StringConstant (string.Empty, loc));
if (rs_equals == null) {
rs_equals = field_equal;
string_concat = new Binary (Binary.Operator.Addition,
string_concat,
new Binary (Binary.Operator.Addition,
new StringConstant (" " + p.Name + " = ", loc),
field_to_string));
continue;
}
//
// Implementation of ToString () body using string concatenation
//
string_concat = new Binary (Binary.Operator.Addition,
new Binary (Binary.Operator.Addition,
string_concat,
new StringConstant (", " + p.Name + " = ", loc)),
field_to_string);
rs_equals = new Binary (Binary.Operator.LogicalAnd, rs_equals, field_equal);
}
string_concat = new Binary (Binary.Operator.Addition,
string_concat,
new StringConstant (" }", loc));
//
// Equals (object obj) override
//
LocalVariableReference other_variable_assign = new LocalVariableReference (equals_block, "other", loc);
equals_block.AddStatement (new StatementExpression (
new SimpleAssign (other_variable_assign,
new As (equals_block.GetParameterReference ("obj", loc),
current_type, loc), loc)));
Expression equals_test = new Binary (Binary.Operator.Inequality, other_variable, new NullLiteral (loc));
if (rs_equals != null)
equals_test = new Binary (Binary.Operator.LogicalAnd, equals_test, rs_equals);
equals_block.AddStatement (new Return (equals_test, loc));
//.........这里部分代码省略.........
TypeExpr CreateSiteType(CompilerContext ctx, Arguments arguments, int dyn_args_count, bool is_statement)
{
int default_args = is_statement ? 1 : 2;
bool has_ref_out_argument = false;
FullNamedExpression[] targs = new FullNamedExpression[dyn_args_count + default_args];
targs [0] = new TypeExpression (TypeManager.call_site_type, loc);
for (int i = 0; i < dyn_args_count; ++i) {
TypeSpec arg_type;
Argument a = arguments [i];
if (a.Type == TypeManager.null_type)
arg_type = TypeManager.object_type;
else
arg_type = a.Type;
if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
has_ref_out_argument = true;
targs [i + 1] = new TypeExpression (arg_type, loc);
}
TypeExpr del_type = null;
if (!has_ref_out_argument) {
string d_name = is_statement ? "Action" : "Func";
TypeSpec t = TypeManager.CoreLookupType (ctx, "System", d_name, dyn_args_count + default_args, MemberKind.Delegate, false);
if (t != null) {
if (!is_statement)
targs [targs.Length - 1] = new TypeExpression (type, loc);
del_type = new GenericTypeExpr (t, new TypeArguments (targs), loc);
}
}
//
// Create custom delegate when no appropriate predefined one is found
//
if (del_type == null) {
TypeSpec rt = is_statement ? TypeManager.void_type : type;
Parameter[] p = new Parameter [dyn_args_count + 1];
p[0] = new Parameter (targs [0], "p0", Parameter.Modifier.NONE, null, loc);
for (int i = 1; i < dyn_args_count + 1; ++i)
p[i] = new Parameter (targs[i], "p" + i.ToString ("X"), arguments[i - 1].Modifier, null, loc);
TypeContainer parent = CreateSiteContainer ();
Delegate d = new Delegate (parent.NamespaceEntry, parent, new TypeExpression (rt, loc),
Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
new MemberName ("Container" + container_counter++.ToString ("X")),
new ParametersCompiled (ctx, p), null);
d.CreateType ();
d.DefineType ();
d.Define ();
d.Emit ();
parent.AddDelegate (d);
del_type = new TypeExpression (d.Definition, loc);
}
TypeExpr site_type = new GenericTypeExpr (TypeManager.generic_call_site_type, new TypeArguments (del_type), loc);
return site_type;
}
开发者ID:speier,项目名称:shake,代码行数:63,代码来源:dynamic.cs
示例16: EmitStoreyInstantiation
//
// Initializes all hoisted variables
//
public void EmitStoreyInstantiation (EmitContext ec)
{
// There can be only one instance variable for each storey type
if (Instance != null)
throw new InternalErrorException ();
SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);
//
// Create an instance of storey type
//
Expression storey_type_expr;
if (is_generic) {
//
// Use current method type parameter (MVAR) for top level storey only. All
// nested storeys use class type parameter (VAR)
//
TypeParameter[] tparams = ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.Storey != null ?
ec.CurrentAnonymousMethod.Storey.TypeParameters :
ec.CurrentTypeParameters;
TypeArguments targs = new TypeArguments ();
if (tparams.Length < CountTypeParameters) {
TypeParameter[] parent_tparams = ec.MemberContext.CurrentTypeDefinition.TypeParameters;
for (int i = 0; i < parent_tparams.Length; ++i)
targs.Add (new TypeParameterExpr (parent_tparams[i], Location));
}
for (int i = 0; i < tparams.Length; ++i)
targs.Add (new TypeParameterExpr (tparams[i], Location));
storey_type_expr = new GenericTypeExpr (TypeBuilder, targs, Location);
} else {
storey_type_expr = new TypeExpression (TypeBuilder, Location);
}
ResolveContext rc = new ResolveContext (this);
Expression e = new New (storey_type_expr, null, Location).Resolve (rc);
e.Emit (ec);
Instance = new LocalTemporary (storey_type_expr.Type);
Instance.Store (ec);
EmitHoistedFieldsInitialization (ec);
SymbolWriter.DefineScopeVariable (ID, Instance.Builder);
SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
}
请发表评论