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)); }
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); } }
public void FormatMethodWithMultipleArgumentsForMessage() { var message = FormatHelper.FormatMethodForMessage("foo", new List <Type>() { typeof(string), typeof(int) }); Assert.Equal("foo(System.String,System.Int32)", message); }
public void FormatMethodWithSingleArgumentForMessage() { var message = FormatHelper.FormatMethodForMessage("foo", new List <Type>() { typeof(string) }); Assert.Equal("foo(System.String)", message); }
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)); } }
private void ThrowIfNotNullSafe(IList <Type> argumentTypes) { if (!_nullSafe) { throw new SpelEvaluationException(StartPosition, SpelMessage.METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED, FormatHelper.FormatMethodForMessage(_name, argumentTypes)); } }