示例#1
0
 /// <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);
     }
 }
示例#2
0
        public static ILVariable GetILVariable(this IdentifierExpression expr)
        {
            var rr = expr.Annotation <ResolveResult>() as ILVariableResolveResult;

            if (rr != null)
            {
                return(rr.Variable);
            }
            else
            {
                return(null);
            }
        }
示例#3
0
        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));
        }
示例#4
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
 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));
 }
示例#7
0
        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));
        }