Exemplo n.º 1
0
 public VariantPropertyDesc ResolveProperty(
     string propertyName,
     EventType[] variants)
 {
     // property numbers should start at zero since the serve as array index
     var propertyGetterCache = variantEventType.VariantPropertyGetterCache;
     propertyGetterCache.AddGetters(propertyName);
     EventPropertyGetterSPI getter = new VariantEventPropertyGetterAny(variantEventType, propertyName);
     return new VariantPropertyDesc(typeof(object), getter, true);
 }
Exemplo n.º 2
0
        public VariantPropertyDesc ResolveProperty(
            string propertyName,
            EventType[] variants)
        {
            var existsInAll = true;
            Type commonType = null;
            var mustCoerce = false;
            for (var i = 0; i < variants.Length; i++) {
                var type = variants[i].GetPropertyType(propertyName).GetBoxedType();
                if (type == null) {
                    existsInAll = false;
                    continue;
                }

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

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

                // coercion
                if (type.IsNumeric()) {
                    if (type.CanCoerce(commonType)) {
                        mustCoerce = true;
                        continue;
                    }

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

                    if (supersForType.Contains(commonType)) {
                        continue; // type implements or : common type
                    }

                    if (TypeHelper.IsSubclassOrImplementsInterface(commonType, type)) {
                        commonType = type; // common type implements type
                        continue;
                    }

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

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

                    if (found) {
                        continue;
                    }

                    // Take common interfaces
                    foreach (var superClassType in supersForType) {
                        if (superClassType.IsInterface && supersForCommonType.Contains(superClassType)) {
                            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 propertyGetterCache = variantEventType.VariantPropertyGetterCache;
            propertyGetterCache.AddGetters(propertyName);

            EventPropertyGetterSPI getter;
            if (mustCoerce) {
                var caster = SimpleTypeCasterFactory.GetCaster(null, commonType);
                getter = new VariantEventPropertyGetterAnyWCast(variantEventType, propertyName, caster);
            }
            else {
                getter = new VariantEventPropertyGetterAny(variantEventType, propertyName);
            }

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