public object Get(EventBean eventBean)
 {
     var value = VariantEventPropertyGetterAny.VariantGet(eventBean, _propertyGetterCache,
         _assignedPropertyNumber);
     if (value == null) return null;
     return _caster.Invoke(value);
 }
Пример #2
0
        public VariantPropertyDesc ResolveProperty(String propertyName, EventType[] variants)
        {
            // property numbers should start at zero since the serve as array index
            int assignedPropertyNumber = _currentPropertyNumber;

            _currentPropertyNumber++;
            _propertyGetterCache.AddGetters(assignedPropertyNumber, propertyName);

            var getter = new VariantEventPropertyGetterAny(_propertyGetterCache, assignedPropertyNumber);

            return(new VariantPropertyDesc(typeof(Object), getter, true));
        }
 public ICodegenExpression CodegenUnderlyingFragment(ICodegenExpression underlyingExpression,
     ICodegenContext context)
 {
     throw VariantEventPropertyGetterAny.VariantImplementationNotProvided();
 }
 public bool IsExistsProperty(EventBean eventBean)
 {
     return VariantEventPropertyGetterAny.VariantExists(eventBean, _propertyGetterCache,
         _assignedPropertyNumber);
 }
        public VariantPropertyDesc ResolveProperty(String propertyName, EventType[] variants)
        {
            bool existsInAll = true;
            Type commonType  = null;
            bool mustCoerce  = false;

            for (int i = 0; i < variants.Length; i++)
            {
                Type type = variants[i].GetPropertyType(propertyName); //.GetBoxedType();
                if (type == null)
                {
                    existsInAll = false;
                    continue;
                }

                if (commonType == null)
                {
                    commonType = type;
                    continue;
                }

                // compare types
                if (type == commonType)
                {
                    continue;
                }

                if (type.GetBoxedType() == commonType.GetBoxedType())
                {
                    commonType = commonType.GetBoxedType();
                    continue;
                }

                // coercion
                if (type.IsNumeric())
                {
                    if (TypeHelper.CanCoerce(type, commonType))
                    {
                        mustCoerce = true;
                        continue;
                    }
                    if (TypeHelper.CanCoerce(commonType, type))
                    {
                        mustCoerce = true;
                        commonType = type;
                    }
                }
                else if (commonType == typeof(Object))
                {
                    continue;
                }
                // common interface or base class
                else if (!type.IsBuiltinDataType())
                {
                    var supersForType = new FIFOHashSet <Type>();
                    TypeHelper.GetBase(type, supersForType);
                    supersForType.Remove(typeof(Object));

                    if (supersForType.Contains(commonType))
                    {
                        continue;   // type, or : common type
                    }
                    if (TypeHelper.IsSubclassOrImplementsInterface(commonType, type))
                    {
                        commonType = type;  // common type : type
                        continue;
                    }

                    // find common interface or type both implement
                    var supersForCommonType = new FIFOHashSet <Type>();
                    TypeHelper.GetBase(commonType, supersForCommonType);
                    supersForCommonType.Remove(typeof(Object));

                    // Take common classes first, ignoring interfaces
                    bool found = false;
                    foreach (Type superClassType in supersForType)
                    {
                        if (!superClassType.IsInterface && (supersForCommonType.Contains(superClassType)))
                        {
                            break;
                        }
                    }
                    if (found)
                    {
                        continue;
                    }
                    // Take common interfaces
                    foreach (var superClassType in supersForType)
                    {
                        if (superClassType.IsInterface && supersForCommonType.Contains(superClassType))
                        {
                            commonType = superClassType;
                            found      = true;
                            break;
                        }
                    }
                }

                commonType = typeof(Object);
            }

            if (!existsInAll)
            {
                return(null);
            }

            if (commonType == null)
            {
                return(null);
            }

            // property numbers should start at zero since the serve as array index
            var assignedPropertyNumber = currentPropertyNumber;

            currentPropertyNumber++;
            propertyGetterCache.AddGetters(assignedPropertyNumber, propertyName);

            EventPropertyGetterSPI getter;

            if (mustCoerce)
            {
                SimpleTypeCaster caster = SimpleTypeCasterFactory.GetCaster(null, commonType);
                getter = new VariantEventPropertyGetterAnyWCast(propertyGetterCache, assignedPropertyNumber, caster);
            }
            else
            {
                getter = new VariantEventPropertyGetterAny(propertyGetterCache, assignedPropertyNumber);
            }

            return(new VariantPropertyDesc(commonType, getter, true));
        }