/// <summary> /// Retrieves the <see cref="ILVariable"/> associated with this <see cref="IdentifierExpression"/>, /// or <c>null</c> if no variable is associated with this identifier. /// </summary> public static ILVariable GetILVariable(this IdentifierExpression expr) { if (expr.Annotation <ResolveResult>() is ILVariableResolveResult rr) { return(rr.Variable); } else { return(null); } }
public static ILVariable GetILVariable(this IdentifierExpression expr) { var rr = expr.Annotation <ResolveResult>() as ILVariableResolveResult; if (rr != null) { return(rr.Variable); } else { return(null); } }
public override AstNode Emit() { var variable = _identifierExpression.Annotation <ILVariable>(); var variableReference = variable.OriginalVariable; if (variableReference != null) { var localBuilder = _locals[variableReference.Index]; Type = variable.Type.GetActualType(); ILGenerator.Emit(OpCodes.Ldloc, localBuilder); } return(new AstNodeDecorator(_identifierExpression, Type)); }
public override AstNode VisitIdentifierExpression(IdentifierExpression identifierExpression, ICecilArgumentsResolver argumentsResolver) { var variable = identifierExpression.Annotation <ILVariable>(); if (variable != null) { var variableType = variable.Type.GetGenericTypeOrSelfReference(); if (variableType.IsGenericParameter) { variable.Type = argumentsResolver.ResolveTypeReference(variableType.ToString()); } } return(identifierExpression); }
bool TryConvertAssignmentExpressionIntoVariableDeclaration(Expression expression, AstType type, string variableName) { AssignmentExpression ae = expression as AssignmentExpression; if (ae != null && ae.Operator == AssignmentOperatorType.Assign) { IdentifierExpression ident = ae.Left as IdentifierExpression; if (ident != null && ident.Identifier == variableName) { variablesToDeclare.Add(new VariableToDeclare { Type = type, Name = variableName, ILVariable = ident.Annotation <ILVariable>(), ReplacedAssignment = ae }); return(true); } } return(false); }
public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data) { // Console.WriteLine(objectCreateExpression.ToString()); if (objectCreateExpression.Arguments.Count == 2) { Expression obj = objectCreateExpression.Arguments.First(); Expression func = objectCreateExpression.Arguments.Last(); Annotation annotation = func.Annotation <Annotation>(); if (annotation != null) { IdentifierExpression methodIdent = (IdentifierExpression)((InvocationExpression)func).Arguments.Single(); MethodReference method = methodIdent.Annotation <MethodReference>(); if (method != null) { if (HandleAnonymousMethod(objectCreateExpression, obj, method)) { // Console.WriteLine("is HandleAnonymousMethod"); return(null); } // Perform the transformation to "new Action(obj.func)". obj.Remove(); methodIdent.Remove(); if (!annotation.IsVirtual && obj is ThisReferenceExpression) { // maybe it's getting the pointer of a base method? if (method.DeclaringType.GetElementType() != context.CurrentType) { obj = new BaseReferenceExpression(); } } if (!annotation.IsVirtual && obj is NullReferenceExpression && !method.HasThis) { // We're loading a static method. // However it is possible to load extension methods with an instance, so we compare the number of arguments: bool isExtensionMethod = false; TypeReference delegateType = objectCreateExpression.Type.Annotation <TypeReference>(); if (delegateType != null) { TypeDefinition delegateTypeDef = delegateType.Resolve(); if (delegateTypeDef != null) { MethodDefinition invokeMethod = delegateTypeDef.Methods.FirstOrDefault(m => m.Name == "Invoke"); if (invokeMethod != null) { isExtensionMethod = (invokeMethod.Parameters.Count + 1 == method.Parameters.Count); } } } if (!isExtensionMethod) { obj = new TypeReferenceExpression { Type = AstBuilder.ConvertType(method.DeclaringType) }; } } // now transform the identifier into a member reference MemberReferenceExpression mre = new MemberReferenceExpression(); mre.Target = obj; mre.MemberName = methodIdent.Identifier; methodIdent.TypeArguments.MoveTo(mre.TypeArguments); mre.AddAnnotation(method); objectCreateExpression.Arguments.Clear(); objectCreateExpression.Arguments.Add(mre); return(null); } } } return(base.VisitObjectCreateExpression(objectCreateExpression, data)); }
Expression Convert(Expression expr) { InvocationExpression invocation = expr as InvocationExpression; if (invocation != null) { IMethod mr = invocation.Annotation <IMethod>(); if (mr != null && mr.DeclaringType != null && mr.DeclaringType.FullName == "System.Linq.Expressions.Expression") { switch (mr.Name) { case "Add": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Add, false)); case "AddChecked": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Add, true)); case "AddAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Add, false)); case "AddAssignChecked": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Add, true)); case "And": return(ConvertBinaryOperator(invocation, BinaryOperatorType.BitwiseAnd)); case "AndAlso": return(ConvertBinaryOperator(invocation, BinaryOperatorType.ConditionalAnd)); case "AndAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.BitwiseAnd)); case "ArrayAccess": case "ArrayIndex": return(ConvertArrayIndex(invocation)); case "ArrayLength": return(ConvertArrayLength(invocation)); case "Assign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Assign)); case "Call": return(ConvertCall(invocation)); case "Coalesce": return(ConvertBinaryOperator(invocation, BinaryOperatorType.NullCoalescing)); case "Condition": return(ConvertCondition(invocation)); case "Constant": if (invocation.Arguments.Count >= 1) { return(invocation.Arguments.First().Clone()); } else { return(NotSupported(expr)); } case "Convert": return(ConvertCast(invocation, false)); case "ConvertChecked": return(ConvertCast(invocation, true)); case "Divide": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Divide)); case "DivideAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Divide)); case "Equal": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Equality)); case "ExclusiveOr": return(ConvertBinaryOperator(invocation, BinaryOperatorType.ExclusiveOr)); case "ExclusiveOrAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.ExclusiveOr)); case "Field": return(ConvertField(invocation)); case "GreaterThan": return(ConvertBinaryOperator(invocation, BinaryOperatorType.GreaterThan)); case "GreaterThanOrEqual": return(ConvertBinaryOperator(invocation, BinaryOperatorType.GreaterThanOrEqual)); case "Invoke": return(ConvertInvoke(invocation)); case "Lambda": return(ConvertLambda(invocation)); case "LeftShift": return(ConvertBinaryOperator(invocation, BinaryOperatorType.ShiftLeft)); case "LeftShiftAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.ShiftLeft)); case "LessThan": return(ConvertBinaryOperator(invocation, BinaryOperatorType.LessThan)); case "LessThanOrEqual": return(ConvertBinaryOperator(invocation, BinaryOperatorType.LessThanOrEqual)); case "ListInit": return(ConvertListInit(invocation)); case "MemberInit": return(ConvertMemberInit(invocation)); case "Modulo": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Modulus)); case "ModuloAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Modulus)); case "Multiply": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Multiply, false)); case "MultiplyChecked": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Multiply, true)); case "MultiplyAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Multiply, false)); case "MultiplyAssignChecked": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Multiply, true)); case "Negate": return(ConvertUnaryOperator(invocation, UnaryOperatorType.Minus, false)); case "NegateChecked": return(ConvertUnaryOperator(invocation, UnaryOperatorType.Minus, true)); case "New": return(ConvertNewObject(invocation)); case "NewArrayBounds": return(ConvertNewArrayBounds(invocation)); case "NewArrayInit": return(ConvertNewArrayInit(invocation)); case "Not": return(ConvertUnaryOperator(invocation, UnaryOperatorType.Not)); case "NotEqual": return(ConvertBinaryOperator(invocation, BinaryOperatorType.InEquality)); case "OnesComplement": return(ConvertUnaryOperator(invocation, UnaryOperatorType.BitNot)); case "Or": return(ConvertBinaryOperator(invocation, BinaryOperatorType.BitwiseOr)); case "OrAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.BitwiseOr)); case "OrElse": return(ConvertBinaryOperator(invocation, BinaryOperatorType.ConditionalOr)); case "Property": return(ConvertProperty(invocation)); case "Quote": if (invocation.Arguments.Count == 1) { return(Convert(invocation.Arguments.Single())); } else { return(NotSupported(invocation)); } case "RightShift": return(ConvertBinaryOperator(invocation, BinaryOperatorType.ShiftRight)); case "RightShiftAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.ShiftRight)); case "Subtract": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Subtract, false)); case "SubtractChecked": return(ConvertBinaryOperator(invocation, BinaryOperatorType.Subtract, true)); case "SubtractAssign": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Subtract, false)); case "SubtractAssignChecked": return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Subtract, true)); case "TypeAs": return(ConvertTypeAs(invocation)); case "TypeIs": return(ConvertTypeIs(invocation)); } } } IdentifierExpression ident = expr as IdentifierExpression; if (ident != null) { ILVariable v = ident.Annotation <ILVariable>(); if (v != null) { foreach (LambdaExpression lambda in activeLambdas) { foreach (ParameterDeclaration p in lambda.Parameters) { if (p.Annotation <ILVariable>() == v) { return(IdentifierExpression.Create(p.Name, v.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local).WithAnnotation(v)); } } } } } return(NotSupported(expr)); }