public ITypedValue GetValue() { var value = _map[_key]; _indexer._exitTypeDescriptor = CodeFlow.ToDescriptor(typeof(object)); return(new TypedValue(value, ReflectionHelper.GetMapValueTypeDescriptor(_mapEntryDescriptor, value))); }
protected internal TypeDescriptor ComputeExitDescriptor(object result, Type propertyReturnType) { if (propertyReturnType.IsValueType) { return(CodeFlow.ToDescriptor(propertyReturnType)); } return(CodeFlow.ToDescriptorFromObject(result)); }
private TypedValue ExecuteFunctionJLRMethod(ExpressionState state, MethodInfo method) { var functionArgs = GetArguments(state); if (!method.IsVarArgs()) { var declaredParamCount = method.GetParameters().Length; if (declaredParamCount != functionArgs.Length) { throw new SpelEvaluationException(SpelMessage.INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION, functionArgs.Length, declaredParamCount); } } if (!method.IsStatic) { throw new SpelEvaluationException(StartPosition, SpelMessage.FUNCTION_MUST_BE_STATIC, ClassUtils.GetQualifiedMethodName(method), _name); } // Convert arguments if necessary and remap them for varargs if required var converter = state.EvaluationContext.TypeConverter; var argumentConversionOccurred = ReflectionHelper.ConvertAllArguments(converter, functionArgs, method); if (method.IsVarArgs()) { functionArgs = ReflectionHelper.SetupArgumentsForVarargsInvocation(ClassUtils.GetParameterTypes(method), functionArgs); } var compilable = false; try { var result = method.Invoke(method.GetType(), functionArgs); compilable = !argumentConversionOccurred; return(new TypedValue(result, result?.GetType() ?? method.ReturnType)); } catch (Exception ex) { throw new SpelEvaluationException(StartPosition, ex, SpelMessage.EXCEPTION_DURING_FUNCTION_CALL, _name, ex.Message); } finally { if (compilable) { _exitTypeDescriptor = CodeFlow.ToDescriptor(method.ReturnType); _method = method; } else { _exitTypeDescriptor = null; _method = null; } } }
public ITypedValue GetValue() { var value = _ref.GetValueInternal(_contextObject, _evalContext, _autoGrowNullReferences); var accessorToUse = _ref._cachedReadAccessor; if (accessorToUse is ICompilablePropertyAccessor) { _ref.SetExitTypeDescriptor(CodeFlow.ToDescriptor(((ICompilablePropertyAccessor)accessorToUse).GetPropertyType())); } return(value); }
public override ITypedValue GetValueInternal(ExpressionState state) { var tv = GetValueInternal(state.GetActiveContextObject(), state.EvaluationContext, state.Configuration.AutoGrowNullReferences); var accessorToUse = _cachedReadAccessor; if (accessorToUse is ICompilablePropertyAccessor) { var accessor = (ICompilablePropertyAccessor)accessorToUse; SetExitTypeDescriptor(CodeFlow.ToDescriptor(accessor.GetPropertyType())); } return(tv); }
public ITypedValue GetValue() { var targetObjectRuntimeClass = _indexer.GetObjectType(_targetObject); try { if (_indexer._cachedReadName != null && _indexer._cachedReadName.Equals(_name) && _indexer._cachedReadTargetType != null && _indexer._cachedReadTargetType.Equals(targetObjectRuntimeClass)) { // It is OK to use the cached accessor var accessor = _indexer._cachedReadAccessor; if (accessor == null) { throw new InvalidOperationException("No cached read accessor"); } return(accessor.Read(_evaluationContext, _targetObject, _name)); } var accessorsToTry = AstUtils.GetPropertyAccessorsToTry(targetObjectRuntimeClass, _evaluationContext.PropertyAccessors); foreach (var acc in accessorsToTry) { var accessor = acc; if (accessor.CanRead(_evaluationContext, _targetObject, _name)) { if (accessor is ReflectivePropertyAccessor) { accessor = ((ReflectivePropertyAccessor)accessor).CreateOptimalAccessor(_evaluationContext, _targetObject, _name); } _indexer._cachedReadAccessor = accessor; _indexer._cachedReadName = _name; _indexer._cachedReadTargetType = targetObjectRuntimeClass; if (accessor is ReflectivePropertyAccessor.OptimalPropertyAccessor) { var optimalAccessor = (ReflectivePropertyAccessor.OptimalPropertyAccessor)accessor; var member = optimalAccessor.Member; _indexer._exitTypeDescriptor = CodeFlow.ToDescriptor(member is MethodInfo ? ((MethodInfo)member).ReturnType : ((FieldInfo)member).FieldType); } return(accessor.Read(_evaluationContext, _targetObject, _name)); } } } catch (AccessException ex) { throw new SpelEvaluationException(_indexer.StartPosition, ex, SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, _targetObjectTypeDescriptor.ToString()); } throw new SpelEvaluationException(_indexer.StartPosition, SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, _targetObjectTypeDescriptor.ToString()); }
private void UpdateExitTypeDescriptor() { var executorToCheck = _cachedExecutor; if (executorToCheck != null && executorToCheck.Get() is ReflectiveMethodExecutor) { var method = ((ReflectiveMethodExecutor)executorToCheck.Get()).Method; var descriptor = CodeFlow.ToDescriptor(method.ReturnType); if (_nullSafe && CodeFlow.IsPrimitive(descriptor)) { _originalPrimitiveExitTypeDescriptor = descriptor; _exitTypeDescriptor = CodeFlow.ToBoxedDescriptor(descriptor); } else { _exitTypeDescriptor = descriptor; } } }
public ITypedValue GetValue() { GrowCollectionIfNecessary(); if (_collection is IList) { var o = _collection[_index]; _indexer._exitTypeDescriptor = CodeFlow.ToDescriptor(typeof(object)); return(new TypedValue(o, ReflectionHelper.GetElementTypeDescriptor(_collectionEntryDescriptor, o))); } var pos = 0; foreach (var o in _collection) { if (pos == _index) { return(new TypedValue(o, ReflectionHelper.GetElementTypeDescriptor(_collectionEntryDescriptor, o))); } pos++; } throw new InvalidOperationException("Failed to find indexed element " + _index + ": " + _collection); }
private object AccessArrayElement(object ctx, int idx) { var arrayComponentType = ctx.GetType().GetElementType(); if (arrayComponentType == typeof(bool)) { var array = (bool[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.Z; return(array[idx]); } else if (arrayComponentType == typeof(byte)) { var array = (byte[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.B; return(array[idx]); } else if (arrayComponentType == typeof(char)) { var array = (char[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.C; return(array[idx]); } else if (arrayComponentType == typeof(double)) { var array = (double[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.D; return(array[idx]); } else if (arrayComponentType == typeof(float)) { var array = (float[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.F; return(array[idx]); } else if (arrayComponentType == typeof(int)) { var array = (int[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.I; return(array[idx]); } else if (arrayComponentType == typeof(long)) { var array = (long[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.J; return(array[idx]); } else if (arrayComponentType == typeof(short)) { var array = (short[])ctx; CheckAccess(array.Length, idx); _exitTypeDescriptor = TypeDescriptor.S; return(array[idx]); } else { var array = (object[])ctx; CheckAccess(array.Length, idx); var retValue = array[idx]; _exitTypeDescriptor = CodeFlow.ToDescriptor(arrayComponentType); return(retValue); } }
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)); } }