예제 #1
0
        private IConstructorExecutor FindExecutorForConstructor(string typeName, List <Type> argumentTypes, ExpressionState state)
        {
            var evalContext   = state.EvaluationContext;
            var ctorResolvers = evalContext.ConstructorResolvers;

            foreach (var ctorResolver in ctorResolvers)
            {
                try
                {
                    var ce = ctorResolver.Resolve(state.EvaluationContext, typeName, argumentTypes);
                    if (ce != null)
                    {
                        return(ce);
                    }
                }
                catch (AccessException ex)
                {
                    throw new SpelEvaluationException(
                              StartPosition,
                              ex,
                              SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM,
                              typeName,
                              FormatHelper.FormatMethodForMessage(string.Empty, argumentTypes));
                }
            }

            throw new SpelEvaluationException(
                      StartPosition,
                      SpelMessage.CONSTRUCTOR_NOT_FOUND,
                      typeName,
                      FormatHelper.FormatMethodForMessage(string.Empty, argumentTypes));
        }
예제 #2
0
        private IMethodExecutor FindAccessorForMethod(List <Type> argumentTypes, object targetObject, IEvaluationContext evaluationContext)
        {
            AccessException accessException = null;
            var             methodResolvers = evaluationContext.MethodResolvers;

            foreach (var methodResolver in methodResolvers)
            {
                try
                {
                    var methodExecutor = methodResolver.Resolve(evaluationContext, targetObject, _name, argumentTypes);
                    if (methodExecutor != null)
                    {
                        return(methodExecutor);
                    }
                }
                catch (AccessException ex)
                {
                    accessException = ex;
                    break;
                }
            }

            var method    = FormatHelper.FormatMethodForMessage(_name, argumentTypes);
            var className = FormatHelper.FormatClassNameForMessage(targetObject is Type type ? type : targetObject.GetType());

            if (accessException != null)
            {
                throw new SpelEvaluationException(StartPosition, accessException, SpelMessage.PROBLEM_LOCATING_METHOD, method, className);
            }
            else
            {
                throw new SpelEvaluationException(StartPosition, SpelMessage.METHOD_NOT_FOUND, method, className);
            }
        }
예제 #3
0
        public void FormatMethodWithMultipleArgumentsForMessage()
        {
            var message = FormatHelper.FormatMethodForMessage("foo", new List <Type>()
            {
                typeof(string), typeof(int)
            });

            Assert.Equal("foo(System.String,System.Int32)", message);
        }
예제 #4
0
        public void FormatMethodWithSingleArgumentForMessage()
        {
            var message = FormatHelper.FormatMethodForMessage("foo", new List <Type>()
            {
                typeof(string)
            });

            Assert.Equal("foo(System.String)", message);
        }
예제 #5
0
        private ITypedValue CreateNewInstance(ExpressionState state)
        {
            var arguments     = new object[ChildCount - 1];
            var argumentTypes = new List <Type>(ChildCount - 1);

            for (var i = 0; i < arguments.Length; i++)
            {
                var childValue = _children[i + 1].GetValueInternal(state);
                var value      = childValue.Value;
                arguments[i] = value;
                var valueType = value?.GetType();
                argumentTypes.Add(valueType);
            }

            var executorToUse = _cachedExecutor;

            if (executorToUse != null)
            {
                try
                {
                    return(executorToUse.Execute(state.EvaluationContext, arguments));
                }
                catch (AccessException ex)
                {
                    // Two reasons this can occur:
                    // 1. the method invoked actually threw a real exception
                    // 2. the method invoked was not passed the arguments it expected and has become 'stale'

                    // In the first case we should not retry, in the second case we should see if there is a
                    // better suited method.

                    // To determine which situation it is, the AccessException will contain a cause.
                    // If the cause is an InvocationTargetException, a user exception was thrown inside the constructor.
                    // Otherwise the constructor could not be invoked.
                    if (ex.InnerException is TargetInvocationException)
                    {
                        // User exception was the root cause - exit now
                        var rootCause = ex.InnerException.InnerException;
                        if (rootCause is SystemException)
                        {
                            throw rootCause;
                        }

                        var name = (string)_children[0].GetValueInternal(state).Value;
                        throw new SpelEvaluationException(
                                  StartPosition,
                                  rootCause,
                                  SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM,
                                  name,
                                  FormatHelper.FormatMethodForMessage(string.Empty, argumentTypes));
                    }

                    // At this point we know it wasn't a user problem so worth a retry if a better candidate can be found
                    _cachedExecutor = null;
                }
            }

            // Either there was no accessor or it no longer exists
            var typeName = (string)_children[0].GetValueInternal(state).Value;

            if (typeName == null)
            {
                throw new InvalidOperationException("No type name");
            }

            executorToUse = FindExecutorForConstructor(typeName, argumentTypes, state);
            try
            {
                _cachedExecutor = executorToUse;
                if (executorToUse is ReflectiveConstructorExecutor executor)
                {
                    _exitTypeDescriptor = CodeFlow.ToDescriptor(executor.Constructor.DeclaringType);
                }

                return(executorToUse.Execute(state.EvaluationContext, arguments));
            }
            catch (AccessException ex)
            {
                throw new SpelEvaluationException(
                          StartPosition,
                          ex,
                          SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM,
                          typeName,
                          FormatHelper.FormatMethodForMessage(string.Empty, argumentTypes));
            }
        }
예제 #6
0
 private void ThrowIfNotNullSafe(IList <Type> argumentTypes)
 {
     if (!_nullSafe)
     {
         throw new SpelEvaluationException(StartPosition, SpelMessage.METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED, FormatHelper.FormatMethodForMessage(_name, argumentTypes));
     }
 }