public MethodValueRef(MethodReference mref, ExpressionState state, object[] arguments)
 {
     _mref = mref;
     _evaluationContext = state.EvaluationContext;
     _value             = state.GetActiveContextObject().Value;
     _targetType        = state.GetActiveContextObject().TypeDescriptor;
     _arguments         = arguments;
 }
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var evaluationContext = state.EvaluationContext;
            var value             = state.GetActiveContextObject().Value;
            var targetType        = state.GetActiveContextObject().TypeDescriptor;
            var arguments         = GetArguments(state);
            var result            = GetValueInternal(evaluationContext, value, targetType, arguments);

            UpdateExitTypeDescriptor(result.Value);
            return(result);
        }
Beispiel #3
0
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            if (_name.Equals(_THIS))
            {
                return(state.GetActiveContextObject());
            }

            if (_name.Equals(_ROOT))
            {
                var obj = state.RootContextObject;
                _exitTypeDescriptor = CodeFlow.ToDescriptorFromObject(obj.Value);
                return(obj);
            }

            var result = state.LookupVariable(_name);
            var value  = result.Value;

            if (value == null || !value.GetType().IsPublic)
            {
                // If the type is not public then when generateCode produces a checkcast to it
                // then an IllegalAccessError will occur.
                // If resorting to Object isn't sufficient, the hierarchy could be traversed for
                // the first public type.
                _exitTypeDescriptor = "Ljava/lang/Object";
            }
            else
            {
                _exitTypeDescriptor = CodeFlow.ToDescriptorFromObject(value);
            }

            // a null value will mean either the value was null or the variable was not found
            return(result);
        }
        protected internal override IValueRef GetValueRef(ExpressionState state)
        {
            var arguments = GetArguments(state);

            if (state.GetActiveContextObject().Value == null)
            {
                ThrowIfNotNullSafe(GetArgumentTypes(arguments));
                return(NullValueRef.INSTANCE);
            }

            return(new MethodValueRef(this, state, arguments));
        }
        public override ITypedValue GetValueInternal(ExpressionState state)
        {
            var tv            = GetValueInternal(state.GetActiveContextObject(), state.EvaluationContext, state.Configuration.AutoGrowNullReferences);
            var accessorToUse = _cachedReadAccessor;

            if (accessorToUse is ICompilablePropertyAccessor accessor)
            {
                var descriptor = ComputeExitDescriptor(tv.Value, accessor.GetPropertyType());
                SetExitTypeDescriptor(descriptor);
            }

            return(tv);
        }
Beispiel #6
0
        protected internal override IValueRef GetValueRef(ExpressionState state)
        {
            if (_name.Equals(_THIS))
            {
                return(new TypedValueHolderValueRef(state.GetActiveContextObject(), this));
            }

            if (_name.Equals(_ROOT))
            {
                return(new TypedValueHolderValueRef(state.RootContextObject, this));
            }

            var result = state.LookupVariable(_name);

            // a null value will mean either the value was null or the variable was not found
            return(new VariableRef(_name, result, state.EvaluationContext));
        }
Beispiel #7
0
        protected internal override IValueRef GetValueRef(ExpressionState state)
        {
            var op                = state.GetActiveContextObject();
            var operand           = op.Value;
            var selectionCriteria = _children[0];

            if (operand is System.Collections.IDictionary mapdata)
            {
                // Don't lose generic info for the new map
                var    result  = new Dictionary <object, object>();
                object lastKey = null;

                foreach (DictionaryEntry entry in mapdata)
                {
                    try
                    {
                        var kvPair = new TypedValue(entry);
                        state.PushActiveContextObject(kvPair);
                        state.EnterScope();
                        var val = selectionCriteria.GetValueInternal(state).Value;
                        if (val is bool boolean)
                        {
                            if (boolean)
                            {
                                if (_variant == FIRST)
                                {
                                    result[entry.Key] = entry.Value;
                                    return(new TypedValueHolderValueRef(new TypedValue(result), this));
                                }

                                result[entry.Key] = entry.Value;
                                lastKey           = entry.Key;
                            }
                        }
                        else
                        {
                            throw new SpelEvaluationException(selectionCriteria.StartPosition, SpelMessage.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
                        }
                    }
                    finally
                    {
                        state.PopActiveContextObject();
                        state.ExitScope();
                    }
                }

                if ((_variant == FIRST || _variant == LAST) && result.Count == 0)
                {
                    return(new TypedValueHolderValueRef(new TypedValue(null), this));
                }

                if (_variant == LAST)
                {
                    var resultMap = new Dictionary <object, object>();
                    result.TryGetValue(lastKey, out var lastValue);
                    resultMap[lastKey] = lastValue;
                    return(new TypedValueHolderValueRef(new TypedValue(resultMap), this));
                }

                return(new TypedValueHolderValueRef(new TypedValue(result), this));
            }

            if (operand is IEnumerable)
            {
                var operandAsArray = operand as Array;
                var data           = operand as IEnumerable;

                var result = new List <object>();
                var index  = 0;
                foreach (var element in data)
                {
                    try
                    {
                        state.PushActiveContextObject(new TypedValue(element));
                        state.EnterScope("index", index);
                        var val = selectionCriteria.GetValueInternal(state).Value;
                        if (val is bool boolean)
                        {
                            if (boolean)
                            {
                                if (_variant == FIRST)
                                {
                                    return(new TypedValueHolderValueRef(new TypedValue(element), this));
                                }

                                result.Add(element);
                            }
                        }
                        else
                        {
                            throw new SpelEvaluationException(selectionCriteria.StartPosition, SpelMessage.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
                        }

                        index++;
                    }
                    finally
                    {
                        state.ExitScope();
                        state.PopActiveContextObject();
                    }
                }

                if ((_variant == FIRST || _variant == LAST) && result.Count == 0)
                {
                    return(NullValueRef.INSTANCE);
                }

                if (_variant == LAST)
                {
                    var lastElem = result == null || result.Count == 0 ? null : result[result.Count - 1];
                    return(new TypedValueHolderValueRef(new TypedValue(lastElem), this));
                }

                if (operand is IEnumerable && operandAsArray == null)
                {
                    return(new TypedValueHolderValueRef(new TypedValue(result), this));
                }

                // Array
                if (operandAsArray != null)
                {
                    Type elementType = null;
                    var  typeDesc    = op.TypeDescriptor;
                    if (typeDesc != null)
                    {
                        elementType = ReflectionHelper.GetElementTypeDescriptor(typeDesc);
                    }

                    if (elementType == null)
                    {
                        throw new InvalidOperationException("Unresolvable element type");
                    }

                    var resultArray = Array.CreateInstance(elementType, result.Count);
                    Array.Copy(result.ToArray(), 0, resultArray, 0, result.Count);
                    return(new TypedValueHolderValueRef(new TypedValue(resultArray), this));
                }
            }

            if (operand == null)
            {
                if (_nullSafe)
                {
                    return(NullValueRef.INSTANCE);
                }

                throw new SpelEvaluationException(StartPosition, SpelMessage.INVALID_TYPE_FOR_SELECTION, "null");
            }

            throw new SpelEvaluationException(StartPosition, SpelMessage.INVALID_TYPE_FOR_SELECTION, operand.GetType().FullName);
        }
Beispiel #8
0
        protected internal override IValueRef GetValueRef(ExpressionState state)
        {
            var         context          = state.GetActiveContextObject();
            var         target           = context.Value;
            var         targetDescriptor = context.TypeDescriptor;
            ITypedValue indexValue;
            object      index;

            // This first part of the if clause prevents a 'double dereference' of the property (SPR-5847)
            if (target is System.Collections.IDictionary && (_children[0] is PropertyOrFieldReference reference1))
            {
                var reference = reference1;
                index      = reference.Name;
                indexValue = new TypedValue(index);
            }
            else
            {
                // In case the map key is unqualified, we want it evaluated against the root object
                // so temporarily push that on whilst evaluating the key
                try
                {
                    state.PushActiveContextObject(state.RootContextObject);
                    indexValue = _children[0].GetValueInternal(state);
                    index      = indexValue.Value;
                    if (index == null)
                    {
                        throw new InvalidOperationException("No index");
                    }
                }
                finally
                {
                    state.PopActiveContextObject();
                }
            }

            // Raise a proper exception in case of a null target
            if (target == null)
            {
                throw new SpelEvaluationException(StartPosition, SpelMessage.CANNOT_INDEX_INTO_NULL_VALUE);
            }

            // At this point, we need a TypeDescriptor for a non-null target object
            if (targetDescriptor == null)
            {
                throw new InvalidOperationException("No type descriptor");
            }

            // Indexing into a Map
            if (target is System.Collections.IDictionary)
            {
                var key        = index;
                var mapkeyType = ReflectionHelper.GetMapKeyTypeDescriptor(targetDescriptor);
                if (mapkeyType != null)
                {
                    key = state.ConvertValue(key, mapkeyType);
                }

                _indexedType = IndexedType.MAP;
                return(new MapIndexingValueRef(this, state.TypeConverter, (IDictionary)target, key, targetDescriptor));
            }

            // If the object is something that looks indexable by an integer,
            // attempt to treat the index value as a number
            if (target is Array || target is IList || target is string)
            {
                var idx = (int)state.ConvertValue(index, typeof(int));
                if (target is Array)
                {
                    _indexedType = IndexedType.ARRAY;
                    return(new ArrayIndexingValueRef(this, state.TypeConverter, target, idx, targetDescriptor));
                }
                else if (target is IList list)
                {
                    _indexedType = IndexedType.LIST;

                    return(new CollectionIndexingValueRef(this, list, idx, targetDescriptor, state.TypeConverter, state.Configuration.AutoGrowCollections, state.Configuration.MaximumAutoGrowSize));
                }
                else
                {
                    _indexedType = IndexedType.STRING;
                    return(new StringIndexingLValue(this, (string)target, idx, targetDescriptor));
                }
            }

            // Try and treat the index value as a property of the context object
            // Could call the conversion service to convert the value to a String
            var valueType = indexValue.TypeDescriptor;

            if (valueType != null && typeof(string) == valueType)
            {
                _indexedType = IndexedType.OBJECT;
                return(new PropertyIndexingValueRef(this, target, (string)index, state.EvaluationContext, targetDescriptor));
            }

            throw new SpelEvaluationException(StartPosition, SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, targetDescriptor);
        }
 public override bool IsWritable(ExpressionState state)
 {
     return(IsWritableProperty(_name, state.GetActiveContextObject(), state.EvaluationContext));
 }
 public override void SetValue(ExpressionState state, object newValue)
 {
     WriteProperty(state.GetActiveContextObject(), state.EvaluationContext, _name, newValue);
 }
 protected internal override IValueRef GetValueRef(ExpressionState state)
 {
     return(new AccessorLValue(this, state.GetActiveContextObject(), state.EvaluationContext, state.Configuration.AutoGrowNullReferences));
 }
Beispiel #12
0
        protected internal override IValueRef GetValueRef(ExpressionState state)
        {
            var op = state.GetActiveContextObject();

            var operand        = op.Value;
            var operandAsArray = operand as Array;

            // TypeDescriptor operandTypeDescriptor = op.getTypeDescriptor();

            // When the input is a map, we push a special context object on the stack
            // before calling the specified operation. This special context object
            // has two fields 'key' and 'value' that refer to the map entries key
            // and value, and they can be referenced in the operation
            // eg. {'a':'y','b':'n'}.![value=='y'?key:null]" == ['a', null]
            if (operand is IDictionary)
            {
                var mapData = (IDictionary)operand;
                var result  = new List <object>();
                foreach (var entry in mapData)
                {
                    try
                    {
                        state.PushActiveContextObject(new TypedValue(entry));
                        state.EnterScope();
                        result.Add(_children[0].GetValueInternal(state).Value);
                    }
                    finally
                    {
                        state.PopActiveContextObject();
                        state.ExitScope();
                    }
                }

                return(new TypedValueHolderValueRef(new TypedValue(result), this));  // TODO unable to build correct type descriptor
            }

            if (operand is IEnumerable)
            {
                var data = operand as IEnumerable;

                var  result           = new List <object>();
                Type arrayElementType = null;
                foreach (var element in data)
                {
                    try
                    {
                        state.PushActiveContextObject(new TypedValue(element));
                        state.EnterScope("index", result.Count);
                        var value = _children[0].GetValueInternal(state).Value;
                        if (value != null && operandAsArray != null)
                        {
                            arrayElementType = DetermineCommonType(arrayElementType, value.GetType());
                        }

                        result.Add(value);
                    }
                    finally
                    {
                        state.ExitScope();
                        state.PopActiveContextObject();
                    }
                }

                if (operandAsArray != null)
                {
                    if (arrayElementType == null)
                    {
                        arrayElementType = typeof(object);
                    }

                    var resultArray = Array.CreateInstance(arrayElementType, result.Count);
                    Array.Copy(result.ToArray(), 0, resultArray, 0, result.Count);
                    return(new TypedValueHolderValueRef(new TypedValue(resultArray), this));
                }

                return(new TypedValueHolderValueRef(new TypedValue(result), this));
            }

            if (operand == null)
            {
                if (_nullSafe)
                {
                    return(NullValueRef.INSTANCE);
                }

                throw new SpelEvaluationException(StartPosition, SpelMessage.PROJECTION_NOT_SUPPORTED_ON_TYPE, "null");
            }

            throw new SpelEvaluationException(StartPosition, SpelMessage.PROJECTION_NOT_SUPPORTED_ON_TYPE, operand.GetType().FullName);
        }