Example #1
0
			public override void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
			{
				base.VisitThisReferenceExpression(thisReferenceExpression);
				var memberReference = thisReferenceExpression.Parent as MemberReferenceExpression;
				if (memberReference == null) {
					return;
				}

				var state = ctx.GetResolverStateAfter(thisReferenceExpression);
				var wholeResult = ctx.Resolve(memberReference);
			
				IMember member = GetMember(wholeResult);
				if (member == null) { 
					return;
				}

				var result = state.LookupSimpleNameOrTypeName(memberReference.MemberName, EmptyList<IType>.Instance, SimpleNameLookupMode.Expression);
			
				bool isRedundant;
				if (result is MemberResolveResult) {
					isRedundant = ((MemberResolveResult)result).Member.Region.Equals(member.Region);
				} else if (result is MethodGroupResolveResult) {
					isRedundant = ((MethodGroupResolveResult)result).Methods.Any(m => m.Region.Equals(member.Region));
				} else {
					return;
				}

				if (isRedundant) {
					AddIssue(thisReferenceExpression.StartLocation, memberReference.MemberNameToken.StartLocation, ctx.TranslateString("Remove redundant 'this.'"), script => {
						script.Replace(memberReference, RefactoringAstHelper.RemoveTarget(memberReference));
					}
					);
				}
			}
		public override IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var property = context.GetNode<PropertyDeclaration> ();
			if (property == null || !property.NameToken.Contains(context.Location))
				yield break;

			if (!IsNotImplemented (context, property.Getter.Body) ||
			    !IsNotImplemented (context, property.Setter.Body)) {
				yield break;
			}
			
			yield return new CodeAction(context.TranslateString("Implement property"), script => {
				string backingStoreName = context.GetNameProposal (property.Name);
				
				// create field
				var backingStore = new FieldDeclaration ();
				if (property.Modifiers.HasFlag (Modifiers.Static))
					backingStore.Modifiers |= Modifiers.Static;

				if (property.Setter.IsNull)
					backingStore.Modifiers |= Modifiers.Readonly;
				
				backingStore.ReturnType = property.ReturnType.Clone ();
				
				var initializer = new VariableInitializer (backingStoreName);
				backingStore.Variables.Add (initializer);
				
				// create new property & implement the get/set bodies
				var newProperty = (PropertyDeclaration)property.Clone ();
				Expression id1;
				if (backingStoreName == "value")
					id1 = new ThisReferenceExpression().Member("value");
				else
					id1 = new IdentifierExpression (backingStoreName);
				Expression id2 = id1.Clone();
				newProperty.Getter.Body = new BlockStatement () {
					new ReturnStatement (id1)
				};
				if (!property.Setter.IsNull) {
					newProperty.Setter.Body = new BlockStatement () {
						new AssignmentExpression (id2, AssignmentOperatorType.Assign, new IdentifierExpression ("value"))
					};
				}
				
				script.Replace (property, newProperty);
				script.InsertBefore (property, backingStore);
				if (!property.Setter.IsNull)
					script.Link (initializer, id1, id2);
				else
					script.Link (initializer, id1);
			}, property.NameToken);
		}
		public IEnumerable<CodeAction> GetActions(RefactoringContext context)
		{
			var property = context.GetNode<PropertyDeclaration>();
			if (!(property != null &&
				!property.Getter.IsNull && !property.Setter.IsNull && // automatic properties always need getter & setter
				property.Getter.Body.IsNull &&
				property.Setter.Body.IsNull)) {
				yield break;
			}
			
			yield return new CodeAction(context.TranslateString("Create backing store"), script => {
				string backingStoreName = context.GetNameProposal (property.Name);
				
				// create field
				var backingStore = new FieldDeclaration ();
				if (property.Modifiers.HasFlag (Modifiers.Static))
					backingStore.Modifiers |= Modifiers.Static;
				backingStore.ReturnType = property.ReturnType.Clone ();
				
				var initializer = new VariableInitializer (backingStoreName);
				backingStore.Variables.Add (initializer);
				
				// create new property & implement the get/set bodies
				var newProperty = (PropertyDeclaration)property.Clone ();
				Expression id1;
				if (backingStoreName == "value")
					id1 = new ThisReferenceExpression().Member("value");
				else
					id1 = new IdentifierExpression (backingStoreName);
				Expression id2 = id1.Clone();
				newProperty.Getter.Body = new BlockStatement () {
					new ReturnStatement (id1)
				};
				newProperty.Setter.Body = new BlockStatement () {
					new AssignmentExpression (id2, AssignmentOperatorType.Assign, new IdentifierExpression ("value"))
				};
				
				script.Replace (property, newProperty);
				script.InsertBefore (property, backingStore);
				script.Link (initializer, id1, id2);
			});
		}
Example #4
0
 public abstract StringBuilder VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, int data);
		public virtual object TrackedVisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data) {
			return base.VisitThisReferenceExpression(thisReferenceExpression, data);
		}
Example #6
0
			public override object Visit (This thisExpression)
			{
				var result = new ThisReferenceExpression ();
				result.Location = Convert (thisExpression.Location);
				return result;
			}
Example #7
0
		AstNode TransformByteCode(ILExpression byteCode)
		{
			object operand = byteCode.Operand;
			AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference);

			List<Ast.Expression> args = new List<Expression>();
			foreach(ILExpression arg in byteCode.Arguments) {
				args.Add((Ast.Expression)TransformExpression(arg));
			}
			Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
			Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
			Ast.Expression arg3 = args.Count >= 3 ? args[2] : null;
			
			switch (byteCode.Code) {
					#region Arithmetic
				case ILCode.Add:
				case ILCode.Add_Ovf:
				case ILCode.Add_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PointerType) {
							if (byteCode.Arguments[0].ExpectedType is PointerType) {
								arg2 = DivideBySize(arg2, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else if (byteCode.Arguments[1].ExpectedType is PointerType) {
								arg1 = DivideBySize(arg1, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else {
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Add ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
				case ILCode.Sub:
				case ILCode.Sub_Ovf:
				case ILCode.Sub_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PointerType) {
							if (byteCode.Arguments[0].ExpectedType is PointerType) {
								arg2 = DivideBySize(arg2, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
								boe.WithAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else {
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Sub ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
					case ILCode.Div:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Div_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Mul:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Mul_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Rem:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.Rem_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.And:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2);
					case ILCode.Or:         return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2);
					case ILCode.Xor:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2);
					case ILCode.Shl:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2);
					case ILCode.Shr:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Shr_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Neg:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Not:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1);
				case ILCode.PostIncrement:
				case ILCode.PostIncrement_Ovf:
				case ILCode.PostIncrement_Ovf_Un:
					{
						if (arg1 is DirectionExpression)
							arg1 = ((DirectionExpression)arg1).Expression.Detach();
						var uoe = new Ast.UnaryOperatorExpression(
							(int)byteCode.Operand > 0 ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement, arg1);
						uoe.AddAnnotation((byteCode.Code == ILCode.PostIncrement) ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return uoe;
					}
					#endregion
					#region Arrays
				case ILCode.Newarr:
					case ILCode.InitArray: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						if (ct != null) {
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
						}
						if (byteCode.Code == ILCode.InitArray) {
							ace.Initializer = new ArrayInitializerExpression();
							ace.Initializer.Elements.AddRange(args);
						} else {
							ace.Arguments.Add(arg1);
						}
						return ace;
					}
					case ILCode.Ldlen: return arg1.Member("Length");
				case ILCode.Ldelem_I:
				case ILCode.Ldelem_I1:
				case ILCode.Ldelem_I2:
				case ILCode.Ldelem_I4:
				case ILCode.Ldelem_I8:
				case ILCode.Ldelem_U1:
				case ILCode.Ldelem_U2:
				case ILCode.Ldelem_U4:
				case ILCode.Ldelem_R4:
				case ILCode.Ldelem_R8:
				case ILCode.Ldelem_Ref:
				case ILCode.Ldelem_Any:
					return arg1.Indexer(arg2);
				case ILCode.Ldelema:
					return MakeRef(arg1.Indexer(arg2));
				case ILCode.Stelem_I:
				case ILCode.Stelem_I1:
				case ILCode.Stelem_I2:
				case ILCode.Stelem_I4:
				case ILCode.Stelem_I8:
				case ILCode.Stelem_R4:
				case ILCode.Stelem_R8:
				case ILCode.Stelem_Ref:
				case ILCode.Stelem_Any:
					return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
				case ILCode.CompoundAssignment:
					{
						CastExpression cast = arg1 as CastExpression;
						BinaryOperatorExpression boe = (BinaryOperatorExpression)(cast != null ? cast.Expression : arg1);
						var assignment = new Ast.AssignmentExpression {
							Left = boe.Left.Detach(),
							Operator = ReplaceMethodCallsWithOperators.GetAssignmentOperatorForBinaryOperator(boe.Operator),
							Right = boe.Right.Detach()
						}.CopyAnnotationsFrom(boe);
						// We do not mark the resulting assignment as RestoreOriginalAssignOperatorAnnotation, because
						// the operator cannot be translated back to the expanded form (as the left-hand expression
						// would be evaluated twice, and might have side-effects)
						if (cast != null) {
							cast.Expression = assignment;
							return cast;
						} else {
							return assignment;
						}
					}
					#endregion
					#region Comparison
					case ILCode.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
					case ILCode.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					case ILCode.Cgt_Un: {
						// can also mean Inequality, when used with object references
						TypeReference arg1Type = byteCode.Arguments[0].InferredType;
						if (arg1Type != null && !arg1Type.IsValueType)
							return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
						else
							return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					}
					case ILCode.Clt:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					case ILCode.Clt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					#endregion
					#region Logical
					case ILCode.LogicNot:   return new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1);
					case ILCode.LogicAnd:   return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalAnd, arg2);
					case ILCode.LogicOr:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalOr, arg2);
					case ILCode.TernaryOp:  return new Ast.ConditionalExpression() { Condition = arg1, TrueExpression = arg2, FalseExpression = arg3 };
					case ILCode.NullCoalescing: 	return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.NullCoalescing, arg2);
					#endregion
					#region Branch
					case ILCode.Br:         return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
				case ILCode.Brtrue:
					return new Ast.IfElseStatement() {
						Condition = arg1,
						TrueStatement = new BlockStatement() {
							new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
						}
					};
					case ILCode.LoopOrSwitchBreak: return new Ast.BreakStatement();
					case ILCode.LoopContinue:      return new Ast.ContinueStatement();
					#endregion
					#region Conversions
				case ILCode.Conv_I1:
				case ILCode.Conv_I2:
				case ILCode.Conv_I4:
				case ILCode.Conv_I8:
				case ILCode.Conv_U1:
				case ILCode.Conv_U2:
				case ILCode.Conv_U4:
				case ILCode.Conv_U8:
				case ILCode.Conv_I:
				case ILCode.Conv_U:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);
						}
						return arg1;
					}
				case ILCode.Conv_R4:
				case ILCode.Conv_R8:
				case ILCode.Conv_R_Un: // TODO
					return arg1;
				case ILCode.Conv_Ovf_I1:
				case ILCode.Conv_Ovf_I2:
				case ILCode.Conv_Ovf_I4:
				case ILCode.Conv_Ovf_I8:
				case ILCode.Conv_Ovf_U1:
				case ILCode.Conv_Ovf_U2:
				case ILCode.Conv_Ovf_U4:
				case ILCode.Conv_Ovf_U8:
				case ILCode.Conv_Ovf_I1_Un:
				case ILCode.Conv_Ovf_I2_Un:
				case ILCode.Conv_Ovf_I4_Un:
				case ILCode.Conv_Ovf_I8_Un:
				case ILCode.Conv_Ovf_U1_Un:
				case ILCode.Conv_Ovf_U2_Un:
				case ILCode.Conv_Ovf_U4_Un:
				case ILCode.Conv_Ovf_U8_Un:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);
						}
						return arg1;
					}
					case ILCode.Conv_Ovf_I:     return arg1.CastTo(typeof(IntPtr)); // TODO
					case ILCode.Conv_Ovf_U:     return arg1.CastTo(typeof(UIntPtr));
					case ILCode.Conv_Ovf_I_Un:  return arg1.CastTo(typeof(IntPtr));
					case ILCode.Conv_Ovf_U_Un:  return arg1.CastTo(typeof(UIntPtr));
					case ILCode.Castclass:      return arg1.CastTo(operandAsTypeRef);
				case ILCode.Unbox_Any:
					// unboxing does not require a cast if the argument was an isinst instruction
					if (arg1 is AsExpression && byteCode.Arguments[0].Code == ILCode.Isinst && TypeAnalysis.IsSameType(operand as TypeReference, byteCode.Arguments[0].Operand as TypeReference))
						return arg1;
					else
						return arg1.CastTo(operandAsTypeRef);
					case ILCode.Isinst:         return arg1.CastAs(operandAsTypeRef);
					case ILCode.Box:            return arg1;
					case ILCode.Unbox:          return InlineAssembly(byteCode, args);
					#endregion
					#region Indirect
				case ILCode.Ldind_Ref:
				case ILCode.Ldobj:
					if (arg1 is DirectionExpression)
						return ((DirectionExpression)arg1).Expression.Detach();
					else
						return new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1);
				case ILCode.Stind_Ref:
				case ILCode.Stobj:
					if (arg1 is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)arg1).Expression.Detach(), arg2);
					else
						return new AssignmentExpression(new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1), arg2);
					#endregion
				case ILCode.Arglist:
					return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess };
					case ILCode.Break:    return InlineAssembly(byteCode, args);
				case ILCode.Call:
				case ILCode.CallGetter:
				case ILCode.CallSetter:
					return TransformCall(false, byteCode, args);
				case ILCode.Callvirt:
				case ILCode.CallvirtGetter:
				case ILCode.CallvirtSetter:
					return TransformCall(true, byteCode,  args);
					case ILCode.Ldftn: {
						Cecil.MethodReference cecilMethod = ((MethodReference)operand);
						var expr = new Ast.IdentifierExpression(cecilMethod.Name);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return new IdentifierExpression("ldftn").Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(false));
					}
					case ILCode.Ldvirtftn: {
						Cecil.MethodReference cecilMethod = ((MethodReference)operand);
						var expr = new Ast.IdentifierExpression(cecilMethod.Name);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return new IdentifierExpression("ldvirtftn").Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true));
					}
					case ILCode.Calli:       return InlineAssembly(byteCode, args);
					case ILCode.Ckfinite:    return InlineAssembly(byteCode, args);
					case ILCode.Constrained: return InlineAssembly(byteCode, args);
					case ILCode.Cpblk:       return InlineAssembly(byteCode, args);
					case ILCode.Cpobj:       return InlineAssembly(byteCode, args);
					case ILCode.Dup:         return arg1;
					case ILCode.Endfilter:   return InlineAssembly(byteCode, args);
					case ILCode.Endfinally:  return null;
					case ILCode.Initblk:     return InlineAssembly(byteCode, args);
				case ILCode.Initobj:
					if (args[0] is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), MakeDefaultValue((TypeReference)operand));
					else
						return InlineAssembly(byteCode, args);
				case ILCode.DefaultValue:
					return MakeDefaultValue((TypeReference)operand);
					case ILCode.Jmp: return InlineAssembly(byteCode, args);
				case ILCode.Ldc_I4:
					return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType);
				case ILCode.Ldc_I8:
					return AstBuilder.MakePrimitive((long)operand, byteCode.InferredType);
				case ILCode.Ldc_R4:
				case ILCode.Ldc_R8:
				case ILCode.Ldc_Decimal:
					return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand);
				case ILCode.Ldsfld:
					return AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand);
				case ILCode.Stfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return new AssignmentExpression(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand), arg2);
				case ILCode.Stsfld:
					return new AssignmentExpression(
						AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand),
						arg1);
				case ILCode.Ldflda:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return MakeRef(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand));
				case ILCode.Ldsflda:
					return MakeRef(
						AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand));
					case ILCode.Ldloc: {
						ILVariable v = (ILVariable)operand;
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						Expression expr;
						if (v.IsParameter && v.OriginalParameter.Index < 0)
							expr = new ThisReferenceExpression();
						else
							expr = new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand);
						return v.IsParameter && v.Type is ByReferenceType ? MakeRef(expr) : expr;
					}
					case ILCode.Ldloca: {
						ILVariable v = (ILVariable)operand;
						if (v.IsParameter && v.OriginalParameter.Index < 0)
							return MakeRef(new ThisReferenceExpression());
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand));
					}
					case ILCode.Ldnull: return new Ast.NullReferenceExpression();
					case ILCode.Ldstr:  return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldtoken:
					if (operand is Cecil.TypeReference) {
						return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle");
					} else {
						return InlineAssembly(byteCode, args);
					}
					case ILCode.Leave:    return new GotoStatement() { Label = ((ILLabel)operand).Name };
				case ILCode.Localloc:
					{
						PointerType ptrType = byteCode.InferredType as PointerType;
						TypeReference type;
						if (ptrType != null) {
							type = ptrType.ElementType;
						} else {
							type = typeSystem.Byte;
						}
						return new StackAllocExpression {
							Type = AstBuilder.ConvertType(type),
							CountExpression = DivideBySize(arg1, type)
						};
					}
				case ILCode.Mkrefany:
					{
						DirectionExpression dir = arg1 as DirectionExpression;
						if (dir != null) {
							return new UndocumentedExpression {
								UndocumentedExpressionType = UndocumentedExpressionType.MakeRef,
								Arguments = { dir.Expression.Detach() }
							};
						} else {
							return InlineAssembly(byteCode, args);
						}
					}
				case ILCode.Refanytype:
					return new UndocumentedExpression {
						UndocumentedExpressionType = UndocumentedExpressionType.RefType,
						Arguments = { arg1 }
					}.Member("TypeHandle");
				case ILCode.Refanyval:
					return MakeRef(
						new UndocumentedExpression {
							UndocumentedExpressionType = UndocumentedExpressionType.RefValue,
							Arguments = { arg1, new TypeReferenceExpression(operandAsTypeRef) }
						});
					case ILCode.Newobj: {
						Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
						if (declaringType is ArrayType) {
							ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType;
							if (ct != null && ct.ArraySpecifiers.Count >= 1) {
								var ace = new Ast.ArrayCreateExpression();
								ct.ArraySpecifiers.First().Remove();
								ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
								ace.Type = ct;
								ace.Arguments.AddRange(args);
								return ace;
							}
						}
						var oce = new Ast.ObjectCreateExpression();
						if (declaringType.IsAnonymousType()) {
							MethodDefinition ctor = ((MethodReference)operand).Resolve();
							if (methodDef != null) {
								oce.Initializer = new ArrayInitializerExpression();
								for (int i = 0; i < args.Count; i++) {
									oce.Initializer.Elements.Add(
										new NamedArgumentExpression {
											Identifier = ctor.Parameters[i].Name,
											Expression = args[i]
										});
								}
							}
							return oce;
						}
						oce.Type = AstBuilder.ConvertType(declaringType);
						oce.Arguments.AddRange(args);
						return oce.WithAnnotation(operand);
					}
					case ILCode.No: return InlineAssembly(byteCode, args);
					case ILCode.Nop: return null;
					case ILCode.Pop: return arg1;
					case ILCode.Readonly: return InlineAssembly(byteCode, args);
				case ILCode.Ret:
					if (methodDef.ReturnType.FullName != "System.Void") {
						return new Ast.ReturnStatement { Expression = arg1 };
					} else {
						return new Ast.ReturnStatement();
					}
					case ILCode.Rethrow: return new Ast.ThrowStatement();
					case ILCode.Sizeof:  return new Ast.SizeOfExpression { Type = operandAsTypeRef };
					case ILCode.Stloc: {
						ILVariable locVar = (ILVariable)operand;
						if (!locVar.IsParameter)
							localVariablesToDefine.Add(locVar);
						return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name).WithAnnotation(locVar), arg1);
					}
					case ILCode.Switch: return InlineAssembly(byteCode, args);
					case ILCode.Tail: return InlineAssembly(byteCode, args);
					case ILCode.Throw: return new Ast.ThrowStatement { Expression = arg1 };
					case ILCode.Unaligned: return InlineAssembly(byteCode, args);
					case ILCode.Volatile: return InlineAssembly(byteCode, args);
				case ILCode.YieldBreak:
					return new Ast.YieldBreakStatement();
				case ILCode.YieldReturn:
					return new Ast.YieldStatement { Expression = arg1 };
				case ILCode.InitObject:
				case ILCode.InitCollection:
					{
						ArrayInitializerExpression initializer = new ArrayInitializerExpression();
						for (int i = 1; i < args.Count; i++) {
							Match m = objectInitializerPattern.Match(args[i]);
							if (m.Success) {
								MemberReferenceExpression mre = m.Get<MemberReferenceExpression>("left").Single();
								initializer.Elements.Add(
									new NamedArgumentExpression {
										Identifier = mre.MemberName,
										Expression = m.Get<Expression>("right").Single().Detach()
									}.CopyAnnotationsFrom(mre));
							} else {
								m = collectionInitializerPattern.Match(args[i]);
								if (m.Success) {
									if (m.Get("arg").Count() == 1) {
										initializer.Elements.Add(m.Get<Expression>("arg").Single().Detach());
									} else {
										ArrayInitializerExpression argList = new ArrayInitializerExpression();
										foreach (var expr in m.Get<Expression>("arg")) {
											argList.Elements.Add(expr.Detach());
										}
										initializer.Elements.Add(argList);
									}
								} else {
									initializer.Elements.Add(args[i]);
								}
							}
						}
						ObjectCreateExpression oce = arg1 as ObjectCreateExpression;
						if (oce != null) {
							oce.Initializer = initializer;
							return oce;
						} else {
							return new AssignmentExpression(arg1, initializer);
						}
					}
				case ILCode.InitializedObject:
					return new InitializedObjectExpression();
				case ILCode.AddressOf:
					return MakeRef(arg1);
				default:
					throw new Exception("Unknown OpCode: " + byteCode.Code);
			}
		}
Example #8
0
		AstNode TransformByteCode(ILExpression byteCode)
		{
			object operand = byteCode.Operand;
			AstType operandAsTypeRef = AstBuilder.ConvertType(operand as Cecil.TypeReference);

			List<Ast.Expression> args = new List<Expression>();
			foreach(ILExpression arg in byteCode.Arguments) {
				args.Add((Ast.Expression)TransformExpression(arg));
			}
			Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
			Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
			Ast.Expression arg3 = args.Count >= 3 ? args[2] : null;
			
			switch (byteCode.Code) {
					#region Arithmetic
				case ILCode.Add:
				case ILCode.Add_Ovf:
				case ILCode.Add_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PointerType) {
							if (byteCode.Arguments[0].ExpectedType is PointerType) {
								arg2 = DivideBySize(arg2, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else if (byteCode.Arguments[1].ExpectedType is PointerType) {
								arg1 = DivideBySize(arg1, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else {
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Add ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
				case ILCode.Sub:
				case ILCode.Sub_Ovf:
				case ILCode.Sub_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PointerType) {
							if (byteCode.Arguments[0].ExpectedType is PointerType) {
								arg2 = DivideBySize(arg2, ((PointerType)byteCode.InferredType).ElementType);
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
								boe.WithAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							} else {
								boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Sub ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
					case ILCode.Div:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Div_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Mul:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Mul_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Rem:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.Rem_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.And:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2);
					case ILCode.Or:         return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2);
					case ILCode.Xor:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2);
					case ILCode.Shl:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2);
					case ILCode.Shr:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Shr_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Neg:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Not:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1);
					#endregion
					#region Arrays
				case ILCode.Newarr:
					case ILCode.InitArray: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						if (ct != null) {
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
						}
						if (byteCode.Code == ILCode.InitArray) {
							ace.Initializer = new ArrayInitializerExpression();
							ace.Initializer.Elements.AddRange(args);
						} else {
							ace.Arguments.Add(arg1);
						}
						return ace;
					}
					case ILCode.Ldlen: return arg1.Member("Length");
				case ILCode.Ldelem_I:
				case ILCode.Ldelem_I1:
				case ILCode.Ldelem_I2:
				case ILCode.Ldelem_I4:
				case ILCode.Ldelem_I8:
				case ILCode.Ldelem_U1:
				case ILCode.Ldelem_U2:
				case ILCode.Ldelem_U4:
				case ILCode.Ldelem_R4:
				case ILCode.Ldelem_R8:
				case ILCode.Ldelem_Ref:
				case ILCode.Ldelem_Any:
					return arg1.Indexer(arg2);
					case ILCode.Ldelema: return MakeRef(arg1.Indexer(arg2));
				case ILCode.Stelem_I:
				case ILCode.Stelem_I1:
				case ILCode.Stelem_I2:
				case ILCode.Stelem_I4:
				case ILCode.Stelem_I8:
				case ILCode.Stelem_R4:
				case ILCode.Stelem_R8:
				case ILCode.Stelem_Ref:
				case ILCode.Stelem_Any:
					return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
					#endregion
					#region Comparison
					case ILCode.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
					case ILCode.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					case ILCode.Cgt_Un: {
						// can also mean Inequality, when used with object references
						TypeReference arg1Type = byteCode.Arguments[0].InferredType;
						if (arg1Type != null && !arg1Type.IsValueType)
							return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
						else
							return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					}
					case ILCode.Clt:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					case ILCode.Clt_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					#endregion
					#region Logical
					case ILCode.LogicNot:   return new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1);
					case ILCode.LogicAnd:   return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalAnd, arg2);
					case ILCode.LogicOr:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalOr, arg2);
					case ILCode.TernaryOp:  return new Ast.ConditionalExpression() { Condition = arg1, TrueExpression = arg2, FalseExpression = arg3 };
					case ILCode.NullCoalescing: 	return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.NullCoalescing, arg2);
					#endregion
					#region Branch
					case ILCode.Br:         return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
				case ILCode.Brtrue:
					return new Ast.IfElseStatement() {
						Condition = arg1,
						TrueStatement = new BlockStatement() {
							new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
						}
					};
					case ILCode.LoopOrSwitchBreak: return new Ast.BreakStatement();
					case ILCode.LoopContinue:      return new Ast.ContinueStatement();
					#endregion
					#region Conversions
				case ILCode.Conv_I1:
				case ILCode.Conv_I2:
				case ILCode.Conv_I4:
				case ILCode.Conv_I8:
				case ILCode.Conv_U1:
				case ILCode.Conv_U2:
				case ILCode.Conv_U4:
				case ILCode.Conv_U8:
				case ILCode.Conv_I:
				case ILCode.Conv_U:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);
						}
						return arg1;
					}
					case ILCode.Conv_R4:   return arg1.CastTo(typeof(float));
					case ILCode.Conv_R8:   return arg1.CastTo(typeof(double));
					case ILCode.Conv_R_Un: return arg1.CastTo(typeof(double)); // TODO
				case ILCode.Conv_Ovf_I1:
				case ILCode.Conv_Ovf_I2:
				case ILCode.Conv_Ovf_I4:
				case ILCode.Conv_Ovf_I8:
				case ILCode.Conv_Ovf_U1:
				case ILCode.Conv_Ovf_U2:
				case ILCode.Conv_Ovf_U4:
				case ILCode.Conv_Ovf_U8:
				case ILCode.Conv_Ovf_I1_Un:
				case ILCode.Conv_Ovf_I2_Un:
				case ILCode.Conv_Ovf_I4_Un:
				case ILCode.Conv_Ovf_I8_Un:
				case ILCode.Conv_Ovf_U1_Un:
				case ILCode.Conv_Ovf_U2_Un:
				case ILCode.Conv_Ovf_U4_Un:
				case ILCode.Conv_Ovf_U8_Un:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);
						}
						return arg1;
					}
					case ILCode.Conv_Ovf_I:     return arg1.CastTo(typeof(IntPtr)); // TODO
					case ILCode.Conv_Ovf_U:     return arg1.CastTo(typeof(UIntPtr));
					case ILCode.Conv_Ovf_I_Un:  return arg1.CastTo(typeof(IntPtr));
					case ILCode.Conv_Ovf_U_Un:  return arg1.CastTo(typeof(UIntPtr));
					case ILCode.Castclass:      return arg1.CastTo(operandAsTypeRef);
					case ILCode.Unbox_Any:      return arg1.CastTo(operandAsTypeRef);
					case ILCode.Isinst:         return arg1.CastAs(operandAsTypeRef);
					case ILCode.Box:            return arg1;
					case ILCode.Unbox:          return InlineAssembly(byteCode, args);
					#endregion
					#region Indirect
				case ILCode.Ldind_Ref:
				case ILCode.Ldobj:
					if (arg1 is DirectionExpression)
						return ((DirectionExpression)arg1).Expression.Detach();
					else
						return new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1);
				case ILCode.Stind_Ref:
				case ILCode.Stobj:
					if (arg1 is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)arg1).Expression.Detach(), arg2);
					else
						return new AssignmentExpression(new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1), arg2);
					#endregion
					case ILCode.Arglist:  return InlineAssembly(byteCode, args);
					case ILCode.Break:    return InlineAssembly(byteCode, args);
					case ILCode.Call:     return TransformCall(false, operand, methodDef, args);
					case ILCode.Callvirt: return TransformCall(true, operand, methodDef, args);
					case ILCode.Ldftn: {
						Cecil.MethodReference cecilMethod = ((MethodReference)operand);
						var expr = new Ast.IdentifierExpression(cecilMethod.Name);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return new IdentifierExpression("ldftn").Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(false));
					}
					case ILCode.Ldvirtftn: {
						Cecil.MethodReference cecilMethod = ((MethodReference)operand);
						var expr = new Ast.IdentifierExpression(cecilMethod.Name);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return new IdentifierExpression("ldvirtftn").Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true));
					}
					case ILCode.Calli:       return InlineAssembly(byteCode, args);
					case ILCode.Ckfinite:    return InlineAssembly(byteCode, args);
					case ILCode.Constrained: return InlineAssembly(byteCode, args);
					case ILCode.Cpblk:       return InlineAssembly(byteCode, args);
					case ILCode.Cpobj:       return InlineAssembly(byteCode, args);
					case ILCode.Dup:         return arg1;
					case ILCode.Endfilter:   return InlineAssembly(byteCode, args);
					case ILCode.Endfinally:  return null;
					case ILCode.Initblk:     return InlineAssembly(byteCode, args);
				case ILCode.Initobj:
					if (args[0] is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)args[0]).Expression.Detach(), MakeDefaultValue((TypeReference)operand));
					else
						return InlineAssembly(byteCode, args);
				case ILCode.DefaultValue:
					return MakeDefaultValue((TypeReference)operand);
					case ILCode.Jmp: return InlineAssembly(byteCode, args);
					case ILCode.Ldc_I4: return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType);
					case ILCode.Ldc_I8: return AstBuilder.MakePrimitive((long)operand, byteCode.InferredType);
				case ILCode.Ldc_R4:
				case ILCode.Ldc_R8:
				case ILCode.Ldc_Decimal:
					return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand);
				case ILCode.Ldsfld:
					return AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand);
				case ILCode.Stfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return new AssignmentExpression(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand), arg2);
				case ILCode.Stsfld:
					return new AssignmentExpression(
						AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand),
						arg1);
					case ILCode.Ldflda:  return MakeRef(arg1.Member(((FieldReference) operand).Name).WithAnnotation(operand));
				case ILCode.Ldsflda:
					return MakeRef(
						AstBuilder.ConvertType(((FieldReference)operand).DeclaringType)
						.Member(((FieldReference)operand).Name).WithAnnotation(operand));
					case ILCode.Ldloc: {
						ILVariable v = (ILVariable)operand;
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						Expression expr;
						if (v.IsParameter && v.OriginalParameter.Index < 0)
							expr = new ThisReferenceExpression();
						else
							expr = new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand);
						return v.IsParameter && v.Type is ByReferenceType ? MakeRef(expr) : expr;
					}
					case ILCode.Ldloca: {
						ILVariable v = (ILVariable)operand;
						if (v.IsParameter && v.OriginalParameter.Index < 0)
							return MakeRef(new ThisReferenceExpression());
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						return MakeRef(new Ast.IdentifierExpression(((ILVariable)operand).Name).WithAnnotation(operand));
					}
					case ILCode.Ldnull: return new Ast.NullReferenceExpression();
					case ILCode.Ldstr:  return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldtoken:
					if (operand is Cecil.TypeReference) {
						return new Ast.TypeOfExpression { Type = operandAsTypeRef }.Member("TypeHandle");
					} else {
						return InlineAssembly(byteCode, args);
					}
					case ILCode.Leave:    return new GotoStatement() { Label = ((ILLabel)operand).Name };
				case ILCode.Localloc:
					{
						PointerType ptrType = byteCode.InferredType as PointerType;
						TypeReference type;
						if (ptrType != null) {
							type = ptrType.ElementType;
						} else {
							type = typeSystem.Byte;
						}
						return new StackAllocExpression {
							Type = AstBuilder.ConvertType(type),
							CountExpression = DivideBySize(arg1, type)
						};
					}
					case ILCode.Mkrefany: return InlineAssembly(byteCode, args);
					case ILCode.Newobj: {
						Cecil.TypeReference declaringType = ((MethodReference)operand).DeclaringType;
						if (declaringType is ArrayType) {
							ComposedType ct = AstBuilder.ConvertType((ArrayType)declaringType) as ComposedType;
							if (ct != null && ct.ArraySpecifiers.Count >= 1) {
								var ace = new Ast.ArrayCreateExpression();
								ct.ArraySpecifiers.First().Remove();
								ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
								ace.Type = ct;
								ace.Arguments.AddRange(args);
								return ace;
							}
						}
						var oce = new Ast.ObjectCreateExpression();
						oce.Type = AstBuilder.ConvertType(declaringType);
						oce.Arguments.AddRange(args);
						return oce.WithAnnotation(operand);
					}
					case ILCode.No: return InlineAssembly(byteCode, args);
					case ILCode.Nop: return null;
					case ILCode.Pop: return arg1;
					case ILCode.Readonly: return InlineAssembly(byteCode, args);
					case ILCode.Refanytype: return InlineAssembly(byteCode, args);
					case ILCode.Refanyval: return InlineAssembly(byteCode, args);
				case ILCode.Ret:
					if (methodDef.ReturnType.FullName != "System.Void") {
						return new Ast.ReturnStatement { Expression = arg1 };
					} else {
						return new Ast.ReturnStatement();
					}
					case ILCode.Rethrow: return new Ast.ThrowStatement();
					case ILCode.Sizeof:  return new Ast.SizeOfExpression { Type = operandAsTypeRef };
					case ILCode.Stloc: {
						ILVariable locVar = (ILVariable)operand;
						if (!locVar.IsParameter)
							localVariablesToDefine.Add(locVar);
						return new Ast.AssignmentExpression(new Ast.IdentifierExpression(locVar.Name).WithAnnotation(locVar), arg1);
					}
					case ILCode.Switch: return InlineAssembly(byteCode, args);
					case ILCode.Tail: return InlineAssembly(byteCode, args);
					case ILCode.Throw: return new Ast.ThrowStatement { Expression = arg1 };
					case ILCode.Unaligned: return InlineAssembly(byteCode, args);
					case ILCode.Volatile: return InlineAssembly(byteCode, args);
				case ILCode.YieldBreak:
					return new Ast.YieldBreakStatement();
				case ILCode.YieldReturn:
					return new Ast.YieldStatement { Expression = arg1 };
					case ILCode.InitCollection: {
						ObjectCreateExpression oce = (ObjectCreateExpression)arg1;
						oce.Initializer = new ArrayInitializerExpression();
						for (int i = 1; i < args.Count; i++) {
							ArrayInitializerExpression aie = args[i] as ArrayInitializerExpression;
							if (aie != null && aie.Elements.Count == 1)
								oce.Initializer.Elements.Add(aie.Elements.Single().Detach());
							else
								oce.Initializer.Elements.Add(args[i]);
						}
						return oce;
					}
					case ILCode.InitCollectionAddMethod: {
						var collectionInit = new ArrayInitializerExpression();
						collectionInit.Elements.AddRange(args);
						return collectionInit;
					}
					default: throw new Exception("Unknown OpCode: " + byteCode.Code);
			}
		}
Example #9
0
 public void VisitThisReferenceExpression(ThisReferenceExpression expression)
 {
     Formatter.StartNode(expression);
     Formatter.WriteKeyword("this");
     Formatter.EndNode();
 }
		public virtual object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data) {
			Debug.Assert((thisReferenceExpression != null));
			return null;
		}
Example #11
0
 public void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
 {
     JsonObject expression = CreateJsonExpression(thisReferenceExpression);
     Push(expression);
 }
Example #12
0
 public void VisitThisReferenceExpression(ThisReferenceExpression node)
 {
     VisitChildren(node);
 }
		public virtual object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data) {
			throw new global::System.NotImplementedException("ThisReferenceExpression");
		}
Example #14
0
        private void PrimaryExpr(out Expression pexpr)
        {
            TypeReference typeReference = null;
            List<TypeReference> types = null;
            Expression expression;
            bool flag = false;
            pexpr = null;
            if (this.la.kind == 0x70)
            {
                base.lexer.NextToken();
                pexpr = new PrimitiveExpression(true, "true");
            }
            else if (this.la.kind == 0x47)
            {
                base.lexer.NextToken();
                pexpr = new PrimitiveExpression(false, "false");
            }
            else if (this.la.kind == 0x59)
            {
                base.lexer.NextToken();
                pexpr = new PrimitiveExpression(null, "null");
            }
            else if (this.la.kind == 2)
            {
                base.lexer.NextToken();
                pexpr = new PrimitiveExpression(this.t.literalValue, this.t.val);
            }
            else if ((this.la.kind == 1) && (this.Peek(1).kind == 10))
            {
                base.Expect(1);
                typeReference = new TypeReference(this.t.val);
                base.Expect(10);
                pexpr = new TypeReferenceExpression(typeReference);
                base.Expect(1);
                if (typeReference.Type == "global")
                {
                    typeReference.IsGlobal = true;
                    typeReference.Type = this.t.val ?? "?";
                }
                else
                {
                    typeReference.Type = typeReference.Type + "." + (this.t.val ?? "?");
                }
            }
            else if (this.la.kind == 1)
            {
                base.lexer.NextToken();
                pexpr = new IdentifierExpression(this.t.val);
            }
            else if (this.la.kind == 20)
            {
                base.lexer.NextToken();
                this.Expr(out expression);
                base.Expect(0x15);
                pexpr = new ParenthesizedExpression(expression);
            }
            else if (!this.StartOf(0x1a))
            {
                if (this.la.kind == 110)
                {
                    base.lexer.NextToken();
                    pexpr = new ThisReferenceExpression();
                }
                else if (this.la.kind == 50)
                {
                    base.lexer.NextToken();
                    Expression targetObject = new BaseReferenceExpression();
                    if (this.la.kind == 15)
                    {
                        base.lexer.NextToken();
                        base.Expect(1);
                        targetObject = new FieldReferenceExpression(targetObject, this.t.val);
                    }
                    else if (this.la.kind == 0x12)
                    {
                        base.lexer.NextToken();
                        this.Expr(out expression);
                        List<Expression> indices = new List<Expression>();
                        if (expression != null)
                        {
                            indices.Add(expression);
                        }
                        while (this.la.kind == 14)
                        {
                            base.lexer.NextToken();
                            this.Expr(out expression);
                            if (expression != null)
                            {
                                indices.Add(expression);
                            }
                        }
                        base.Expect(0x13);
                        targetObject = new IndexerExpression(targetObject, indices);
                    }
                    else
                    {
                        base.SynErr(0xb3);
                    }
                    pexpr = targetObject;
                }
                else if (this.la.kind == 0x58)
                {
                    base.lexer.NextToken();
                    this.NonArrayType(out typeReference);
                    List<Expression> parameters = new List<Expression>();
                    if (this.la.kind == 20)
                    {
                        base.lexer.NextToken();
                        ObjectCreateExpression expression3 = new ObjectCreateExpression(typeReference, parameters);
                        if (this.StartOf(0x15))
                        {
                            this.Argument(out expression);
                            if (expression != null)
                            {
                                parameters.Add(expression);
                            }
                            while (this.la.kind == 14)
                            {
                                base.lexer.NextToken();
                                this.Argument(out expression);
                                if (expression != null)
                                {
                                    parameters.Add(expression);
                                }
                            }
                        }
                        base.Expect(0x15);
                        pexpr = expression3;
                    }
                    else if (this.la.kind == 0x12)
                    {
                        base.lexer.NextToken();
                        flag = true;
                        ArrayCreateExpression expression4 = new ArrayCreateExpression(typeReference);
                        pexpr = expression4;
                        int item = 0;
                        List<int> list4 = new List<int>();
                        if ((this.la.kind == 14) || (this.la.kind == 0x13))
                        {
                            while (this.la.kind == 14)
                            {
                                base.lexer.NextToken();
                                item++;
                            }
                            base.Expect(0x13);
                            list4.Add(item);
                            item = 0;
                            while (this.la.kind == 0x12)
                            {
                                base.lexer.NextToken();
                                while (this.la.kind == 14)
                                {
                                    base.lexer.NextToken();
                                    item++;
                                }
                                base.Expect(0x13);
                                list4.Add(item);
                                item = 0;
                            }
                            expression4.CreateType.RankSpecifier = list4.ToArray();
                            this.ArrayInitializer(out expression);
                            expression4.ArrayInitializer = (ArrayInitializerExpression) expression;
                        }
                        else if (this.StartOf(5))
                        {
                            this.Expr(out expression);
                            if (expression != null)
                            {
                                parameters.Add(expression);
                            }
                            while (this.la.kind == 14)
                            {
                                base.lexer.NextToken();
                                item++;
                                this.Expr(out expression);
                                if (expression != null)
                                {
                                    parameters.Add(expression);
                                }
                            }
                            base.Expect(0x13);
                            list4.Add(item);
                            expression4.Arguments = parameters;
                            for (item = 0; this.la.kind == 0x12; item = 0)
                            {
                                base.lexer.NextToken();
                                while (this.la.kind == 14)
                                {
                                    base.lexer.NextToken();
                                    item++;
                                }
                                base.Expect(0x13);
                                list4.Add(item);
                            }
                            expression4.CreateType.RankSpecifier = list4.ToArray();
                            if (this.la.kind == 0x10)
                            {
                                this.ArrayInitializer(out expression);
                                expression4.ArrayInitializer = (ArrayInitializerExpression) expression;
                            }
                        }
                        else
                        {
                            base.SynErr(180);
                        }
                    }
                    else
                    {
                        base.SynErr(0xb5);
                    }
                }
                else if (this.la.kind == 0x72)
                {
                    base.lexer.NextToken();
                    base.Expect(20);
                    if (this.NotVoidPointer())
                    {
                        base.Expect(0x7a);
                        typeReference = new TypeReference("void");
                    }
                    else if (this.StartOf(9))
                    {
                        this.TypeWithRestriction(out typeReference, true, true);
                    }
                    else
                    {
                        base.SynErr(0xb6);
                    }
                    base.Expect(0x15);
                    pexpr = new TypeOfExpression(typeReference);
                }
                else if ((this.la.kind == 0x3e) && (this.Peek(1).kind == 20))
                {
                    base.Expect(0x3e);
                    base.Expect(20);
                    this.Type(out typeReference);
                    base.Expect(0x15);
                    pexpr = new DefaultValueExpression(typeReference);
                }
                else if (this.la.kind == 0x68)
                {
                    base.lexer.NextToken();
                    base.Expect(20);
                    this.Type(out typeReference);
                    base.Expect(0x15);
                    pexpr = new SizeOfExpression(typeReference);
                }
                else if (this.la.kind == 0x39)
                {
                    base.lexer.NextToken();
                    base.Expect(20);
                    this.Expr(out expression);
                    base.Expect(0x15);
                    pexpr = new CheckedExpression(expression);
                }
                else if (this.la.kind == 0x75)
                {
                    base.lexer.NextToken();
                    base.Expect(20);
                    this.Expr(out expression);
                    base.Expect(0x15);
                    pexpr = new UncheckedExpression(expression);
                }
                else if (this.la.kind == 0x3f)
                {
                    base.lexer.NextToken();
                    this.AnonymousMethodExpr(out expression);
                    pexpr = expression;
                }
                else
                {
                    base.SynErr(0xb7);
                }
            }
            else
            {
                string typeName = null;
                switch (this.la.kind)
                {
                    case 0x3d:
                        base.lexer.NextToken();
                        typeName = "decimal";
                        break;

                    case 0x41:
                        base.lexer.NextToken();
                        typeName = "double";
                        break;

                    case 0x4a:
                        base.lexer.NextToken();
                        typeName = "float";
                        break;

                    case 0x33:
                        base.lexer.NextToken();
                        typeName = "bool";
                        break;

                    case 0x35:
                        base.lexer.NextToken();
                        typeName = "byte";
                        break;

                    case 0x38:
                        base.lexer.NextToken();
                        typeName = "char";
                        break;

                    case 0x51:
                        base.lexer.NextToken();
                        typeName = "int";
                        break;

                    case 0x56:
                        base.lexer.NextToken();
                        typeName = "long";
                        break;

                    case 90:
                        base.lexer.NextToken();
                        typeName = "object";
                        break;

                    case 0x65:
                        base.lexer.NextToken();
                        typeName = "sbyte";
                        break;

                    case 0x67:
                        base.lexer.NextToken();
                        typeName = "short";
                        break;

                    case 0x6b:
                        base.lexer.NextToken();
                        typeName = "string";
                        break;

                    case 0x73:
                        base.lexer.NextToken();
                        typeName = "uint";
                        break;

                    case 0x74:
                        base.lexer.NextToken();
                        typeName = "ulong";
                        break;

                    case 0x77:
                        base.lexer.NextToken();
                        typeName = "ushort";
                        break;
                }
                this.t.val = "";
                base.Expect(15);
                base.Expect(1);
                pexpr = new FieldReferenceExpression(new TypeReferenceExpression(typeName), this.t.val);
            }
            while ((this.StartOf(0x1b) || (this.IsGenericFollowedBy(15) && this.IsTypeReferenceExpression(pexpr))) || this.IsGenericFollowedBy(20))
            {
                if ((this.la.kind == 0x1f) || (this.la.kind == 0x20))
                {
                    if (this.la.kind == 0x1f)
                    {
                        base.lexer.NextToken();
                        pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostIncrement);
                    }
                    else if (this.la.kind == 0x20)
                    {
                        base.lexer.NextToken();
                        pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostDecrement);
                    }
                    else
                    {
                        base.SynErr(0xb8);
                    }
                }
                else
                {
                    if (this.la.kind == 0x2f)
                    {
                        base.lexer.NextToken();
                        base.Expect(1);
                        pexpr = new PointerReferenceExpression(pexpr, this.t.val);
                        continue;
                    }
                    if (this.la.kind == 15)
                    {
                        base.lexer.NextToken();
                        base.Expect(1);
                        pexpr = new FieldReferenceExpression(pexpr, this.t.val);
                        continue;
                    }
                    if (this.IsGenericFollowedBy(15) && this.IsTypeReferenceExpression(pexpr))
                    {
                        this.TypeArgumentList(out types, false);
                        base.Expect(15);
                        base.Expect(1);
                        pexpr = new FieldReferenceExpression(this.GetTypeReferenceExpression(pexpr, types), this.t.val);
                        continue;
                    }
                    if (this.la.kind == 20)
                    {
                        base.lexer.NextToken();
                        List<Expression> arguments = new List<Expression>();
                        if (this.StartOf(0x15))
                        {
                            this.Argument(out expression);
                            if (expression != null)
                            {
                                arguments.Add(expression);
                            }
                            while (this.la.kind == 14)
                            {
                                base.lexer.NextToken();
                                this.Argument(out expression);
                                if (expression != null)
                                {
                                    arguments.Add(expression);
                                }
                            }
                        }
                        base.Expect(0x15);
                        pexpr = new InvocationExpression(pexpr, arguments);
                        continue;
                    }
                    if (this.IsGenericFollowedBy(20))
                    {
                        this.TypeArgumentList(out types, false);
                        base.Expect(20);
                        List<Expression> list6 = new List<Expression>();
                        if (this.StartOf(0x15))
                        {
                            this.Argument(out expression);
                            if (expression != null)
                            {
                                list6.Add(expression);
                            }
                            while (this.la.kind == 14)
                            {
                                base.lexer.NextToken();
                                this.Argument(out expression);
                                if (expression != null)
                                {
                                    list6.Add(expression);
                                }
                            }
                        }
                        base.Expect(0x15);
                        pexpr = new InvocationExpression(pexpr, list6, types);
                        continue;
                    }
                    if (flag)
                    {
                        this.Error("element access not allow on array creation");
                    }
                    List<Expression> list7 = new List<Expression>();
                    base.lexer.NextToken();
                    this.Expr(out expression);
                    if (expression != null)
                    {
                        list7.Add(expression);
                    }
                    while (this.la.kind == 14)
                    {
                        base.lexer.NextToken();
                        this.Expr(out expression);
                        if (expression != null)
                        {
                            list7.Add(expression);
                        }
                    }
                    base.Expect(0x13);
                    pexpr = new IndexerExpression(pexpr, list7);
                }
            }
        }
		public sealed override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data) {
			BeginVisit(thisReferenceExpression);
			object result = TrackedVisitThisReferenceExpression(thisReferenceExpression, data);
			EndVisit(thisReferenceExpression);
			return result;
		}
 public override object Visit(ThisReferenceExpression thisReferenceExpression, object data)
 {
     if (resolver.CallingClass == null) {
         return null;
     }
     return new ReturnType(resolver.CallingClass.FullyQualifiedName);
 }
Example #17
0
 public ThisReferenceBlock(IEmitter emitter, ThisReferenceExpression thisReferenceExpression)
     : base(emitter, thisReferenceExpression)
 {
     this.Emitter = emitter;
     this.ThisReferenceExpression = thisReferenceExpression;
 }
Example #18
0
		AstNode TransformByteCode(ILExpression byteCode)
		{
			object operand = byteCode.Operand;
			AstType operandAsTypeRef = AstBuilder.ConvertType(operand as ITypeDefOrRef);

			List<Ast.Expression> args = new List<Expression>();
			foreach(ILExpression arg in byteCode.Arguments) {
				args.Add((Ast.Expression)TransformExpression(arg));
			}
			Ast.Expression arg1 = args.Count >= 1 ? args[0] : null;
			Ast.Expression arg2 = args.Count >= 2 ? args[1] : null;
			Ast.Expression arg3 = args.Count >= 3 ? args[2] : null;
			
			switch (byteCode.Code) {
					#region Arithmetic
				case ILCode.Add:
				case ILCode.Add_Ovf:
				case ILCode.Add_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PtrSig) {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
							if (byteCode.Arguments[0].ExpectedType is PtrSig ||
								byteCode.Arguments[1].ExpectedType is PtrSig) {
								boe.AddAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Add, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Add ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
				case ILCode.Sub:
				case ILCode.Sub_Ovf:
				case ILCode.Sub_Ovf_Un:
					{
						BinaryOperatorExpression boe;
						if (byteCode.InferredType is PtrSig) {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
							if (byteCode.Arguments[0].ExpectedType is PtrSig) {
								boe.WithAnnotation(IntroduceUnsafeModifier.PointerArithmeticAnnotation);
							}
						} else {
							boe = new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Subtract, arg2);
						}
						boe.AddAnnotation(byteCode.Code == ILCode.Sub ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return boe;
					}
					case ILCode.Div:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Div_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Divide, arg2);
					case ILCode.Mul:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Mul_Ovf:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Mul_Ovf_Un: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Multiply, arg2).WithAnnotation(AddCheckedBlocks.CheckedAnnotation);
					case ILCode.Rem:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.Rem_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Modulus, arg2);
					case ILCode.And:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseAnd, arg2);
					case ILCode.Or:         return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.BitwiseOr, arg2);
					case ILCode.Xor:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ExclusiveOr, arg2);
					case ILCode.Shl:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftLeft, arg2);
					case ILCode.Shr:        return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Shr_Un:     return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ShiftRight, arg2);
					case ILCode.Neg:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.Minus, arg1).WithAnnotation(AddCheckedBlocks.UncheckedAnnotation);
					case ILCode.Not:        return new Ast.UnaryOperatorExpression(UnaryOperatorType.BitNot, arg1);
				case ILCode.PostIncrement:
				case ILCode.PostIncrement_Ovf:
				case ILCode.PostIncrement_Ovf_Un:
					{
						if (arg1 is DirectionExpression)
							arg1 = ((DirectionExpression)arg1).Expression.Detach();
						var uoe = new Ast.UnaryOperatorExpression(
							(int)byteCode.Operand > 0 ? UnaryOperatorType.PostIncrement : UnaryOperatorType.PostDecrement, arg1);
						uoe.AddAnnotation((byteCode.Code == ILCode.PostIncrement) ? AddCheckedBlocks.UncheckedAnnotation : AddCheckedBlocks.CheckedAnnotation);
						return uoe;
					}
					#endregion
					#region Arrays
					case ILCode.Newarr: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						if (ct != null) {
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
						}
						if (byteCode.Code == ILCode.InitArray) {
							ace.Initializer = new ArrayInitializerExpression();
							ace.Initializer.Elements.AddRange(args);
						} else {
							ace.Arguments.Add(arg1);
						}
						return ace;
					}
					case ILCode.InitArray: {
						var ace = new Ast.ArrayCreateExpression();
						ace.Type = operandAsTypeRef;
						ComposedType ct = operandAsTypeRef as ComposedType;
						if (ct != null)
						{
							// change "new (int[,])[10] to new int[10][,]"
							ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
							ace.Initializer = new ArrayInitializerExpression();
						}
						var arySig = ((TypeSpec)operand).TypeSig.RemovePinnedAndModifiers() as ArraySigBase;
						if (arySig == null) {
						}
						else if (arySig.IsSingleDimensional)
						{
							ace.Initializer.Elements.AddRange(args);
						}
						else
						{
							var newArgs = new List<Expression>();
							foreach (var length in arySig.GetLengths().Skip(1).Reverse())
							{
								for (int j = 0; j < args.Count; j += length)
								{
									var child = new ArrayInitializerExpression();
									child.Elements.AddRange(args.GetRange(j, length));
									newArgs.Add(child);
								}
								var temp = args;
								args = newArgs;
								newArgs = temp;
								newArgs.Clear();
							}
							ace.Initializer.Elements.AddRange(args);
						}
						return ace;
					}
					case ILCode.Ldlen: return arg1.Member("Length", TextTokenType.InstanceProperty).WithAnnotation(Create_SystemArray_get_Length());
				case ILCode.Ldelem_I:
				case ILCode.Ldelem_I1:
				case ILCode.Ldelem_I2:
				case ILCode.Ldelem_I4:
				case ILCode.Ldelem_I8:
				case ILCode.Ldelem_U1:
				case ILCode.Ldelem_U2:
				case ILCode.Ldelem_U4:
				case ILCode.Ldelem_R4:
				case ILCode.Ldelem_R8:
				case ILCode.Ldelem_Ref:
				case ILCode.Ldelem:
					return arg1.Indexer(arg2);
				case ILCode.Ldelema:
					return MakeRef(arg1.Indexer(arg2));
				case ILCode.Stelem_I:
				case ILCode.Stelem_I1:
				case ILCode.Stelem_I2:
				case ILCode.Stelem_I4:
				case ILCode.Stelem_I8:
				case ILCode.Stelem_R4:
				case ILCode.Stelem_R8:
				case ILCode.Stelem_Ref:
				case ILCode.Stelem:
					return new Ast.AssignmentExpression(arg1.Indexer(arg2), arg3);
				case ILCode.CompoundAssignment:
					{
						CastExpression cast = arg1 as CastExpression;
						var boe = cast != null ? (BinaryOperatorExpression)cast.Expression : arg1 as BinaryOperatorExpression;
						// AssignmentExpression doesn't support overloaded operators so they have to be processed to BinaryOperatorExpression
						if (boe == null) {
							var tmp = new ParenthesizedExpression(arg1);
							ReplaceMethodCallsWithOperators.ProcessInvocationExpression((InvocationExpression)arg1);
							boe = (BinaryOperatorExpression)tmp.Expression;
						}
						var assignment = new Ast.AssignmentExpression {
							Left = boe.Left.Detach(),
							Operator = ReplaceMethodCallsWithOperators.GetAssignmentOperatorForBinaryOperator(boe.Operator),
							Right = boe.Right.Detach()
						}.CopyAnnotationsFrom(boe);
						// We do not mark the resulting assignment as RestoreOriginalAssignOperatorAnnotation, because
						// the operator cannot be translated back to the expanded form (as the left-hand expression
						// would be evaluated twice, and might have side-effects)
						if (cast != null) {
							cast.Expression = assignment;
							return cast;
						} else {
							return assignment;
						}
					}
					#endregion
					#region Comparison
					case ILCode.Ceq: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.Equality, arg2);
					case ILCode.Cne: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.InEquality, arg2);
					case ILCode.Cgt: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThan, arg2);
					case ILCode.Cgt_Un: {
						// can also mean Inequality, when used with object references
						TypeSig arg1Type = byteCode.Arguments[0].InferredType;
						if (arg1Type != null && !DnlibExtensions.IsValueType(arg1Type)) goto case ILCode.Cne;

						// when comparing signed integral values using Cgt_Un with 0
						// the Ast should actually contain InEquality since "(uint)a > 0u" is identical to "a != 0"
						if (arg1Type.IsSignedIntegralType())
						{
							var p = arg2 as Ast.PrimitiveExpression;
							if (p != null && p.Value.IsZero()) goto case ILCode.Cne;
						}

						goto case ILCode.Cgt;
					}
					case ILCode.Cle_Un: {
						// can also mean Equality, when used with object references
						TypeSig arg1Type = byteCode.Arguments[0].InferredType;
						if (arg1Type != null && !DnlibExtensions.IsValueType(arg1Type)) goto case ILCode.Ceq;

						// when comparing signed integral values using Cle_Un with 0
						// the Ast should actually contain Equality since "(uint)a <= 0u" is identical to "a == 0"
						if (arg1Type.IsSignedIntegralType())
						{
							var p = arg2 as Ast.PrimitiveExpression;
							if (p != null && p.Value.IsZero()) goto case ILCode.Ceq;
						}

						goto case ILCode.Cle;
					}
					case ILCode.Cle: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThanOrEqual, arg2);
				case ILCode.Cge_Un:
					case ILCode.Cge: return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.GreaterThanOrEqual, arg2);
				case ILCode.Clt_Un:
					case ILCode.Clt:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.LessThan, arg2);
					#endregion
					#region Logical
					case ILCode.LogicNot:   return new Ast.UnaryOperatorExpression(UnaryOperatorType.Not, arg1);
					case ILCode.LogicAnd:   return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalAnd, arg2);
					case ILCode.LogicOr:    return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.ConditionalOr, arg2);
					case ILCode.TernaryOp:  return new Ast.ConditionalExpression() { Condition = arg1, TrueExpression = arg2, FalseExpression = arg3 };
					case ILCode.NullCoalescing: 	return new Ast.BinaryOperatorExpression(arg1, BinaryOperatorType.NullCoalescing, arg2);
					#endregion
					#region Branch
					case ILCode.Br:         return new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name);
				case ILCode.Brtrue:
					return new Ast.IfElseStatement() {
						Condition = arg1,
						TrueStatement = new BlockStatement() {
							new Ast.GotoStatement(((ILLabel)byteCode.Operand).Name)
						}
					};
					case ILCode.LoopOrSwitchBreak: return new Ast.BreakStatement();
					case ILCode.LoopContinue:      return new Ast.ContinueStatement();
					#endregion
					#region Conversions
				case ILCode.Conv_I1:
				case ILCode.Conv_I2:
				case ILCode.Conv_I4:
				case ILCode.Conv_I8:
				case ILCode.Conv_U1:
				case ILCode.Conv_U2:
				case ILCode.Conv_U4:
				case ILCode.Conv_U8:
				case ILCode.Conv_I:
				case ILCode.Conv_U:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.UncheckedAnnotation);
						}
						return arg1;
					}
				case ILCode.Conv_R4:
				case ILCode.Conv_R8:
				case ILCode.Conv_R_Un: // TODO
					return arg1;
				case ILCode.Conv_Ovf_I1:
				case ILCode.Conv_Ovf_I2:
				case ILCode.Conv_Ovf_I4:
				case ILCode.Conv_Ovf_I8:
				case ILCode.Conv_Ovf_U1:
				case ILCode.Conv_Ovf_U2:
				case ILCode.Conv_Ovf_U4:
				case ILCode.Conv_Ovf_U8:
				case ILCode.Conv_Ovf_I1_Un:
				case ILCode.Conv_Ovf_I2_Un:
				case ILCode.Conv_Ovf_I4_Un:
				case ILCode.Conv_Ovf_I8_Un:
				case ILCode.Conv_Ovf_U1_Un:
				case ILCode.Conv_Ovf_U2_Un:
				case ILCode.Conv_Ovf_U4_Un:
				case ILCode.Conv_Ovf_U8_Un:
				case ILCode.Conv_Ovf_I:
				case ILCode.Conv_Ovf_U:
				case ILCode.Conv_Ovf_I_Un:
				case ILCode.Conv_Ovf_U_Un:
					{
						// conversion was handled by Convert() function using the info from type analysis
						CastExpression cast = arg1 as CastExpression;
						if (cast != null) {
							cast.AddAnnotation(AddCheckedBlocks.CheckedAnnotation);
						}
						return arg1;
					}
				case ILCode.Unbox_Any:
					// unboxing does not require a cast if the argument was an isinst instruction
					if (arg1 is AsExpression && byteCode.Arguments[0].Code == ILCode.Isinst && TypeAnalysis.IsSameType(operand as ITypeDefOrRef, byteCode.Arguments[0].Operand as ITypeDefOrRef))
						return arg1;
					else
						goto case ILCode.Castclass;
				case ILCode.Castclass:
					if ((byteCode.Arguments[0].InferredType != null && byteCode.Arguments[0].InferredType.IsGenericParameter) || (operand as ITypeDefOrRef).TryGetGenericSig() != null)
						return arg1.CastTo(new PrimitiveType("object")).CastTo(operandAsTypeRef);
					else
						return arg1.CastTo(operandAsTypeRef);
				case ILCode.Isinst:
					return arg1.CastAs(operandAsTypeRef);
				case ILCode.Box:
					return arg1;
				case ILCode.Unbox:
					return MakeRef(arg1.CastTo(operandAsTypeRef));
					#endregion
					#region Indirect
				case ILCode.Ldind_Ref:
				case ILCode.Ldobj:
					if (arg1 is DirectionExpression)
						return ((DirectionExpression)arg1).Expression.Detach();
					else
						return new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1);
				case ILCode.Stind_Ref:
				case ILCode.Stobj:
					if (arg1 is DirectionExpression)
						return new AssignmentExpression(((DirectionExpression)arg1).Expression.Detach(), arg2);
					else
						return new AssignmentExpression(new UnaryOperatorExpression(UnaryOperatorType.Dereference, arg1), arg2);
					#endregion
				case ILCode.Arglist:
					return new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess };
					case ILCode.Break:    return InlineAssembly(byteCode, args);
				case ILCode.Call:
				case ILCode.CallGetter:
				case ILCode.CallSetter:
					return TransformCall(false, byteCode, args);
				case ILCode.Callvirt:
				case ILCode.CallvirtGetter:
				case ILCode.CallvirtSetter:
					return TransformCall(true, byteCode,  args);
					case ILCode.Ldftn: {
						IMethod cecilMethod = (IMethod)operand;
						var expr = Ast.IdentifierExpression.Create(cecilMethod.Name, cecilMethod);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return IdentifierExpression.Create("ldftn", TextTokenType.OpCode).Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(false));
					}
					case ILCode.Ldvirtftn: {
						IMethod cecilMethod = (IMethod)operand;
						var expr = Ast.IdentifierExpression.Create(cecilMethod.Name, cecilMethod);
						expr.TypeArguments.AddRange(ConvertTypeArguments(cecilMethod));
						expr.AddAnnotation(cecilMethod);
						return IdentifierExpression.Create("ldvirtftn", TextTokenType.OpCode).Invoke(expr)
							.WithAnnotation(new Transforms.DelegateConstruction.Annotation(true));
					}
					case ILCode.Calli:       return InlineAssembly(byteCode, args);
					case ILCode.Ckfinite:    return InlineAssembly(byteCode, args);
					case ILCode.Constrained: return InlineAssembly(byteCode, args);
					case ILCode.Cpblk:       return InlineAssembly(byteCode, args);
					case ILCode.Cpobj:       return InlineAssembly(byteCode, args);
					case ILCode.Dup:         return arg1;
					case ILCode.Endfilter:   return InlineAssembly(byteCode, args);
					case ILCode.Endfinally:  return null;
					case ILCode.Initblk:     return InlineAssembly(byteCode, args);
					case ILCode.Initobj:      return InlineAssembly(byteCode, args);
				case ILCode.DefaultValue:
					return MakeDefaultValue((operand as ITypeDefOrRef).ToTypeSig());
					case ILCode.Jmp: return InlineAssembly(byteCode, args);
				case ILCode.Ldc_I4:
						return AstBuilder.MakePrimitive((int)operand, byteCode.InferredType.ToTypeDefOrRef());
				case ILCode.Ldc_I8:
						return AstBuilder.MakePrimitive((long)operand, byteCode.InferredType.ToTypeDefOrRef());
				case ILCode.Ldc_R4:
				case ILCode.Ldc_R8:
				case ILCode.Ldc_Decimal:
					return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return arg1.Member(((IField) operand).Name, operand).WithAnnotation(operand);
				case ILCode.Ldsfld:
					return AstBuilder.ConvertType(((IField)operand).DeclaringType)
						.Member(((IField)operand).Name, operand).WithAnnotation(operand);
				case ILCode.Stfld:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return new AssignmentExpression(arg1.Member(((IField) operand).Name, operand).WithAnnotation(operand), arg2);
				case ILCode.Stsfld:
					return new AssignmentExpression(
						AstBuilder.ConvertType(((IField)operand).DeclaringType)
						.Member(((IField)operand).Name, operand).WithAnnotation(operand),
						arg1);
				case ILCode.Ldflda:
					if (arg1 is DirectionExpression)
						arg1 = ((DirectionExpression)arg1).Expression.Detach();
					return MakeRef(arg1.Member(((IField) operand).Name, operand).WithAnnotation(operand));
				case ILCode.Ldsflda:
					return MakeRef(
						AstBuilder.ConvertType(((IField)operand).DeclaringType)
						.Member(((IField)operand).Name, operand).WithAnnotation(operand));
					case ILCode.Ldloc: {
						ILVariable v = (ILVariable)operand;
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						Expression expr;
						if (v.IsParameter && v.OriginalParameter.IsHiddenThisParameter)
							expr = new ThisReferenceExpression().WithAnnotation(methodDef.DeclaringType);
						else
							expr = Ast.IdentifierExpression.Create(((ILVariable)operand).Name, ((ILVariable)operand).IsParameter ? TextTokenType.Parameter : TextTokenType.Local).WithAnnotation(operand);
						return v.IsParameter && v.Type is ByRefSig ? MakeRef(expr) : expr;
					}
					case ILCode.Ldloca: {
						ILVariable v = (ILVariable)operand;
						if (v.IsParameter && v.OriginalParameter.IsHiddenThisParameter)
							return MakeRef(new ThisReferenceExpression().WithAnnotation(methodDef.DeclaringType));
						if (!v.IsParameter)
							localVariablesToDefine.Add((ILVariable)operand);
						return MakeRef(Ast.IdentifierExpression.Create(((ILVariable)operand).Name, ((ILVariable)operand).IsParameter ? TextTokenType.Parameter : TextTokenType.Local).WithAnnotation(operand));
					}
					case ILCode.Ldnull: return new Ast.NullReferenceExpression();
					case ILCode.Ldstr:  return new Ast.PrimitiveExpression(operand);
				case ILCode.Ldtoken:
					if (operand is ITypeDefOrRef) {
						var th = Create_SystemType_get_TypeHandle();
						return AstBuilder.CreateTypeOfExpression((ITypeDefOrRef)operand).Member("TypeHandle", TextTokenType.InstanceProperty).WithAnnotation(th);
					} else {
						Expression referencedEntity;
						string loadName;
						string handleName;
						if (operand is IField && ((IField)operand).FieldSig != null) {
							loadName = "fieldof";
							handleName = "FieldHandle";
							IField fr = (IField)operand;
							referencedEntity = AstBuilder.ConvertType(fr.DeclaringType).Member(fr.Name, fr).WithAnnotation(fr);
						} else if (operand is IMethod) {
							loadName = "methodof";
							handleName = "MethodHandle";
							IMethod mr = (IMethod)operand;
							var methodParameters = mr.MethodSig.GetParameters().Select(p => new TypeReferenceExpression(AstBuilder.ConvertType(p)));
							referencedEntity = AstBuilder.ConvertType(mr.DeclaringType).Invoke(mr, mr.Name, methodParameters).WithAnnotation(mr);
						} else {
							loadName = "ldtoken";
							handleName = "Handle";
							var ie = IdentifierExpression.Create(FormatByteCodeOperand(byteCode.Operand), byteCode.Operand);
							ie.IdentifierToken.AddAnnotation(IdentifierEscaper.IdentifierFormatted);
							referencedEntity = ie;
						}
						return IdentifierExpression.Create(loadName, TextTokenType.Keyword).Invoke(referencedEntity).WithAnnotation(new LdTokenAnnotation()).Member(handleName, TextTokenType.InstanceProperty);
					}
					case ILCode.Leave:    return new GotoStatement() { Label = ((ILLabel)operand).Name };
				case ILCode.Localloc:
					{
						PtrSig ptrType = byteCode.InferredType as PtrSig;
						TypeSig type;
						if (ptrType != null) {
							type = ptrType.Next;
						} else {
							type = corLib.Byte;
						}
						return new StackAllocExpression {
							Type = AstBuilder.ConvertType(type),
                            CountExpression = arg1
						};
					}
				case ILCode.Mkrefany:
					{
						DirectionExpression dir = arg1 as DirectionExpression;
						if (dir != null) {
							return new UndocumentedExpression {
								UndocumentedExpressionType = UndocumentedExpressionType.MakeRef,
								Arguments = { dir.Expression.Detach() }
							};
						} else {
							return InlineAssembly(byteCode, args);
						}
					}
				case ILCode.Refanytype:
					return new UndocumentedExpression {
						UndocumentedExpressionType = UndocumentedExpressionType.RefType,
						Arguments = { arg1 }
					}.Member("TypeHandle", TextTokenType.InstanceProperty).WithAnnotation(Create_SystemType_get_TypeHandle());
				case ILCode.Refanyval:
					return MakeRef(
						new UndocumentedExpression {
							UndocumentedExpressionType = UndocumentedExpressionType.RefValue,
							Arguments = { arg1, new TypeReferenceExpression(operandAsTypeRef) }
						});
					case ILCode.Newobj: {
						ITypeDefOrRef declaringType = ((IMethod)operand).DeclaringType;
						if (declaringType.TryGetSZArraySig() != null || declaringType.TryGetArraySig() != null) {
							ComposedType ct = AstBuilder.ConvertType(declaringType) as ComposedType;
							if (ct != null && ct.ArraySpecifiers.Count >= 1) {
								var ace = new Ast.ArrayCreateExpression();
								ct.ArraySpecifiers.First().Remove();
								ct.ArraySpecifiers.MoveTo(ace.AdditionalArraySpecifiers);
								ace.Type = ct;
								ace.Arguments.AddRange(args);
								return ace;
							}
						}
						if (declaringType.IsAnonymousType()) {
							MethodDef ctor = ((IMethod)operand).Resolve();
							if (methodDef != null) {
								AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
								if (CanInferAnonymousTypePropertyNamesFromArguments(args, ctor.Parameters)) {
									atce.Initializers.AddRange(args);
								} else {
									int skip = ctor.Parameters.GetParametersSkip();
									for (int i = 0; i < args.Count; i++) {
										atce.Initializers.Add(
											new NamedExpression {
												NameToken = Identifier.Create(ctor.Parameters[i + skip].Name).WithAnnotation(ctor.Parameters[i + skip]),
												Expression = args[i]
											});
									}
								}
								return atce;
							}
						}
						var oce = new Ast.ObjectCreateExpression();
						oce.Type = AstBuilder.ConvertType(declaringType);
						oce.Arguments.AddRange(args);
						return oce.WithAnnotation(operand);
					}
					case ILCode.No: return InlineAssembly(byteCode, args);
					case ILCode.Nop: return null;
					case ILCode.Pop: return arg1;
					case ILCode.Readonly: return InlineAssembly(byteCode, args);
				case ILCode.Ret:
					if (methodDef.ReturnType.GetFullName() != "System.Void") {
						return new Ast.ReturnStatement { Expression = arg1 };
					} else {
						return new Ast.ReturnStatement();
					}
					case ILCode.Rethrow: return new Ast.ThrowStatement();
					case ILCode.Sizeof:  return new Ast.SizeOfExpression { Type = operandAsTypeRef };
					case ILCode.Stloc: {
						ILVariable locVar = (ILVariable)operand;
						if (!locVar.IsParameter)
							localVariablesToDefine.Add(locVar);
						return new Ast.AssignmentExpression(Ast.IdentifierExpression.Create(locVar.Name, locVar.IsParameter ? TextTokenType.Parameter : TextTokenType.Local).WithAnnotation(locVar), arg1);
					}
					case ILCode.Switch: return InlineAssembly(byteCode, args);
					case ILCode.Tailcall: return InlineAssembly(byteCode, args);
					case ILCode.Throw: return new Ast.ThrowStatement { Expression = arg1 };
					case ILCode.Unaligned: return InlineAssembly(byteCode, args);
					case ILCode.Volatile: return InlineAssembly(byteCode, args);
				case ILCode.YieldBreak:
					return new Ast.YieldBreakStatement();
				case ILCode.YieldReturn:
					return new Ast.YieldReturnStatement { Expression = arg1 };
				case ILCode.InitObject:
				case ILCode.InitCollection:
					{
						ArrayInitializerExpression initializer = new ArrayInitializerExpression();
						for (int i = 1; i < args.Count; i++) {
							Match m = objectInitializerPattern.Match(args[i]);
							if (m.Success) {
								MemberReferenceExpression mre = m.Get<MemberReferenceExpression>("left").Single();
								initializer.Elements.Add(
									new NamedExpression {
										NameToken = (Identifier)mre.MemberNameToken.Clone(),
										Expression = m.Get<Expression>("right").Single().Detach()
									}.CopyAnnotationsFrom(mre));
							} else {
								m = collectionInitializerPattern.Match(args[i]);
								if (m.Success) {
									if (m.Get("arg").Count() == 1) {
										initializer.Elements.Add(m.Get<Expression>("arg").Single().Detach());
									} else {
										ArrayInitializerExpression argList = new ArrayInitializerExpression();
										foreach (var expr in m.Get<Expression>("arg")) {
											argList.Elements.Add(expr.Detach());
										}
										initializer.Elements.Add(argList);
									}
								} else {
									initializer.Elements.Add(args[i]);
								}
							}
						}
						ObjectCreateExpression oce = arg1 as ObjectCreateExpression;
						DefaultValueExpression dve = arg1 as DefaultValueExpression;
						if (oce != null) {
							oce.Initializer = initializer;
							return oce;
						} else if (dve != null) {
							oce = new ObjectCreateExpression(dve.Type.Detach());
							oce.CopyAnnotationsFrom(dve);
							oce.Initializer = initializer;
							return oce;
						} else {
							return new AssignmentExpression(arg1, initializer);
						}
					}
				case ILCode.InitializedObject:
					return new InitializedObjectExpression();
				case ILCode.Wrap:
					return arg1.WithAnnotation(PushNegation.LiftedOperatorAnnotation);
				case ILCode.AddressOf:
					return MakeRef(arg1);
				case ILCode.ExpressionTreeParameterDeclarations:
					args[args.Count - 1].AddAnnotation(new ParameterDeclarationAnnotation(byteCode));
					return args[args.Count - 1];
				case ILCode.Await:
					return new UnaryOperatorExpression(UnaryOperatorType.Await, UnpackDirectionExpression(arg1));
				case ILCode.NullableOf:
				case ILCode.ValueOf: 
					return arg1;
				default:
					throw new Exception("Unknown OpCode: " + byteCode.Code);
			}
		}
Example #19
0
	void PrimaryExpr(
#line  1862 "cs.ATG" 
out Expression pexpr) {

#line  1864 "cs.ATG" 
		TypeReference type = null;
		Expression expr;
		pexpr = null;
		

#line  1869 "cs.ATG" 
		Location startLocation = la.Location; 
		if (la.kind == 113) {
			lexer.NextToken();

#line  1871 "cs.ATG" 
			pexpr = new PrimitiveExpression(true, "true");  
		} else if (la.kind == 72) {
			lexer.NextToken();

#line  1872 "cs.ATG" 
			pexpr = new PrimitiveExpression(false, "false"); 
		} else if (la.kind == 90) {
			lexer.NextToken();

#line  1873 "cs.ATG" 
			pexpr = new PrimitiveExpression(null, "null");  
		} else if (la.kind == 2) {
			lexer.NextToken();

#line  1874 "cs.ATG" 
			pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
		} else if (
#line  1875 "cs.ATG" 
StartOfQueryExpression()) {
			QueryExpression(
#line  1876 "cs.ATG" 
out pexpr);
		} else if (
#line  1877 "cs.ATG" 
IdentAndDoubleColon()) {
			Identifier();

#line  1878 "cs.ATG" 
			type = new TypeReference(t.val); 
			Expect(10);

#line  1879 "cs.ATG" 
			pexpr = new TypeReferenceExpression(type); 
			Identifier();

#line  1880 "cs.ATG" 
			if (type.Type == "global") { type.IsGlobal = true; type.Type = t.val ?? "?"; } else type.Type += "." + (t.val ?? "?"); 
		} else if (StartOf(19)) {
			Identifier();

#line  1884 "cs.ATG" 
			pexpr = new IdentifierExpression(t.val); 
			if (la.kind == 48 || 
#line  1887 "cs.ATG" 
IsGenericInSimpleNameOrMemberAccess()) {
				if (la.kind == 48) {
					ShortedLambdaExpression(
#line  1886 "cs.ATG" 
(IdentifierExpression)pexpr, out pexpr);
				} else {

#line  1888 "cs.ATG" 
					List<TypeReference> typeList; 
					TypeArgumentList(
#line  1889 "cs.ATG" 
out typeList, false);

#line  1890 "cs.ATG" 
					((IdentifierExpression)pexpr).TypeArguments = typeList; 
				}
			}
		} else if (
#line  1892 "cs.ATG" 
IsLambdaExpression()) {
			LambdaExpression(
#line  1893 "cs.ATG" 
out pexpr);
		} else if (la.kind == 20) {
			lexer.NextToken();
			Expr(
#line  1896 "cs.ATG" 
out expr);
			Expect(21);

#line  1896 "cs.ATG" 
			pexpr = new ParenthesizedExpression(expr); 
		} else if (StartOf(35)) {

#line  1899 "cs.ATG" 
			string val = null; 
			switch (la.kind) {
			case 52: {
				lexer.NextToken();

#line  1900 "cs.ATG" 
				val = "System.Boolean"; 
				break;
			}
			case 54: {
				lexer.NextToken();

#line  1901 "cs.ATG" 
				val = "System.Byte"; 
				break;
			}
			case 57: {
				lexer.NextToken();

#line  1902 "cs.ATG" 
				val = "System.Char"; 
				break;
			}
			case 62: {
				lexer.NextToken();

#line  1903 "cs.ATG" 
				val = "System.Decimal"; 
				break;
			}
			case 66: {
				lexer.NextToken();

#line  1904 "cs.ATG" 
				val = "System.Double"; 
				break;
			}
			case 75: {
				lexer.NextToken();

#line  1905 "cs.ATG" 
				val = "System.Single"; 
				break;
			}
			case 82: {
				lexer.NextToken();

#line  1906 "cs.ATG" 
				val = "System.Int32"; 
				break;
			}
			case 87: {
				lexer.NextToken();

#line  1907 "cs.ATG" 
				val = "System.Int64"; 
				break;
			}
			case 91: {
				lexer.NextToken();

#line  1908 "cs.ATG" 
				val = "System.Object"; 
				break;
			}
			case 102: {
				lexer.NextToken();

#line  1909 "cs.ATG" 
				val = "System.SByte"; 
				break;
			}
			case 104: {
				lexer.NextToken();

#line  1910 "cs.ATG" 
				val = "System.Int16"; 
				break;
			}
			case 108: {
				lexer.NextToken();

#line  1911 "cs.ATG" 
				val = "System.String"; 
				break;
			}
			case 116: {
				lexer.NextToken();

#line  1912 "cs.ATG" 
				val = "System.UInt32"; 
				break;
			}
			case 117: {
				lexer.NextToken();

#line  1913 "cs.ATG" 
				val = "System.UInt64"; 
				break;
			}
			case 120: {
				lexer.NextToken();

#line  1914 "cs.ATG" 
				val = "System.UInt16"; 
				break;
			}
			case 123: {
				lexer.NextToken();

#line  1915 "cs.ATG" 
				val = "System.Void"; 
				break;
			}
			}

#line  1917 "cs.ATG" 
			pexpr = new TypeReferenceExpression(new TypeReference(val, true)) { StartLocation = t.Location, EndLocation = t.EndLocation }; 
		} else if (la.kind == 111) {
			lexer.NextToken();

#line  1920 "cs.ATG" 
			pexpr = new ThisReferenceExpression(); pexpr.StartLocation = t.Location; pexpr.EndLocation = t.EndLocation; 
		} else if (la.kind == 51) {
			lexer.NextToken();

#line  1922 "cs.ATG" 
			pexpr = new BaseReferenceExpression(); pexpr.StartLocation = t.Location; pexpr.EndLocation = t.EndLocation; 
		} else if (la.kind == 89) {
			NewExpression(
#line  1925 "cs.ATG" 
out pexpr);
		} else if (la.kind == 115) {
			lexer.NextToken();
			Expect(20);
			if (
#line  1929 "cs.ATG" 
NotVoidPointer()) {
				Expect(123);

#line  1929 "cs.ATG" 
				type = new TypeReference("System.Void", true); 
			} else if (StartOf(10)) {
				TypeWithRestriction(
#line  1930 "cs.ATG" 
out type, true, true);
			} else SynErr(208);
			Expect(21);

#line  1932 "cs.ATG" 
			pexpr = new TypeOfExpression(type); 
		} else if (la.kind == 63) {
			lexer.NextToken();
			Expect(20);
			Type(
#line  1934 "cs.ATG" 
out type);
			Expect(21);

#line  1934 "cs.ATG" 
			pexpr = new DefaultValueExpression(type); 
		} else if (la.kind == 105) {
			lexer.NextToken();
			Expect(20);
			Type(
#line  1935 "cs.ATG" 
out type);
			Expect(21);

#line  1935 "cs.ATG" 
			pexpr = new SizeOfExpression(type); 
		} else if (la.kind == 58) {
			lexer.NextToken();
			Expect(20);
			Expr(
#line  1936 "cs.ATG" 
out expr);
			Expect(21);

#line  1936 "cs.ATG" 
			pexpr = new CheckedExpression(expr); 
		} else if (la.kind == 118) {
			lexer.NextToken();
			Expect(20);
			Expr(
#line  1937 "cs.ATG" 
out expr);
			Expect(21);

#line  1937 "cs.ATG" 
			pexpr = new UncheckedExpression(expr); 
		} else if (la.kind == 64) {
			lexer.NextToken();
			AnonymousMethodExpr(
#line  1938 "cs.ATG" 
out expr);

#line  1938 "cs.ATG" 
			pexpr = expr; 
		} else SynErr(209);

#line  1940 "cs.ATG" 
		if (pexpr != null) {
		if (pexpr.StartLocation.IsEmpty)
			pexpr.StartLocation = startLocation;
		if (pexpr.EndLocation.IsEmpty)
			pexpr.EndLocation = t.EndLocation;
		}
		
		while (StartOf(36)) {
			if (la.kind == 31 || la.kind == 32) {

#line  1948 "cs.ATG" 
				startLocation = la.Location; 
				if (la.kind == 31) {
					lexer.NextToken();

#line  1950 "cs.ATG" 
					pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostIncrement); 
				} else if (la.kind == 32) {
					lexer.NextToken();

#line  1951 "cs.ATG" 
					pexpr = new UnaryOperatorExpression(pexpr, UnaryOperatorType.PostDecrement); 
				} else SynErr(210);
			} else if (la.kind == 47) {
				PointerMemberAccess(
#line  1954 "cs.ATG" 
out pexpr, pexpr);
			} else if (la.kind == 15) {
				MemberAccess(
#line  1955 "cs.ATG" 
out pexpr, pexpr);
			} else if (la.kind == 20) {
				lexer.NextToken();

#line  1959 "cs.ATG" 
				List<Expression> parameters = new List<Expression>(); 

#line  1960 "cs.ATG" 
				pexpr = new InvocationExpression(pexpr, parameters); 
				if (StartOf(26)) {
					Argument(
#line  1961 "cs.ATG" 
out expr);

#line  1961 "cs.ATG" 
					SafeAdd(pexpr, parameters, expr); 
					while (la.kind == 14) {
						lexer.NextToken();
						Argument(
#line  1962 "cs.ATG" 
out expr);

#line  1962 "cs.ATG" 
						SafeAdd(pexpr, parameters, expr); 
					}
				}
				Expect(21);
			} else {

#line  1968 "cs.ATG" 
				List<Expression> indices = new List<Expression>();
				pexpr = new IndexerExpression(pexpr, indices);
				
				lexer.NextToken();
				Expr(
#line  1971 "cs.ATG" 
out expr);

#line  1971 "cs.ATG" 
				SafeAdd(pexpr, indices, expr); 
				while (la.kind == 14) {
					lexer.NextToken();
					Expr(
#line  1972 "cs.ATG" 
out expr);

#line  1972 "cs.ATG" 
					SafeAdd(pexpr, indices, expr); 
				}
				Expect(19);

#line  1975 "cs.ATG" 
				if (pexpr != null) {
				pexpr.StartLocation = startLocation;
				pexpr.EndLocation = t.EndLocation;
				}
				
			}
		}
	}
		public override void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
		{
			UsesNonStaticMember = true;
			base.VisitThisReferenceExpression(thisReferenceExpression);
		}
Example #21
0
	void SimpleNonInvocationExpression(
#line  1645 "VBNET.ATG" 
out Expression pexpr) {

#line  1647 "VBNET.ATG" 
		Expression expr;
		TypeReference type = null;
		string name = String.Empty;
		pexpr = null;
		
		if (StartOf(32)) {
			switch (la.kind) {
			case 3: {
				lexer.NextToken();

#line  1655 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
				break;
			}
			case 4: {
				lexer.NextToken();

#line  1656 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
				break;
			}
			case 7: {
				lexer.NextToken();

#line  1657 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
				break;
			}
			case 6: {
				lexer.NextToken();

#line  1658 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
				break;
			}
			case 5: {
				lexer.NextToken();

#line  1659 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
				break;
			}
			case 9: {
				lexer.NextToken();

#line  1660 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
				break;
			}
			case 8: {
				lexer.NextToken();

#line  1661 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(t.literalValue, t.val) { LiteralFormat = t.literalFormat };  
				break;
			}
			case 202: {
				lexer.NextToken();

#line  1663 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(true, "true");  
				break;
			}
			case 109: {
				lexer.NextToken();

#line  1664 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(false, "false"); 
				break;
			}
			case 151: {
				lexer.NextToken();

#line  1665 "VBNET.ATG" 
				pexpr = new PrimitiveExpression(null, "null");  
				break;
			}
			case 25: {
				lexer.NextToken();
				Expr(
#line  1666 "VBNET.ATG" 
out expr);
				Expect(26);

#line  1666 "VBNET.ATG" 
				pexpr = new ParenthesizedExpression(expr); 
				break;
			}
			case 2: case 45: case 49: case 51: case 52: case 53: case 54: case 57: case 74: case 85: case 91: case 94: case 103: case 108: case 113: case 120: case 126: case 130: case 133: case 156: case 162: case 169: case 188: case 197: case 198: case 208: case 209: case 215: {
				Identifier();

#line  1668 "VBNET.ATG" 
				pexpr = new IdentifierExpression(t.val);
				pexpr.StartLocation = t.Location; pexpr.EndLocation = t.EndLocation;
				
				if (
#line  1671 "VBNET.ATG" 
la.kind == Tokens.OpenParenthesis && Peek(1).kind == Tokens.Of) {
					lexer.NextToken();
					Expect(155);
					TypeArgumentList(
#line  1672 "VBNET.ATG" 
((IdentifierExpression)pexpr).TypeArguments);
					Expect(26);
				}
				break;
			}
			case 55: case 58: case 69: case 86: case 87: case 96: case 128: case 137: case 154: case 181: case 186: case 187: case 193: case 206: case 207: case 210: {

#line  1674 "VBNET.ATG" 
				string val = String.Empty; 
				if (StartOf(11)) {
					PrimitiveTypeName(
#line  1675 "VBNET.ATG" 
out val);
				} else if (la.kind == 154) {
					lexer.NextToken();

#line  1675 "VBNET.ATG" 
					val = "System.Object"; 
				} else SynErr(257);

#line  1676 "VBNET.ATG" 
				pexpr = new TypeReferenceExpression(new TypeReference(val, true)); 
				break;
			}
			case 139: {
				lexer.NextToken();

#line  1677 "VBNET.ATG" 
				pexpr = new ThisReferenceExpression(); 
				break;
			}
			case 144: case 145: {

#line  1678 "VBNET.ATG" 
				Expression retExpr = null; 
				if (la.kind == 144) {
					lexer.NextToken();

#line  1679 "VBNET.ATG" 
					retExpr = new BaseReferenceExpression(); 
				} else if (la.kind == 145) {
					lexer.NextToken();

#line  1680 "VBNET.ATG" 
					retExpr = new ClassReferenceExpression(); 
				} else SynErr(258);
				Expect(16);
				IdentifierOrKeyword(
#line  1682 "VBNET.ATG" 
out name);

#line  1682 "VBNET.ATG" 
				pexpr = new MemberReferenceExpression(retExpr, name); 
				break;
			}
			case 117: {
				lexer.NextToken();
				Expect(16);
				Identifier();

#line  1684 "VBNET.ATG" 
				type = new TypeReference(t.val ?? ""); 

#line  1686 "VBNET.ATG" 
				type.IsGlobal = true; 

#line  1687 "VBNET.ATG" 
				pexpr = new TypeReferenceExpression(type); 
				break;
			}
			case 148: {
				ObjectCreateExpression(
#line  1688 "VBNET.ATG" 
out expr);

#line  1688 "VBNET.ATG" 
				pexpr = expr; 
				break;
			}
			case 81: case 93: case 204: {

#line  1690 "VBNET.ATG" 
				CastType castType = CastType.Cast; 
				if (la.kind == 93) {
					lexer.NextToken();
				} else if (la.kind == 81) {
					lexer.NextToken();

#line  1692 "VBNET.ATG" 
					castType = CastType.Conversion; 
				} else if (la.kind == 204) {
					lexer.NextToken();

#line  1693 "VBNET.ATG" 
					castType = CastType.TryCast; 
				} else SynErr(259);
				Expect(25);
				Expr(
#line  1695 "VBNET.ATG" 
out expr);
				Expect(12);
				TypeName(
#line  1695 "VBNET.ATG" 
out type);
				Expect(26);

#line  1696 "VBNET.ATG" 
				pexpr = new CastExpression(type, expr, castType); 
				break;
			}
			case 63: case 64: case 65: case 66: case 67: case 68: case 70: case 72: case 73: case 77: case 78: case 79: case 80: case 82: case 83: case 84: {
				CastTarget(
#line  1697 "VBNET.ATG" 
out type);
				Expect(25);
				Expr(
#line  1697 "VBNET.ATG" 
out expr);
				Expect(26);

#line  1697 "VBNET.ATG" 
				pexpr = new CastExpression(type, expr, CastType.PrimitiveConversion); 
				break;
			}
			case 44: {
				lexer.NextToken();
				Expr(
#line  1698 "VBNET.ATG" 
out expr);

#line  1698 "VBNET.ATG" 
				pexpr = new AddressOfExpression(expr); 
				break;
			}
			case 116: {
				lexer.NextToken();
				Expect(25);
				GetTypeTypeName(
#line  1699 "VBNET.ATG" 
out type);
				Expect(26);

#line  1699 "VBNET.ATG" 
				pexpr = new TypeOfExpression(type); 
				break;
			}
			case 205: {
				lexer.NextToken();
				SimpleExpr(
#line  1700 "VBNET.ATG" 
out expr);
				Expect(131);
				TypeName(
#line  1700 "VBNET.ATG" 
out type);

#line  1700 "VBNET.ATG" 
				pexpr = new TypeOfIsExpression(expr, type); 
				break;
			}
			case 122: {
				ConditionalExpression(
#line  1701 "VBNET.ATG" 
out pexpr);
				break;
			}
			}
		} else if (la.kind == 16) {
			lexer.NextToken();
			IdentifierOrKeyword(
#line  1705 "VBNET.ATG" 
out name);

#line  1705 "VBNET.ATG" 
			pexpr = new MemberReferenceExpression(null, name);
		} else SynErr(260);
	}
 public virtual void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
 {
     if (this.ThrowException)
     {
         throw (Exception)this.CreateException(thisReferenceExpression);
     }
 }
 public override StringBuilder VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, int data)
 {
     return null;
 }
		public virtual void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
		{
			VisitChildren (thisReferenceExpression);
		}
Example #25
0
 public override void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
 {
     new ThisReferenceBlock(this, thisReferenceExpression).Emit();
 }
Example #26
0
		public void VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression)
		{
			StartNode(thisReferenceExpression);
			WriteKeyword("this", thisReferenceExpression.Role);
			EndNode(thisReferenceExpression);
		}
		public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
		{
			return new CodeThisReferenceExpression();
		}