예제 #1
0
        static IEnumerable <Error> validateListElementsFields(
            Object containingComponent, IList list, FieldInfo listFieldInfo,
            bool hasNotNull, FieldHierarchy fieldHierarchy,
            IErrorFactory createError,
            Option <CustomObjectValidator> customObjectValidatorOpt,
            Option <UniqueValuesCache> uniqueValuesCache
            )
        {
            var listItemType          = listFieldInfo.FieldType.GetElementType();
            var listItemIsUnityObject = unityObjectType.IsAssignableFrom(listItemType);

            if (listItemIsUnityObject)
            {
                if (hasNotNull && list.Contains(null))
                {
                    yield return(createError.nullField(fieldHierarchy.asString()));
                }
            }
            else
            {
                var index = 0;
                foreach (var listItem in list)
                {
                    fieldHierarchy.stack.Push($"[{index}]");
                    var validationResults = validateFields(
                        containingComponent, listItem, createError,
                        customObjectValidatorOpt, fieldHierarchy,
                        uniqueValuesCache
                        );
                    foreach (var _err in validationResults)
                    {
                        yield return(_err);
                    }
                    fieldHierarchy.stack.Pop();
                    index++;
                }
            }
        }
예제 #2
0
        static IEnumerable <Error> validateFields(
            Object containingComponent,
            object objectBeingValidated,
            IErrorFactory createError,
            Option <CustomObjectValidator> customObjectValidatorOpt,
            FieldHierarchy fieldHierarchy = null,
            Option <UniqueValuesCache> uniqueValuesCache = default
            )
        {
            Option.ensureValue(ref uniqueValuesCache);
            fieldHierarchy = fieldHierarchy ?? new FieldHierarchy();

            foreach (var onObjectValidatable in F.opt(objectBeingValidated as OnObjectValidate))
            {
                // Try because custom validations can throw exceptions.
                var validateResult = F.doTry(() =>
                                             // Force strict enumerable evaluation, because it might throw an exception while evaluating.
                                             onObjectValidatable.onObjectValidate(containingComponent).ToArray()
                                             );
                if (validateResult.isSuccess)
                {
                    foreach (var error in validateResult.__unsafeGet)
                    {
                        yield return(createError.custom(fieldHierarchy.asString(), error, true));
                    }
                }
                else
                {
                    var error = validateResult.__unsafeException;
                    yield return(createError.exceptionInCustomValidator(fieldHierarchy.asString(), error));
                }
            }

            foreach (var unityEvent in F.opt(objectBeingValidated as UnityEventBase))
            {
                var errors = checkUnityEvent(createError, fieldHierarchy.asString(), unityEvent);
                foreach (var error in errors)
                {
                    yield return(error);
                }
            }

            foreach (var customValidator in customObjectValidatorOpt)
            {
                foreach (var _err in customValidator(containingComponent, objectBeingValidated))
                {
                    yield return(createError.custom(fieldHierarchy.asString(), _err, true));
                }
            }

            var fields = getFilteredFields(objectBeingValidated);

            foreach (var fi in fields)
            {
                fieldHierarchy.stack.Push(fi.Name);
                var fieldValue  = fi.GetValue(objectBeingValidated);
                var hasNonEmpty = fi.hasAttribute <NonEmptyAttribute>();

                foreach (var cache in uniqueValuesCache)
                {
                    foreach (var attribute in fi.getAttributes <UniqueValue>())
                    {
                        cache.addCheckedField(attribute.category, fieldValue, containingComponent);
                    }
                }
                if (fieldValue is string s)
                {
                    if (fi.getAttributes <TextFieldAttribute>().Any(a => a.Type == TextFieldType.Tag))
                    {
                        if (!UnityEditorInternal.InternalEditorUtility.tags.Contains(s))
                        {
                            yield return(createError.badTextFieldTag(fieldHierarchy.asString()));
                        }
                    }

                    if (s.isEmpty() && hasNonEmpty)
                    {
                        yield return(createError.emptyString(fieldHierarchy.asString()));
                    }
                }
                if (fi.isSerializable())
                {
                    var hasNotNull = fi.hasAttribute <NotNullAttribute>();
                    // Sometimes we get empty unity object. Equals catches that
                    if (fieldValue == null || fieldValue.Equals(null))
                    {
                        if (hasNotNull)
                        {
                            yield return(createError.nullField(fieldHierarchy.asString()));
                        }
                    }
                    else
                    {
                        if (fieldValue is IList list)
                        {
                            if (list.Count == 0 && hasNonEmpty)
                            {
                                yield return(createError.emptyCollection(fieldHierarchy.asString()));
                            }
                            var fieldValidationResults = validateListElementsFields(
                                containingComponent, list, fi, hasNotNull,
                                fieldHierarchy, createError, customObjectValidatorOpt,
                                uniqueValuesCache
                                );
                            foreach (var _err in fieldValidationResults)
                            {
                                yield return(_err);
                            }
                        }
                        else
                        {
                            var fieldType = fi.FieldType;
                            // Check non-primitive serialized fields.
                            if (
                                !fieldType.IsPrimitive &&
                                fieldType.hasAttribute <SerializableAttribute>()
                                )
                            {
                                var validationErrors = validateFields(
                                    containingComponent, fieldValue, createError,
                                    customObjectValidatorOpt, fieldHierarchy,
                                    uniqueValuesCache
                                    );
                                foreach (var _err in validationErrors)
                                {
                                    yield return(_err);
                                }
                            }
                        }
                    }
                }
                fieldHierarchy.stack.Pop();
            }
        }
예제 #3
0
        static IEnumerable <Error> validateFields(
            Object containingComponent,
            object objectBeingValidated,
            IErrorFactory createError,
            Option <CustomObjectValidator> customObjectValidatorOpt,
            FieldHierarchy fieldHierarchy = null
            )
        {
            fieldHierarchy = fieldHierarchy ?? new FieldHierarchy();

            foreach (var onObjectValidatable in F.opt(objectBeingValidated as OnObjectValidate))
            {
                foreach (var error in onObjectValidatable.onObjectValidate(containingComponent))
                {
                    yield return(createError.custom(fieldHierarchy.asString(), error));
                }
            }

            foreach (var customValidator in customObjectValidatorOpt)
            {
                foreach (var _err in customValidator(containingComponent, objectBeingValidated))
                {
                    yield return(createError.custom(fieldHierarchy.asString(), _err));
                }
            }

            var fields = getFilteredFields(objectBeingValidated);

            foreach (var fi in fields)
            {
                fieldHierarchy.stack.Push(fi.Name);
                if (fi.FieldType == typeof(string))
                {
                    if (fi.getAttributes <TextFieldAttribute>().Any(a => a.Type == TextFieldType.Tag))
                    {
                        var fieldValue = (string)fi.GetValue(objectBeingValidated);
                        if (!UnityEditorInternal.InternalEditorUtility.tags.Contains(fieldValue))
                        {
                            yield return(createError.badTextFieldTag(fieldHierarchy.asString()));
                        }
                    }
                }
                if (fi.isSerializable())
                {
                    var fieldValue = fi.GetValue(objectBeingValidated);
                    var hasNotNull = fi.hasAttribute <NotNullAttribute>();
                    // Sometimes we get empty unity object. Equals catches that
                    if (fieldValue == null || fieldValue.Equals(null))
                    {
                        if (hasNotNull)
                        {
                            yield return(createError.nullField(fieldHierarchy.asString()));
                        }
                    }
                    else
                    {
                        var listOpt = F.opt(fieldValue as IList);
                        if (listOpt.isSome)
                        {
                            var list = listOpt.get;
                            if (list.Count == 0 && fi.hasAttribute <NonEmptyAttribute>())
                            {
                                yield return(createError.emptyCollection(fieldHierarchy.asString()));
                            }
                            var fieldValidationResults = validateFields(
                                containingComponent, list, fi, hasNotNull,
                                fieldHierarchy, createError, customObjectValidatorOpt
                                );
                            foreach (var _err in fieldValidationResults)
                            {
                                yield return(_err);
                            }
                        }
                        else
                        {
                            var fieldType = fi.FieldType;
                            // Check non-primitive serialized fields.
                            if (
                                !fieldType.IsPrimitive &&
                                fieldType.hasAttribute <SerializableAttribute>()
                                )
                            {
                                var validationErrors = validateFields(
                                    containingComponent, fieldValue, createError,
                                    customObjectValidatorOpt, fieldHierarchy
                                    );
                                foreach (var _err in validationErrors)
                                {
                                    yield return(_err);
                                }
                            }
                        }
                    }
                }
                fieldHierarchy.stack.Pop();
            }
        }