Example #1
0
        public static ExpressionAction ResolveMetadataDeclarationFor(MethodCallExpression expression, IRequirementsBuilder requirementsBuiler, out Expression replacement)
        {
            replacement = null;
            if (!IsMetadataDeclarationForMethod(expression.Method))
                return ExpressionAction.None;

            if (expression.Arguments.Count == 0 || typeof(Expression).IsAssignableFrom(expression.Arguments[0].Type))
                return ExpressionAction.None;

            // if any parameters are referenced, fail the expression (cannot port, cannot invoke)
            if (RegionAnalysisStrategy.GetReferencedParameters(expression.Object).Count() > 0)
                return ExpressionAction.Fail;

            // if object is a constant, set a metadata requirement and continue
            if (expression.Object == null)
                throw new ArgumentNullException();
            if (expression.Object is ConstantExpression)
            {
                var constexp = (ConstantExpression) expression.Object;
                requirementsBuiler.NoteMetadataRequirement(new MetadataInfo(expression.Arguments[0].Type, (IExodataDeclaration)constexp.Value, expression.Method,
                    (expression.Arguments.Count == 2) ? expression.Arguments[1] : null));
                return ExpressionAction.Retain;
            }

            // otherwise, attempt to convert the constant expression to a constant
            var constval = (IExodataDeclaration)Expression.Lambda(expression.Object).Compile().DynamicInvoke();
            var objectValue = Expression.Constant(constval);

            replacement = Expression.Call(objectValue, expression.Method, expression.Arguments);
            return ExpressionAction.Replace;
        }