Example #1
0
            public ITypedValue GetValue()
            {
                var value = _map[_key];

                _indexer._exitTypeDescriptor = CodeFlow.ToDescriptor(typeof(object));
                return(new TypedValue(value, ReflectionHelper.GetMapValueTypeDescriptor(_mapEntryDescriptor, value)));
            }
Example #2
0
        protected internal TypeDescriptor ComputeExitDescriptor(object result, Type propertyReturnType)
        {
            if (propertyReturnType.IsValueType)
            {
                return(CodeFlow.ToDescriptor(propertyReturnType));
            }

            return(CodeFlow.ToDescriptorFromObject(result));
        }
Example #3
0
        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;
                }
            }
        }
Example #4
0
            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);
            }
Example #5
0
        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);
        }
Example #6
0
            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());
            }
Example #7
0
        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;
                }
            }
        }
Example #8
0
            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);
            }
Example #9
0
        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);
            }
        }
Example #10
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));
            }
        }