示例#1
0
文件: ecore.cs 项目: speier/shake
        /// <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;
                    almost_matched = new List<MemberSpec> (almost_matched_members);
                }
            */
                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;
                        // Supress CS0219 warning
                        if (li != null)
                            li.Used = true;

                        Error_VariableIsUsedBeforeItIsDeclared (ec.Report, Name);
                        return null;
                    }
                }

                if (RootContext.EvalMode){
                    FieldInfo fi = Evaluator.LookupField (Name);
                    if (fi != null)
                        return new FieldExpr (Import.CreateField (fi, null), loc).Resolve (ec);
                }
            /*
                if (almost_matched != null)
                    almost_matched_members = almost_matched;
                if (almost_matched_type == null)
                    almost_matched_type = ec.CurrentType;
            */
                string type_name = ec.MemberContext.CurrentType == null ? null : ec.MemberContext.CurrentType.Name;
                return Error_MemberLookupFailed (ec, ec.CurrentType, null, ec.CurrentType, Name, arity,
                    type_name, MemberKind.All, BindingRestriction.AccessibleOnly);
            }

            if (e is MemberExpr) {
                MemberExpr me = (MemberExpr) e;

                Expression left;
                if (me.IsInstance) {
                    if (ec.IsStatic || ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.BaseInitializer | ResolveContext.Options.ConstantScope)) {
                        //
                        // Note that an MemberExpr can be both IsInstance and IsStatic.
                        // An unresolved MethodGroupExpr can contain both kinds of methods
                        // and each predicate is true if the MethodGroupExpr contains
                        // at least one of that kind of method.
                        //
            /*
                        if (!me.IsStatic &&
                            (!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) {
                            Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ());
                            return null;
                        }
            */
                        //
                        // Pass the buck to MemberAccess and Invocation.
                        //
                        left = EmptyExpression.Null;
                    } else {
                        left = ec.GetThis (loc);
                    }
                } else {
                    left = new TypeExpression (ec.CurrentType, loc);
                }

                me = me.ResolveMemberAccess (ec, left, loc, null);
                if (me == null)
                    return null;

                if (HasTypeArguments) {
                    if (!targs.Resolve (ec))
                        return null;

                    me.SetTypeArguments (ec, targs);
                }

                if (!me.IsStatic && (me.InstanceExpression != null && me.InstanceExpression != EmptyExpression.Null) &&
                    TypeManager.IsNestedFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
                    me.InstanceExpression.Type != me.DeclaringType &&
                    !TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
                    (!intermediate || !IdenticalNameAndTypeName (ec, e, loc))) {
                    ec.Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
                        TypeManager.CSharpName (me.DeclaringType), TypeManager.CSharpName (me.InstanceExpression.Type));
                    return null;
                }

                return (right_side != null)
                    ? me.DoResolveLValue (ec, right_side)
                    : me.Resolve (ec);
            }

            return e;
        }
示例#2
0
		/// <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;
						// Supress CS0219 warning
						if (li != null)
							li.Used = true;

						Error_VariableIsUsedBeforeItIsDeclared (Name);
						return null;
					}
				}

				if (RootContext.EvalMode){
					FieldInfo fi = Evaluator.LookupField (Name);
					if (fi != null)
						return new FieldExpr (fi, loc).Resolve (ec);
				}

				if (almost_matched != null)
					almost_matched_members = almost_matched;
				if (almost_matched_type == null)
					almost_matched_type = ec.ContainerType;
				return Error_MemberLookupFailed (ec.ContainerType, null, almost_matched_type, Name,
					ec.DeclContainer.Name, AllMemberTypes, AllBindingFlags);
			}

			if (e is MemberExpr) {
				MemberExpr me = (MemberExpr) e;

				Expression left;
				if (me.IsInstance) {
					if (ec.IsStatic || ec.IsInFieldInitializer) {
						//
						// Note that an MemberExpr can be both IsInstance and IsStatic.
						// An unresolved MethodGroupExpr can contain both kinds of methods
						// and each predicate is true if the MethodGroupExpr contains
						// at least one of that kind of method.
						//

						if (!me.IsStatic &&
						    (!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) {
							Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ());
							return null;
						}

						//
						// Pass the buck to MemberAccess and Invocation.
						//
						left = EmptyExpression.Null;
					} else {
						left = ec.GetThis (loc);
					}
				} else {
					left = new TypeExpression (ec.ContainerType, loc);
				}

				me = me.ResolveMemberAccess (ec, left, loc, null);
				if (me == null)
					return null;

				if (targs != null) {
					if (!targs.Resolve (ec))
						return null;

					me.SetTypeArguments (targs);
				}

				if (!me.IsStatic && (me.InstanceExpression != null) &&
				    TypeManager.IsNestedFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
				    me.InstanceExpression.Type != me.DeclaringType &&
				    !TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
				    (!intermediate || !IdenticalNameAndTypeName (ec, e, loc))) {
					Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'",
						TypeManager.CSharpName (me.DeclaringType), TypeManager.CSharpName (me.InstanceExpression.Type));
					return null;
				}

				return (right_side != null)
					? me.DoResolveLValue (ec, right_side)
					: me.DoResolve (ec);
			}

			return e;
		}
示例#3
0
文件: ecore.cs 项目: speier/shake
        public override FullNamedExpression ResolveAsTypeStep(IMemberContext ec, bool silent)
        {
            int errors = ec.Compiler.Report.Errors;
            FullNamedExpression fne = ec.LookupNamespaceOrType (Name, Arity, loc, /*ignore_cs0104=*/ false);

            if (fne != null) {
                if (HasTypeArguments && fne.Type != null && TypeManager.IsGenericType (fne.Type)) {
                    GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
                    return ct.ResolveAsTypeStep (ec, false);
                }

                return fne;
            }

            if (!HasTypeArguments && Name == "dynamic" &&
                RootContext.Version > LanguageVersion.V_3 &&
                RootContext.MetadataCompatibilityVersion > MetadataVersion.v2) {

                if (!PredefinedAttributes.Get.Dynamic.IsDefined) {
                    ec.Compiler.Report.Error (1980, Location,
                        "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core.dll assembly reference?",
                        PredefinedAttributes.Get.Dynamic.GetSignatureForError ());
                }

                return new DynamicTypeExpr (loc);
            }

            if (silent || errors != ec.Compiler.Report.Errors)
                return null;

            Error_TypeOrNamespaceNotFound (ec);
            return null;
        }
示例#4
0
		protected virtual bool DoResolveType ()
		{
			if (!IsGeneric)
				return true;

			if (PartialContainer != this)
				throw new InternalErrorException ();

			TypeExpr current_type = null;
			if (CurrentTypeParameters != null) {
				foreach (TypeParameter type_param in CurrentTypeParameters) {
					if (!type_param.Resolve (this)) {
						error = true;
						return false;
					}
				}

				if (partial_parts != null) {
					foreach (TypeContainer part in partial_parts)
						UpdateTypeParameterConstraints (part);
				}
			}

			for (int i = 0; i < TypeParameters.Length; ++i) {
				//
				// FIXME: Same should be done for delegates
				// TODO: Quite ugly way how to propagate constraints to
				// nested types
				//
				if (nested_gen_params != null && i < nested_gen_params.Length) {
					TypeParameters [i].SetConstraints (nested_gen_params [i]);
				} else {
					if (!TypeParameters [i].DefineType (this)) {
						error = true;
						return false;
					}
				}
			}

			// TODO: Very strange, why not simple make generic type from
			// current type parameters
			current_type = new GenericTypeExpr (this, Location);
			current_type = current_type.ResolveAsTypeTerminal (this, false);
			if (current_type == null) {
				error = true;
				return false;
			}

			currentType = current_type.Type;
			return true;
		}
示例#5
0
		public override FullNamedExpression ResolveAsTypeStep (IResolveContext ec, bool silent)
		{
			FullNamedExpression fne = ec.GenericDeclContainer.LookupGeneric (Name, loc);
			if (fne != null)
				return fne.ResolveAsTypeStep (ec, silent);

			int errors = Report.Errors;
			fne = ec.DeclContainer.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);

			if (fne != null) {
				if (fne.Type == null)
					return fne;

				FullNamedExpression nested = ResolveNested (ec, fne.Type);
				if (nested != null)
					return nested.ResolveAsTypeStep (ec, false);

				if (targs != null) {
					GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
					return ct.ResolveAsTypeStep (ec, false);
				}

				return fne;
			}

			if (silent || errors != Report.Errors)
				return null;

			Error_TypeOrNamespaceNotFound (ec);
			return null;
		}
示例#6
0
文件: dynamic.cs 项目: caomw/mono
		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
			//
			Delegate d;
			if (del_type == null) {
				TypeSpec rt = isStatement ? ec.BuiltinTypes.Void : 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.Containers == null ? 0 : site.Containers.Count;

				if (mutator != null)
					rt = mutator.Mutate (rt);

				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);
				}

				d = new Delegate (site, new TypeExpression (rt, loc),
					Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
					new MemberName ("Container" + index.ToString ("X")),
					new ParametersCompiled (p), null);

				d.CreateContainer ();
				d.DefineContainer ();
				d.Define ();
				d.PrepareEmit ();

				site.AddTypeContainer (d);

				//
				// Add new container to inflated site container when the
				// member cache already exists
				//
				if (site.CurrentType is InflatedTypeSpec && index > 0)
					site.CurrentType.MemberCache.AddMember (d.CurrentType);

				del_type = new TypeExpression (d.CurrentType, loc);
				if (targs_for_instance != null) {
					del_type_instance_access = null;
				} else {
					del_type_instance_access = del_type;
				}
			} else {
				d = null;
			}

			var site_type_decl = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type), loc);
			var field = site_container.CreateCallSiteField (site_type_decl, loc);
			if (field == null)
				return;

			if (del_type_instance_access == null) {
				var dt = d.CurrentType.DeclaringType.MakeGenericType (module, context_mvars.Types);
				del_type_instance_access = new TypeExpression (MemberCache.GetMember (dt, d.CurrentType), loc);
			}

			var instanceAccessExprType = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec,
				new TypeArguments (del_type_instance_access), loc);

			if (instanceAccessExprType.ResolveAsType (ec.MemberContext) == null)
				return;

			bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

			TypeSpec gt;
			if (inflate_using_mvar || context_mvars == null) {
				gt = site_container.CurrentType;
			} else {
				gt = site_container.CurrentType.MakeGenericType (module, context_mvars.Types);
			}

			// When site container already exists the inflated version has to be
			// updated manually to contain newly created field
			if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) {
				var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
				var inflator = new TypeParameterInflator (module, gt, tparams, gt.TypeArguments);
				gt.MemberCache.AddMember (field.InflateMember (inflator));
			}

			FieldExpr site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc);

			BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void);

			Arguments args = new Arguments (1);
			args.Add (new Argument (binder));
			StatementExpression s = new StatementExpression (new SimpleAssign (site_field_expr, new Invocation (new MemberAccess (instanceAccessExprType, "Create"), args)));

			using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {

				var conditionalAccessReceiver = IsConditionalAccessReceiver;
				var ca = ec.ConditionalAccess;

				if (conditionalAccessReceiver) {
					ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ()) {
						Statement = isStatement
					};

					//
					// Emit conditional access expressions before dynamic call
					// is initialized. It pushes site_field_expr on stack before
					// the actual instance argument is emited which would cause
					// jump from non-empty stack.
					//
					EmitConditionalAccess (ec);
				}

				if (s.Resolve (bc)) {
					Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
					init.Emit (ec);
				}

				args = new Arguments (1 + dyn_args_count);
				args.Add (new Argument (site_field_expr));
				if (arguments != null) {
					int arg_pos = 1;
					foreach (Argument a in arguments) {
						if (a is NamedArgument) {
							// Name is not valid in this context
							args.Add (new Argument (a.Expr, a.ArgType));
						} else {
							args.Add (a);
						}

						if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
							a.Expr.Type = targs[arg_pos].Type;

						++arg_pos;
					}
				}

				var target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, false, loc).Resolve (bc);
				if (target != null) {
					target.Emit (ec);
				}

				if (conditionalAccessReceiver) {
					ec.CloseConditionalAccess (!isStatement && type.IsNullableType ? type : null);
					ec.ConditionalAccess = ca;
				}
			}
		}
示例#7
0
文件: anonymous.cs 项目: rabink/mono
		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,
				new StringConstant (Compiler.BuiltinTypes, " }", loc));

			//
			// Equals (object obj) override
			//		
			var other_variable_assign = new TemporaryVariableReference (li_other, loc);
			equals_block.AddStatement (new StatementExpression (
				new SimpleAssign (other_variable_assign,
					new As (equals_block.GetParameterReference (0, 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));

			equals.Block = equals_block;
			equals.Define ();
			Members.Add (equals);

			//
			// GetHashCode () override
			//
			Method hashcode = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Int, loc),
				Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN,
				new MemberName ("GetHashCode", loc),
				Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);

			//
			// Modified FNV with good avalanche behavior and uniform
			// distribution with larger hash sizes.
			//
			// const int FNV_prime = 16777619;
			// int hash = (int) 2166136261;
			// foreach (int d in data)
			//     hash = (hash ^ d) * FNV_prime;
			// hash += hash << 13;
			// hash ^= hash >> 7;
			// hash += hash << 3;
			// hash ^= hash >> 17;
			// hash += hash << 5;

			ToplevelBlock hashcode_top = new ToplevelBlock (Compiler, loc);
			Block hashcode_block = new Block (hashcode_top, loc, loc);
			hashcode_top.AddStatement (new Unchecked (hashcode_block, loc));

			var li_hash = LocalVariable.CreateCompilerGenerated (Compiler.BuiltinTypes.Int, hashcode_top, loc);
			hashcode_block.AddStatement (new BlockVariableDeclaration (new TypeExpression (li_hash.Type, loc), li_hash));
			LocalVariableReference hash_variable_assign = new LocalVariableReference (li_hash, loc);
			hashcode_block.AddStatement (new StatementExpression (
				new SimpleAssign (hash_variable_assign, rs_hashcode)));

			var hash_variable = new LocalVariableReference (li_hash, loc);
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.Addition, hash_variable,
					new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 13, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
					new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 7, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.Addition, hash_variable,
					new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 3, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
					new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 17, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.Addition, hash_variable,
					new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 5, loc)))));

			hashcode_block.AddStatement (new Return (hash_variable, loc));
			hashcode.Block = hashcode_top;
			hashcode.Define ();
			Members.Add (hashcode);

			//
			// ToString () override
			//

			ToplevelBlock tostring_block = new ToplevelBlock (Compiler, loc);
			tostring_block.AddStatement (new Return (string_concat, loc));
			tostring.Block = tostring_block;
			tostring.Define ();
			Members.Add (tostring);

			return true;
		}
		Expression DoResolve (ResolveContext ec, Expression right_side)
		{
			if (type != null)
				throw new Exception ();

			//
			// Resolve the expression with flow analysis turned off, we'll do the definite
			// assignment checks later.  This is because we don't know yet what the expression
			// will resolve to - it may resolve to a FieldExpr and in this case we must do the
			// definite assignment check on the actual field and not on the whole struct.
			//

			SimpleName original = expr as SimpleName;
			Expression expr_resolved = expr.Resolve (ec,
				ResolveFlags.VariableOrValue | ResolveFlags.Type |
				ResolveFlags.Intermediate | ResolveFlags.DisableStructFlowAnalysis);

			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 (ec.Compiler, LookupIdentifier, loc);

				if (retval == null)
					ns.Error_NamespaceDoesNotExist (loc, LookupIdentifier, ec.Report);
				else if (targs != null)
					retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);

				return retval;
			}

			Type expr_type = expr_resolved.Type;
			if (TypeManager.IsDynamicType (expr_type)) {
				Arguments args = new Arguments (2);
				args.Add (new Argument (expr_resolved.Resolve (ec)));
				if (right_side != null)
					args.Add (new Argument (right_side));

				return new DynamicMemberBinder (right_side != null, Name, args, loc).Resolve (ec);
			}

			if (expr_type.IsPointer || expr_type == TypeManager.void_type ||
				expr_type == TypeManager.null_type || expr_type == InternalType.AnonymousMethod) {
				Unary.Error_OperatorCannotBeApplied (ec, loc, ".", expr_type);
				return null;
			}

			Constant c = expr_resolved as Constant;
			if (c != null && c.GetValue () == null) {
				ec.Report.Warning (1720, 1, loc, "Expression will always cause a `{0}'",
					"System.NullReferenceException");
			}

			if (targs != null) {
				if (!targs.Resolve (ec))
					return null;
			}

			Expression member_lookup;
			member_lookup = MemberLookup (ec.Compiler,
				ec.CurrentType, expr_type, expr_type, Name, loc);

			if (member_lookup == null && targs != null) {
				member_lookup = MemberLookup (ec.Compiler,
					ec.CurrentType, expr_type, expr_type, LookupIdentifier, loc);
			}

			if (member_lookup == null) {
				ExprClass expr_eclass = expr_resolved.eclass;

				//
				// Extension methods are not allowed on all expression types
				//
				if (expr_eclass == ExprClass.Value || expr_eclass == ExprClass.Variable ||
					expr_eclass == ExprClass.IndexerAccess || expr_eclass == ExprClass.PropertyAccess ||
					expr_eclass == ExprClass.EventAccess) {
					ExtensionMethodGroupExpr ex_method_lookup = ec.LookupExtensionMethod (expr_type, Name, loc);
					if (ex_method_lookup != null) {
						ex_method_lookup.ExtensionExpression = expr_resolved;

						if (targs != null) {
							ex_method_lookup.SetTypeArguments (ec, targs);
						}

						return ex_method_lookup.DoResolve (ec);
					}
				}

				expr = expr_resolved;
				member_lookup = Error_MemberLookupFailed (ec,
					ec.CurrentType, expr_type, expr_type, Name, null,
					AllMemberTypes, AllBindingFlags);
				if (member_lookup == null)
					return null;
			}

			TypeExpr texpr = member_lookup as TypeExpr;
			if (texpr != null) {
				if (!(expr_resolved is TypeExpr) && 
				    (original == null || !original.IdenticalNameAndTypeName (ec, expr_resolved, loc))) {
					ec.Report.Error (572, loc, "`{0}': cannot reference a type through an expression; try `{1}' instead",
						Name, member_lookup.GetSignatureForError ());
					return null;
				}

				if (!texpr.CheckAccessLevel (ec.MemberContext)) {
					ec.Report.SymbolRelatedToPreviousError (member_lookup.Type);
					ErrorIsInaccesible (loc, TypeManager.CSharpName (member_lookup.Type), ec.Report);
					return null;
				}

				GenericTypeExpr ct = expr_resolved as GenericTypeExpr;
				if (ct != null) {
					//
					// When looking up a nested type in a generic instance
					// via reflection, we always get a generic type definition
					// and not a generic instance - so we have to do this here.
					//
					// See gtest-172-lib.cs and gtest-172.cs for an example.
					//

					TypeArguments nested_targs;
					if (HasTypeArguments) {
						nested_targs = ct.TypeArguments.Clone ();
						nested_targs.Add (targs);
					} else {
						nested_targs = ct.TypeArguments;
					}

					ct = new GenericTypeExpr (member_lookup.Type, nested_targs, loc);

					return ct.ResolveAsTypeStep (ec, false);
				}

				return member_lookup;
			}

			MemberExpr me = (MemberExpr) member_lookup;
			me = me.ResolveMemberAccess (ec, expr_resolved, loc, original);
			if (me == null)
				return null;

			if (targs != null) {
				me.SetTypeArguments (ec, targs);
			}

			if (original != null && !TypeManager.IsValueType (expr_type)) {
				if (me.IsInstance) {
					LocalVariableReference var = expr_resolved as LocalVariableReference;
					if (var != null && !var.VerifyAssigned (ec))
						return null;
				}
			}

			// The following DoResolve/DoResolveLValue will do the definite assignment
			// check.

			if (right_side != null)
				return me.DoResolveLValue (ec, right_side);
			else
				return me.DoResolve (ec);
		}
		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;
		}
示例#10
0
		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;
		}
示例#11
0
		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);
		}
示例#12
0
        TypeExpr CreateSiteType(EmitContext ec, Arguments arguments, int dyn_args_count, bool is_statement)
        {
            int default_args = is_statement ? 1 : 2;
            var module       = ec.MemberContext.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.Compiler, 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);
        }
示例#13
0
		public override FullNamedExpression ResolveAsTypeStep (IMemberContext ec, bool silent)
		{
			int errors = ec.Compiler.Report.Errors;
			FullNamedExpression fne = ec.LookupNamespaceOrType (Name, loc, /*ignore_cs0104=*/ false);

			if (fne != null) {
				if (fne.Type == null)
					return fne;

				FullNamedExpression nested = ResolveNested (fne.Type);
				if (nested != null)
					return nested.ResolveAsTypeStep (ec, false);

				if (targs != null) {
					if (TypeManager.IsGenericType (fne.Type)) {
						GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
						return ct.ResolveAsTypeStep (ec, false);
					}

					Namespace.Error_TypeArgumentsCannotBeUsed (fne, loc);
				}

				return fne;
			}

			if (!HasTypeArguments && Name == "dynamic" && RootContext.Version > LanguageVersion.V_3)
				return new DynamicTypeExpr (loc);

			if (silent || errors != ec.Compiler.Report.Errors)
				return null;

			Error_TypeOrNamespaceNotFound (ec);
			return null;
		}
示例#14
0
文件: dynamic.cs 项目: cthrax/mono
		TypeExpr CreateSiteType (EmitContext ec, Arguments arguments, int dyn_args_count, bool is_statement)
		{
			int default_args = is_statement ? 1 : 2;

			bool has_ref_out_argument = false;
			var targs = new TypeExpression[dyn_args_count + default_args];
			targs [0] = new TypeExpression (TypeManager.call_site_type, 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;

				targs [i + 1] = new TypeExpression (a.Type, loc);
			}

			TypeExpr del_type = null;
			if (!has_ref_out_argument) {
				string d_name = is_statement ? "Action" : "Func";

				TypeSpec t = TypeManager.CoreLookupType (ec.MemberContext.Compiler, "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);

				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 (TypeManager.generic_call_site_type, new TypeArguments (del_type), loc);
			return site_type;
		}
示例#15
0
        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)
            {
                TypeParameter[] 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";

                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, Location.Null);
                }

                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.Type, new TypeArguments(targs), loc);
                    if (targs_for_instance != null)
                    {
                        del_type_instance_access = new GenericTypeExpr(te.Type, new TypeArguments(targs_for_instance), loc);
                    }
                    else
                    {
                        del_type_instance_access = del_type;
                    }
                }
            }

            //
            // Create custom delegate when no appropriate predefined delegate has been found
            //
            Delegate d;

            if (del_type == null)
            {
                TypeSpec    rt = isStatement ? ec.BuiltinTypes.Void : 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 (mutator != null)
                {
                    rt = mutator.Mutate(rt);
                }

                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);
                }

                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();

                site.AddDelegate(d);
                del_type = new TypeExpression(d.CurrentType, loc);
                if (targs_for_instance != null)
                {
                    del_type_instance_access = null;
                }
                else
                {
                    del_type_instance_access = del_type;
                }
            }
            else
            {
                d = null;
            }

            var site_type_decl = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments(del_type), loc);
            var field          = site_container.CreateCallSiteField(site_type_decl, loc);

            if (field == null)
            {
                return;
            }

            if (del_type_instance_access == null)
            {
                var dt = d.CurrentType.DeclaringType.MakeGenericType(module, context_mvars.Select(l => l.Type).ToArray());
                del_type_instance_access = new TypeExpression(MemberCache.GetMember(dt, d.CurrentType), loc);
            }

            FullNamedExpression instanceAccessExprType = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec,
                                                                             new TypeArguments(del_type_instance_access), loc);

            BlockContext bc = new BlockContext(ec.MemberContext, null, ec.BuiltinTypes.Void);

            instanceAccessExprType = instanceAccessExprType.ResolveAsType(bc);
            if (instanceAccessExprType == null)
            {
                return;
            }

            bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

            TypeSpec gt;

            if (inflate_using_mvar || context_mvars == null)
            {
                gt = site_container.CurrentType;
            }
            else
            {
                gt = site_container.CurrentType.MakeGenericType(module, context_mvars.Select(l => l.Type).ToArray());
            }

            // When site container already exists the inflated version has to be
            // updated manually to contain newly created field
            if (gt is InflatedTypeSpec && site_container.Fields.Count > 1)
            {
                var tparams  = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
                var inflator = new TypeParameterInflator(module, gt, tparams, gt.TypeArguments);
                gt.MemberCache.AddMember(field.InflateMember(inflator));
            }

            FieldExpr site_field_expr = new FieldExpr(MemberCache.GetMember(gt, field), loc);

            SymbolWriter.OpenCompilerGeneratedBlock(ec);

            Arguments args = new Arguments(1);

            args.Add(new Argument(binder));
            StatementExpression s = new StatementExpression(new SimpleAssign(site_field_expr, new Invocation(new MemberAccess(instanceAccessExprType, "Create"), args)));

            if (s.Resolve(bc))
            {
                Statement init = new If(new Binary(Binary.Operator.Equality, site_field_expr, new NullLiteral(loc), loc), s, loc);
                init.Emit(ec);
            }

            args = new Arguments(1 + dyn_args_count);
            args.Add(new Argument(site_field_expr));
            if (arguments != null)
            {
                int arg_pos = 1;
                foreach (Argument a in arguments)
                {
                    if (a is NamedArgument)
                    {
                        // Name is not valid in this context
                        args.Add(new Argument(a.Expr, a.ArgType));
                    }
                    else
                    {
                        args.Add(a);
                    }

                    if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
                    {
                        a.Expr.Type = targs[arg_pos].Type;
                    }

                    ++arg_pos;
                }
            }

            Expression target = new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, loc).Resolve(bc);

            if (target != null)
            {
                target.Emit(ec);
            }

            SymbolWriter.CloseCompilerGeneratedBlock(ec);
        }
		public override Expression DoResolve (ResolveContext ec)
		{
			if (ec.HasSet (ResolveContext.Options.ConstantScope)) {
				ec.Report.Error (836, loc, "Anonymous types cannot be used in this expression");
				return null;
			}

			if (parameters == null) {
				anonymous_type = CreateAnonymousType (ec, EmptyParameters);
				RequestedType = new TypeExpression (anonymous_type.TypeBuilder, loc);
				return base.DoResolve (ec);
			}

			bool error = false;
			Arguments = new Arguments (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 (ec, parameters);
			if (anonymous_type == null)
				return null;

			RequestedType = new GenericTypeExpr (anonymous_type.TypeBuilder, new TypeArguments (t_args), loc);
			return base.DoResolve (ec);
		}
示例#17
0
        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;
        }
示例#18
0
		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));

			equals.Block = equals_block;
			equals.Define ();
			AddMethod (equals);

			//
			// GetHashCode () override
			//
			Method hashcode = new Method (this, null, TypeManager.system_int32_expr,
				Modifiers.PUBLIC | Modifiers.OVERRIDE | Modifiers.DEBUGGER_HIDDEN,
				new MemberName ("GetHashCode", loc),
				Mono.CSharp.ParametersCompiled.EmptyReadOnlyParameters, null);

			//
			// Modified FNV with good avalanche behavior and uniform
			// distribution with larger hash sizes.
			//
			// const int FNV_prime = 16777619;
			// int hash = (int) 2166136261;
			// foreach (int d in data)
			//     hash = (hash ^ d) * FNV_prime;
			// hash += hash << 13;
			// hash ^= hash >> 7;
			// hash += hash << 3;
			// hash ^= hash >> 17;
			// hash += hash << 5;

			ToplevelBlock hashcode_top = new ToplevelBlock (Compiler, loc);
			Block hashcode_block = new Block (hashcode_top);
			hashcode_top.AddStatement (new Unchecked (hashcode_block));

			hashcode_block.AddVariable (TypeManager.system_int32_expr, "hash", loc);
			LocalVariableReference hash_variable = new LocalVariableReference (hashcode_block, "hash", loc);
			LocalVariableReference hash_variable_assign = new LocalVariableReference (hashcode_block, "hash", loc);
			hashcode_block.AddStatement (new StatementExpression (
				new SimpleAssign (hash_variable_assign, rs_hashcode)));

			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.Addition, hash_variable,
					new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (13, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
					new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (7, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.Addition, hash_variable,
					new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (3, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
					new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (17, loc)))));
			hashcode_block.AddStatement (new StatementExpression (
				new CompoundAssign (Binary.Operator.Addition, hash_variable,
					new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (5, loc)))));

			hashcode_block.AddStatement (new Return (hash_variable, loc));
			hashcode.Block = hashcode_top;
			hashcode.Define ();
			AddMethod (hashcode);

			//
			// ToString () override
			//

			ToplevelBlock tostring_block = new ToplevelBlock (Compiler, loc);
			tostring_block.AddStatement (new Return (string_concat, loc));
			tostring.Block = tostring_block;
			tostring.Define ();
			AddMethod (tostring);
		}
示例#19
0
文件: dynamic.cs 项目: speier/shake
        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;
        }
示例#20
0
		//
		// 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);
		}
示例#21
0
文件: anonymous.cs 项目: rabink/mono
		TypeExpr CreateStoreyTypeExpression (EmitContext ec)
		{
			//
			// Create an instance of storey type
			//
			TypeExpr storey_type_expr;
			if (CurrentTypeParameters != null) {
				//
				// Use current method type parameter (MVAR) for top level storey only. All
				// nested storeys use class type parameter (VAR)
				//
				var tparams = ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.Storey != null ?
					ec.CurrentAnonymousMethod.Storey.CurrentTypeParameters :
					ec.CurrentTypeParameters;

				TypeArguments targs = new TypeArguments ();

				//
				// Use type parameter name instead of resolved type parameter
				// specification to resolve to correctly nested type parameters
				//
				for (int i = 0; i < tparams.Count; ++i)
					targs.Add (new SimpleName (tparams [i].Name, Location)); //  new TypeParameterExpr (tparams[i], Location));

				storey_type_expr = new GenericTypeExpr (Definition, targs, Location);
			} else {
				storey_type_expr = new TypeExpression (CurrentType, Location);
			}

			return storey_type_expr;
		}
示例#22
0
文件: dynamic.cs 项目: mdae/MonoRT
        TypeExpr CreateSiteType(CompilerContext ctx, bool isStatement, int dyn_args_count)
        {
            int default_args = isStatement ? 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)
            {
                Type     arg_type;
                Argument a = arguments [i];
                if (a.Type == TypeManager.null_type)
                {
                    arg_type = TypeManager.object_type;
                }
                else
                {
                    arg_type = TypeManager.TypeToReflectionType(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 = isStatement ? "Action`" : "Func`";

                Type t = TypeManager.CoreLookupType(ctx, "System", d_name + (dyn_args_count + default_args), Kind.Delegate, false);
                if (t != null)
                {
                    if (!isStatement)
                    {
                        targs[targs.Length - 1] = new TypeExpression(TypeManager.TypeToReflectionType(type), loc);
                    }

                    del_type = new GenericTypeExpr(t, new TypeArguments(targs), loc);
                }
            }

            // No appropriate predefined delegate found
            if (del_type == null)
            {
                Type        rt = isStatement ? 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(p), null);

                d.DefineType();
                d.Define();

                parent.AddDelegate(d);
                del_type = new TypeExpression(d.TypeBuilder, loc);
            }

            TypeExpr site_type = new GenericTypeExpr(TypeManager.generic_call_site_type, new TypeArguments(del_type), loc);

            return(site_type);
        }