⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statement.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 5 页
字号:
		public Return (Expression expr, Location l)		{			Expr = expr;			loc = l;		}		bool in_exc;		public override bool Resolve (EmitContext ec)		{			AnonymousContainer am = ec.CurrentAnonymousMethod;			if ((am != null) && am.IsIterator && ec.InIterator) {				Report.Error (1622, loc, "Cannot return a value from iterators. Use the yield return " +					      "statement to return a value, or yield break to end the iteration");				return false;			}			if (ec.ReturnType == null){				if (Expr != null){					if (ec.CurrentAnonymousMethod != null){						Report.Error (1662, loc,							"Cannot convert anonymous method block to delegate type `{0}' because some of the return types in the block are not implicitly convertible to the delegate return type",							ec.CurrentAnonymousMethod.GetSignatureForError ());					}					Error (127, "A return keyword must not be followed by any expression when method returns void");					return false;				}			} else {				if (Expr == null){					Error (126, "An object of a type convertible to `{0}' is required " +					       "for the return statement",					       TypeManager.CSharpName (ec.ReturnType));					return false;				}				Expr = Expr.Resolve (ec);				if (Expr == null)					return false;				if (Expr.Type != ec.ReturnType) {					Expr = Convert.ImplicitConversionRequired (						ec, Expr, ec.ReturnType, loc);					if (Expr == null)						return false;				}			}			FlowBranching.UsageVector vector = ec.CurrentBranching.CurrentUsageVector;			if (ec.CurrentBranching.InTryOrCatch (true)) {				ec.CurrentBranching.AddFinallyVector (vector);				in_exc = true;			} else if (ec.InFinally) {				Error (157, "Control cannot leave the body of a finally clause");				return false;			} else				vector.CheckOutParameters (ec.CurrentBranching);			if (in_exc)				ec.NeedReturnLabel ();			ec.CurrentBranching.CurrentUsageVector.Return ();			return true;		}				protected override void DoEmit (EmitContext ec)		{			if (Expr != null) {				Expr.Emit (ec);				if (in_exc)					ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());			}			if (in_exc)				ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);			else				ec.ig.Emit (OpCodes.Ret);		}	}	public class Goto : Statement {		string target;		LabeledStatement label;				public override bool Resolve (EmitContext ec)		{			label = ec.CurrentBranching.LookupLabel (target, loc);			if (label == null)				return false;			// If this is a forward goto.			if (!label.IsDefined)				label.AddUsageVector (ec.CurrentBranching.CurrentUsageVector);			ec.CurrentBranching.CurrentUsageVector.Goto ();			label.AddReference ();			return true;		}				public Goto (string label, Location l)		{			loc = l;			target = label;		}		public string Target {			get {				return target;			}		}		protected override void DoEmit (EmitContext ec)		{			Label l = label.LabelTarget (ec);			ec.ig.Emit (OpCodes.Br, l);		}	}	public class LabeledStatement : Statement {		bool defined;		bool referenced;		Label label;		ILGenerator ig;		FlowBranching.UsageVector vectors;				public LabeledStatement (string label_name, Location l)		{			this.loc = l;		}		public Label LabelTarget (EmitContext ec)		{			if (defined)				return label;			ig = ec.ig;			label = ec.ig.DefineLabel ();			defined = true;			return label;		}		public bool IsDefined {			get {				return defined;			}		}		public bool HasBeenReferenced {			get {				return referenced;			}		}		public void AddUsageVector (FlowBranching.UsageVector vector)		{			vector = vector.Clone ();			vector.Next = vectors;			vectors = vector;		}		public override bool Resolve (EmitContext ec)		{			ec.CurrentBranching.Label (vectors);			return true;		}		protected override void DoEmit (EmitContext ec)		{			if (ig != null && ig != ec.ig) {				// TODO: location is wrong				Report.Error (1632, loc, "Control cannot leave the body of an anonymous method");				return;			}			LabelTarget (ec);			ec.ig.MarkLabel (label);		}		public void AddReference ()		{			referenced = true;		}	}		/// <summary>	///   `goto default' statement	/// </summary>	public class GotoDefault : Statement {				public GotoDefault (Location l)		{			loc = l;		}		public override bool Resolve (EmitContext ec)		{			ec.CurrentBranching.CurrentUsageVector.Goto ();			return true;		}		protected override void DoEmit (EmitContext ec)		{			if (ec.Switch == null){				Report.Error (153, loc, "A goto case is only valid inside a switch statement");				return;			}			if (!ec.Switch.GotDefault){				Report.Error (159, loc, "No such label `default:' within the scope of the goto statement");				return;			}			ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);		}	}	/// <summary>	///   `goto case' statement	/// </summary>	public class GotoCase : Statement {		Expression expr;		SwitchLabel sl;				public GotoCase (Expression e, Location l)		{			expr = e;			loc = l;		}		public override bool Resolve (EmitContext ec)		{			if (ec.Switch == null){				Report.Error (153, loc, "A goto case is only valid inside a switch statement");				return false;			}			expr = expr.Resolve (ec);			if (expr == null)				return false;			Constant c = expr as Constant;			if (c == null) {				Error (150, "A constant value is expected");				return false;			}			c = c.ToType (ec.Switch.SwitchType, loc);			if (c == null)				return false;			object val = c.GetValue ();			if (val == null)				val = SwitchLabel.NullStringCase;								sl = (SwitchLabel) ec.Switch.Elements [val];			if (sl == null){				Report.Error (159, loc, "No such label `case {0}:' within the scope of the goto statement", c.GetValue () == null ? "null" : val);				return false;			}			ec.CurrentBranching.CurrentUsageVector.Goto ();			return true;		}		protected override void DoEmit (EmitContext ec)		{			ec.ig.Emit (OpCodes.Br, sl.GetILLabelCode (ec));		}	}		public class Throw : Statement {		Expression expr;				public Throw (Expression expr, Location l)		{			this.expr = expr;			loc = l;		}		public override bool Resolve (EmitContext ec)		{			ec.CurrentBranching.CurrentUsageVector.Throw ();			if (expr != null){				expr = expr.Resolve (ec);				if (expr == null)					return false;				ExprClass eclass = expr.eclass;				if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||					eclass == ExprClass.Value || eclass == ExprClass.IndexerAccess)) {					expr.Error_UnexpectedKind (ec, "value, variable, property or indexer access ", loc);					return false;				}				Type t = expr.Type;								if ((t != TypeManager.exception_type) &&					!t.IsSubclassOf (TypeManager.exception_type) &&					!(expr is NullLiteral)) {					Error (155,						"The type caught or thrown must be derived " +						"from System.Exception");					return false;				}				return true;			}			if (!ec.InCatch) {				Error (156, "A throw statement with no arguments is not allowed outside of a catch clause");				return false;			}			if (ec.InFinally) {				Error (724, "A throw statement with no arguments is not allowed inside of a finally clause nested inside of the innermost catch clause");				return false;			}			return true;		}					protected override void DoEmit (EmitContext ec)		{			if (expr == null)				ec.ig.Emit (OpCodes.Rethrow);			else {				expr.Emit (ec);				ec.ig.Emit (OpCodes.Throw);			}		}	}	public class Break : Statement {				public Break (Location l)		{			loc = l;		}		bool crossing_exc;		public override bool Resolve (EmitContext ec)		{			if (!ec.CurrentBranching.InLoop () && !ec.CurrentBranching.InSwitch ()){				Error (139, "No enclosing loop out of which to break or continue");				return false;			} else if (ec.InFinally && ec.CurrentBranching.BreakCrossesTryCatchBoundary()) {				Error (157, "Control cannot leave the body of a finally clause");				return false;			} else if (ec.CurrentBranching.InTryOrCatch (false))				ec.CurrentBranching.AddFinallyVector (					ec.CurrentBranching.CurrentUsageVector);			else if (ec.CurrentBranching.InLoop () || ec.CurrentBranching.InSwitch ())				ec.CurrentBranching.AddBreakVector (					ec.CurrentBranching.CurrentUsageVector);			crossing_exc = ec.CurrentBranching.BreakCrossesTryCatchBoundary ();			if (!crossing_exc)				ec.NeedReturnLabel ();			ec.CurrentBranching.CurrentUsageVector.Break ();			return true;		}		protected override void DoEmit (EmitContext ec)		{			ILGenerator ig = ec.ig;			if (crossing_exc)				ig.Emit (OpCodes.Leave, ec.LoopEnd);			else {				ig.Emit (OpCodes.Br, ec.LoopEnd);			}		}	}	public class Continue : Statement {				public Continue (Location l)		{			loc = l;		}		bool crossing_exc;		public override bool Resolve (EmitContext ec)		{			if (!ec.CurrentBranching.InLoop ()){				Error (139, "No enclosing loop out of which to break or continue");				return false;			} else if (ec.InFinally) {				Error (157, "Control cannot leave the body of a finally clause");				return false;			} else if (ec.CurrentBranching.InTryOrCatch (false))				ec.CurrentBranching.AddFinallyVector (ec.CurrentBranching.CurrentUsageVector);			crossing_exc = ec.CurrentBranching.BreakCrossesTryCatchBoundary ();			ec.CurrentBranching.CurrentUsageVector.Goto ();			return true;		}		protected override void DoEmit (EmitContext ec)		{			Label begin = ec.LoopBegin;						if (crossing_exc)				ec.ig.Emit (OpCodes.Leave, begin);			else				ec.ig.Emit (OpCodes.Br, begin);		}	}	//	// The information about a user-perceived local variable	//	public class LocalInfo {		public Expression Type;		//		// Most of the time a variable will be stored in a LocalBuilder		//		// But sometimes, it will be stored in a field (variables that have been		// hoisted by iterators or by anonymous methods).  The context of the field will		// be stored in the EmitContext		//		//		public LocalBuilder LocalBuilder;		public FieldBuilder FieldBuilder;		public Type VariableType;		public readonly string Name;		public readonly Location Location;		public readonly Block Block;		public VariableInfo VariableInfo;		enum Flags : byte {			Used = 1,			ReadOnly = 2,			Pinned = 4,			IsThis = 8,			Captured = 16,			AddressTaken = 32,			CompilerGenerated = 64		}		public enum ReadOnlyContext: byte {			Using,			Foreach,			Fixed		}		Flags flags;		ReadOnlyContext ro_context;				public LocalInfo (Expression type, string name, Block block, Location l)		{			Type = type;			Name = name;			Block = block;			Location = l;		}		public LocalInfo (TypeContainer tc, Block block, Location l)		{			VariableType = tc.TypeBuilder;			Block = block;			Location = l;		}		public bool IsThisAssigned (EmitContext ec, Location loc)		{			if (VariableInfo == null)				throw new Exception ();			if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo))				return true;			return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, loc);		}		public bool IsAssigned (EmitContext ec)		{			if (VariableInfo == null)				throw new Exception ();			return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo);		}		public bool Resolve (EmitContext ec)		{			if (VariableType == null) {				TypeExpr texpr = Type.ResolveAsTypeTerminal (ec, false);				if (texpr == null)					return false;								VariableType = texpr.ResolveType (ec);			}			if (VariableType == TypeManager.void_type) {				Report.Error (1547, Location,					      "Keyword 'void' cannot be used in this context");				return false;			}			if (VariableType.IsAbstract && VariableType.IsSealed) {				Report.Error (723, Location, "Cannot declare variable of static type `{0}'", TypeManager.CSharpName (VariableType));				return false;			}			if (VariableType.IsPointer && !ec.InUnsafe)				Expression.UnsafeError (Location);			return true;		}		public bool IsCaptured {			get {				return (flags & Flags.Captured) != 0;			}			set {				flags |= Flags.Captured;			}		}		public bool AddressTaken {			get {				return (flags & Flags.AddressTaken) != 0;			}			set {				flags |= Flags.AddressTaken;			}		}		public bool CompilerGenerated {			get {				return (flags & Flags.CompilerGenerated) != 0;			}			set {				flags |= Flags.CompilerGenerated;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -