public Object Compute(Object input, EvaluateParams evaluateParams) { return(_caster.Invoke(input)); }
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); EventPropertyGetter getter; if (mustCoerce) { SimpleTypeCaster caster = SimpleTypeCasterFactory.GetCaster(null, commonType); getter = new ProxyEventPropertyGetter { ProcGet = eventBean => { var variant = (VariantEvent)eventBean; var propertyGetter = propertyGetterCache.GetGetter(assignedPropertyNumber, variant.UnderlyingEventBean.EventType); if (propertyGetter == null) { return(null); } var value = propertyGetter.Get(variant.UnderlyingEventBean); if (value == null) { return(value); } return(caster.Invoke(value)); }, ProcGetFragment = eventBean => null, ProcIsExistsProperty = eventBean => { var variant = (VariantEvent)eventBean; var propertyGetter = propertyGetterCache.GetGetter(assignedPropertyNumber, variant.UnderlyingEventBean.EventType); if (propertyGetter == null) { return(false); } return(propertyGetter.IsExistsProperty(variant.UnderlyingEventBean)); } }; } else { getter = new ProxyEventPropertyGetter { ProcGet = eventBean => { var variant = (VariantEvent)eventBean; var propertyGetter = propertyGetterCache.GetGetter(assignedPropertyNumber, variant.UnderlyingEventBean.EventType); if (propertyGetter == null) { return(null); } return(propertyGetter.Get(variant.UnderlyingEventBean)); }, ProcGetFragment = eventBean => null, ProcIsExistsProperty = eventBean => { var variant = (VariantEvent)eventBean; var propertyGetter = propertyGetterCache.GetGetter(assignedPropertyNumber, variant.UnderlyingEventBean.EventType); if (propertyGetter == null) { return(false); } return(propertyGetter.IsExistsProperty(variant.UnderlyingEventBean)); } }; } return(new VariantPropertyDesc(commonType, getter, true)); }