protected virtual void ValidateParameterType(CompositeValidationResult result, CompositeModel compositeModel, AbstractMemberInfoModel <MemberInfo> memberModel, AbstractInjectableModel injectableModel, Type type) { if (this.IsCompositeTypeAffectingInjection(injectableModel.InjectionScope)) { Stack <Type> stk = new Stack <Type>(); stk.Push(type); while (stk.Any()) { Type current = stk.Pop(); if (current.IsGenericParameter && current #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .DeclaringMethod != null) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Injection scopes affecting composite type (like " + typeof(ThisAttribute) + ", " + typeof(ConcernForAttribute) + ", or " + typeof(SideEffectForAttribute) + " are not allowed on method argument, which is referencing a generic method parameter.", compositeModel, memberModel)); } else if (!current.IsGenericParameter && current.ContainsGenericParameters()) { foreach (Type gArg in current.GetGenericArguments()) { stk.Push(gArg); } } } } }
protected virtual void ValidateConstraintModel(CompositeValidationResult result, CompositeModel model, ConstraintModel constraint) { if (constraint.ConstraintType == null) { result.InternalValidationErrors.Add(ValidationErrorFactory.NewInternalError("Constraint model had null as constraint type", constraint)); } }
private TypeBindingInformationState NewTypeBindingInformation( CompositeValidationResultMutable vResult, CollectionsFactory collectionsFactory, CompositeModel compositeModel, AbstractInjectableModel injModel, Type nInfo, Type type, Type declaringType, IDictionary <Type, TypeBindingInformationState> privateComposites ) { TypeBindingInformationState state = new TypeBindingInformationState(collectionsFactory); state.NativeInfo = nInfo.GetGenericDefinitionIfContainsGenericParameters(); ListProxy <ListProxy <AbstractGenericTypeBinding> > bindings = collectionsFactory.NewListProxy <ListProxy <AbstractGenericTypeBinding> >(); Boolean allBindingsOK = this.NewGenericTypeBinding(collectionsFactory, compositeModel, type, declaringType, bindings, privateComposites); if (allBindingsOK) { state.Bindings.AddRange(bindings.CQ); } else if (vResult != null) { vResult.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Failed to deduce generic bindings for " + (injModel == null ? (Object)type : injModel) + ".", compositeModel, injModel as AbstractMemberInfoModel <Object>)); } return(allBindingsOK ? state : null); }
public IEnumerable <ValidationResult> Validate(ValidationContext validationContext) { if (!IsChecked) { yield return(ValidationErrorFactory.CreateValidationResult <TestViewModel7>(validationContext, "Value is required when the field is checked!", vm => vm.IsChecked)); } }
protected override void PostValidateModel(CompositeModel compositeModel, CompositeValidationResult validationResult) { ServiceCompositeModel sModel = (ServiceCompositeModel)compositeModel; if (sModel.PublicTypes.Any(pType => pType.ContainsGenericParameters())) { validationResult.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("All the generic arguments of service composite's all public types must be closed.", compositeModel)); } }
public void GetPathFromExpression_WithPrimitiveLocal_CorrectExpression() { var index = 1; var expression = ValidationErrorFactory.GetPathFromExpression( DotvvmTestHelper.DefaultConfig, (Expression <Func <TestViewModel, int> >)(vm => vm.Numbers[index])); Assert.AreEqual("Numbers()[1]", expression); }
protected virtual void ValidateCompositeTypeModel(CompositeValidationResult result, CompositeModel compositeModel) { // TODO validate that none of fragments have abstract non-composite methods. if (compositeModel.PublicTypes.Any()) { Type firstType = compositeModel.PublicTypes.First(); Type[] gArgs = firstType.GetGenericArguments(); Int32 gArgsCount = gArgs.Length; foreach (Type cType in compositeModel.GetAllCompositeTypes()) { this.ValidateCompositeType(result, compositeModel, cType); } foreach (Type fType in compositeModel.GetAllFragmentTypes()) { this.ValidateFragmentType(result, compositeModel, fType); } foreach (Type type in compositeModel.PublicTypes) { this.ValidateCompositeType(result, compositeModel, type); Type[] typeGargs = type.GetGenericArguments(); Int32 typeCount = typeGargs.Length; if (typeCount > 0) { if (type.IsGenericTypeDefinition() != firstType.IsGenericTypeDefinition() || typeGargs.Take(Math.Min(gArgsCount, typeCount)).Where((tGArg, idx) => tGArg.IsGenericParameter != gArgs[idx].IsGenericParameter).Any()) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("All type interfaces must be either genericless, generic type definitions, or having all generic parameters closed.", compositeModel)); } else { // TODO generic arguments constraints } } } if (compositeModel.PublicTypes.Count(pType => !pType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsInterface) > 1) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Composite types must contain at most one class, but found the following classes:\n" + String.Join(", ", compositeModel.PublicTypes.Select(pType => !pType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsInterface)), compositeModel)); } } else { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Composite must have at least one public type", compositeModel)); } }
protected virtual void ValidateFragmentMethod(CompositeValidationResult result, CompositeModel compositeModel, CompositeMethodModel compositeMethod, AbstractFragmentMethodModel methodModel) { if (compositeMethod == null) { result.InternalValidationErrors.Add(ValidationErrorFactory.NewInternalError("Composite method model may not be null.", compositeModel)); } if (methodModel != null) { var declType = methodModel.NativeInfo.DeclaringType; if (!declType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsClass) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The declaring type of fragment method " + methodModel.NativeInfo + " must be a class, however " + declType + " is not a class.", compositeModel, compositeMethod)); } if (!methodModel.IsGeneric && (!methodModel.NativeInfo.IsVirtual || methodModel.NativeInfo.IsFinal)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The method " + methodModel.NativeInfo + " in " + declType + " is not virtual, however, all composite methods must be virtual.", compositeModel, methodModel)); } if (declType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsSealed) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The type " + declType + " is sealed, however, all fragment types must be non-sealed.", compositeModel, methodModel)); } //if ( !declType.IsPublic && !declType.IsNestedPublic ) //{ // String msg = null; // if ( methodModel.NativeInfo.IsAssembly || methodModel.NativeInfo.IsFamilyOrAssembly ) // { // if ( !declType.Assembly.GetCustomAttributes( true ).OfType<InternalsVisibleToAttribute>().Any( attr => Qi4CSGeneratedAssemblyAttribute.ASSEMBLY_NAME.Equals( attr.AssemblyName ) ) ) // { // msg = "The type " + declType + " is marked as internal, however, the " + typeof( InternalsVisibleToAttribute ) + " with argument " + typeof( Qi4CSGeneratedAssemblyAttribute ) + ".ASSEMBLY_NAME is not applied to the assembly"; // } // } // else // { // msg = "The type " + declType + " is not visible to the generated assembly."; // } // if ( msg != null ) // { // result.AddStructureError( new StructureValidationErrorImpl( compositeModel, methodModel, msg ) ); // } //} var genName = Qi4CSGeneratedAssemblyAttribute.GetGeneratedAssemblyName(declType.GetAssembly()); if (!IsTypeVisible(declType, genName)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The type " + declType + " is not visible. Consider either making it public, or internal with combination of applying " + typeof(InternalsVisibleToAttribute) + " with argument " + typeof(Qi4CSGeneratedAssemblyAttribute) + ".ASSEMBLY_NAME to the assembly.", compositeModel, methodModel)); } } }
protected virtual void ValidateField(CompositeValidationResult result, CompositeModel compositeModel, FieldModel fieldModel) { if (fieldModel == null) { result.InternalValidationErrors.Add(ValidationErrorFactory.NewInternalError("Field model may not be null.", compositeModel)); } else { this.ValidateInjectableModel(result, compositeModel, fieldModel); } }
public void GetPathFromExpression_WithComplexLocal_CorrectExpression() { var sample = new Sample { Index = 42 }; var complex = ValidationErrorFactory.GetPathFromExpression( DotvvmTestHelper.DefaultConfig, (Expression <Func <TestViewModel, int> >)(vm => vm.Numbers[sample.Index])); Assert.AreEqual("Numbers()[42]", complex); }
protected virtual void ValidateCompositeType(CompositeValidationResult result, CompositeModel compositeModel, Type compositeType) { if (!compositeType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsInterface&& !compositeType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsClass) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Composites must be interfaces or class; the composite " + compositeType + " however is neither.", compositeModel)); } }
public override void ValidateModelsInApplication(ApplicationModel <ApplicationSPI> appModel, ApplicationValidationResultMutable appValidation) { var sModels = appModel.CompositeModels.Values.OfType <ServiceCompositeModel>().ToArray(); if (sModels.Any(sModel => sModel.ServiceID == null)) { appValidation.InternalValidationErrors.Add(ValidationErrorFactory.NewInternalError("The following service composite models had their service ID as null: " + String.Join(", ", sModels.Where(sModel => sModel.ServiceID == null)), null)); } else { var grouping = sModels.GroupBy(sModel => sModel.ServiceID).Where(g => g.Count() > 1).ToArray(); if (grouping.Length > 0) { appValidation.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The following services have same service ID: " + String.Join("; ", grouping.Select(g => String.Join(", ", g))), appModel)); } } }
private static void ValidateGameObjectInternal(GameObject gameObject, object contextObject, bool recursive, ref List <IValidationError> validationErrors, HashSet <object> validatedObjects = null) { if (recursive) { validatedObjects = validatedObjects ?? new HashSet <object>(); validatedObjects.Add(gameObject); } if (IsIgnored(gameObject, contextObject)) { return; } Queue <GameObject> queue = new Queue <GameObject>(); queue.Enqueue(gameObject); while (queue.Count > 0) { GameObject current = queue.Dequeue(); Component[] components = current.GetComponents <Component>(); if (components == null) { continue; } foreach (Component c in components) { if (c == null) { validationErrors = validationErrors ?? new List <IValidationError>(); validationErrors.Add(ValidationErrorFactory.Create(gameObject, contextObject)); continue; } ValidateInternal(c, contextObject, recursive, ref validationErrors, validatedObjects); } foreach (GameObject child in current.GetChildren()) { queue.Enqueue(child); } } }
protected virtual void ValidatePropertyModel(CompositeValidationResult result, CompositeModel model, PropertyModel property) { if (property.IsPartOfCompositeState()) { UseDefaultsAttribute udAttr; if (property.IsUseDefaults(out udAttr)) { if (udAttr.ActualType != null && !property.NativeInfo.PropertyType.IsAssignableFrom(udAttr.ActualType)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The type " + property.NativeInfo.PropertyType + " of " + property.NativeInfo + " is not assignable from type given to " + typeof(UseDefaultsAttribute) + " constructor ( " + udAttr.ActualType + ").", model, property)); } else if (property.NativeInfo.PropertyType.IsGenericParameter) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The type " + property.NativeInfo.PropertyType + " of " + property.NativeInfo + " is marked with " + typeof(UseDefaultsAttribute) + " but it is generic type parameter.", model, property)); } } } }
protected virtual void ValidateEventModel(CompositeValidationResult result, CompositeModel compositeModel, EventModel eventModel) { if (!typeof(MulticastDelegate).IsAssignableFrom(eventModel.NativeInfo.EventHandlerType)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("All event types must be sub-types of " + typeof(MulticastDelegate) + ".", compositeModel, eventModel)); } else { IEnumerable <EventInvocationStyleAttribute> attrs = eventModel.AllAttributes.OfType <EventInvocationStyleAttribute>(); if (attrs.Count() > 1) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Maximum of one " + typeof(EventInvocationStyleAttribute) + " may be applied on event.", compositeModel, eventModel)); } else { EventInvocationStyleAttribute attr = attrs.FirstOrDefault(); if (attr != null && attr.RethrowException != null) { if (!typeof(Exception).IsAssignableFrom(attr.RethrowException)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The exception type must be derived from " + typeof(Exception), compositeModel, eventModel)); } else if (attr.RethrowException.GetConstructor(new Type[] { typeof(Exception[]) }) == null) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The exception to rethrow on event " + eventModel + " invocation must have a public constructor with the following parameters: " + typeof(Exception[]) + ".", compositeModel, eventModel)); } } } } //else //{ // Type[] violatingTypes = this.GetAllFragmentMethodsOf( eventModel.AddMethod ) // .Concat( this.GetAllFragmentMethodsOf( eventModel.RemoveMethod ) ) // .Where( fMethod => !fMethod.NativeInfo.IsAbstract ) // .Select( fMethod => fMethod.NativeInfo.DeclaringType ) // .Distinct() // .ToArray(); // if ( violatingTypes.Any() ) // { // result.AddStructureError( new StructureValidationErrorImpl( compositeModel, eventModel, "The following fragment types have non-abstract event declaration: " + String.Join( ", ", (Object[]) violatingTypes ) + "." ) ); // } //} }
protected override void ValidateApplicationModel(ApplicationValidationResultMutable result) { // Detect cyclic layer dependencies // Perform DFS for each layer var violatingLayers = new HashSet <LayerModel>(); foreach (var layerModel in this.AllLayers) { var seen = new HashSet <LayerModel>(); var stk = new Stack <LayerModel>(); stk.Push(layerModel); while (stk.Any()) { LayerModel current = stk.Pop(); seen.Add(current); var allUsed = current.UsedLayerModels; foreach (LayerModel used in allUsed) { if (seen.Contains(used)) { // Loop detected violatingLayers.Add(layerModel); stk.Clear(); break; } else { stk.Push(used); } } if (!allUsed.Any()) { seen.Remove(current); } } } foreach (var violatingLayer in violatingLayers) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The following layer has cyclic dependencies: " + violatingLayer.LayerName + ".", this)); } }
protected virtual void ValidateFragmentType(CompositeValidationResult result, CompositeModel compositeModel, Type fragmentType) { if (!fragmentType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsClass) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Fragments must be classes; the fragment " + fragmentType + " however is not a class.", compositeModel)); } else { var baseTypes = new HashSet <Type>(fragmentType.GetAllParentTypes()); baseTypes.Remove(fragmentType); if (fragmentType #if WINDOWS_PHONE_APP .GetTypeInfo() #endif .IsAbstract) { foreach (var fMethod in fragmentType.GetAllInstanceMethods()) { if (fMethod.IsAbstract && !compositeModel.Methods.Any(cMethod => AreSameFragmentMethods(fMethod, ReflectionHelper.FindMethodImplicitlyImplementingMethod(fragmentType, cMethod.NativeInfo)))) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Found abstract method " + fMethod + " in " + fragmentType + ", with no corresponding composite method.", compositeModel)); } } } foreach (var baseType in baseTypes) { if (baseType.IsGenericType()) { var baseTypeGDef = baseType.GetGenericTypeDefinition(); if (compositeModel.GetAllCompositeTypes().Except(compositeModel.PublicTypes).SelectMany(cType => cType.GetAllParentTypes()).Any(pType => pType.GetGenericDefinitionIfGenericType().Equals(baseTypeGDef)) && baseType.GetGenericArguments().Any(gArg => gArg.IsArray || gArg.IsByRef || gArg.IsPointer)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Fragment type implements composite type with either array, by ref or pointer generic argument. This is not allowed, as fragment might not be instantiatable in cases of non-array or non-by-ref or non-pointer generic argument of composite type.", compositeModel)); } } } } }
protected virtual void ValidateSpecialMethodModel(CompositeValidationResult result, CompositeModel compositeModel, SpecialMethodModel methodModel) { if (methodModel.NativeInfo.IsGenericMethodDefinition) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Special methods can not be generic method definitions.", compositeModel, methodModel)); } else { var declType = methodModel.NativeInfo.DeclaringType; var genName = Qi4CSGeneratedAssemblyAttribute.GetGeneratedAssemblyName(declType.GetAssembly()); if ((methodModel.NativeInfo.IsAssembly || methodModel.NativeInfo.IsFamilyAndAssembly) && !IsTypeVisible(declType, genName)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The type " + declType + " is not visible. Consider either making it public, or internal with combination of applying " + typeof(InternalsVisibleToAttribute) + " with argument " + typeof(Qi4CSGeneratedAssemblyAttribute) + ".ASSEMBLY_NAME to the assembly.", compositeModel, methodModel)); } foreach (var pModel in methodModel.Parameters) { this.ValidateParameter(result, compositeModel, pModel); } } }
protected virtual void ValidateInjectableModel(CompositeValidationResult result, CompositeModel compositeModel, AbstractInjectableModel model) { Int32 amount = model.GetAttributesMarkedWith(typeof(InjectionScopeAttribute)).Count; if (amount > 1) { result.InjectionValidationErrors.Add(ValidationErrorFactory.NewInjectionError("Only one injection permitted for field or parameter.", model)); } else { Attribute attr = model.InjectionScope; if (attr != null) { InjectionService injectionService = compositeModel.ApplicationModel.InjectionService; if (injectionService.HasFunctionalityFor(attr)) { if (!model.IsOptional) { var validationResult = injectionService.InjectionPossible(model); if (validationResult == null || !validationResult.InjectionPossible) { result.InjectionValidationErrors.Add(ValidationErrorFactory.NewInjectionError("Injection was not possible" + (validationResult == null ? "." : (": " + validationResult.AdditionalMessage)), model)); } } } else if (!model.IsOptional) { result.InjectionValidationErrors.Add(ValidationErrorFactory.NewInjectionError("Could not find injection functionality for attribute " + attr + ".", model)); } } else if (model is FieldModel) { result.InternalValidationErrors.Add(ValidationErrorFactory.NewInternalError("Injection attribute was null", model)); } } }
public void ModelState_ArrayAccessExpression() { Assert.AreEqual("AnotherProperty().TestViewModel2().Collection()[0]().StringValue", ValidationErrorFactory.CreateModelError(viewModel, v => v.AnotherProperty.TestViewModel2.Collection[0].StringValue, "").PropertyPath); }
private static void ValidateInternal(object obj, object contextObject, bool recursive, ref List <IValidationError> validationErrors, HashSet <object> validatedObjects = null) { if (obj == null) { return; } if (validatedObjects != null) { if (validatedObjects.Contains(obj)) { return; } validatedObjects.Add(obj); } Type objectType = obj.GetType(); var whitelistedNamespaces = ValidatorWhitelistedNamespaceProvider.GetWhitelistedNamespaces(); // if whitelisted asset exists - use whitelisting instead of blacklisting if (whitelistedNamespaces.Count > 0) { int ignoredNamespacesCount = ValidatorIgnoredNamespaceProvider.GetIgnoredNamespaces().Count; if (ignoredNamespacesCount > 0) { Debug.LogWarning("Both ValidatorIgnoredNamespace + ValidatorWhitelistedNamespace exist in project (mutually exclusive) - will only use whitelisted!"); } if (string.IsNullOrEmpty(objectType.Namespace)) { // No namespace means no validation in whitelist format return; } foreach (var whitelistedNamespace in whitelistedNamespaces) { if (!objectType.Namespace.Contains(whitelistedNamespace.Namespace)) { return; } } } else { if (!string.IsNullOrEmpty(objectType.Namespace)) { // allow user defined ignores for namespaces foreach (var validatorIgnoredNamespace in ValidatorIgnoredNamespaceProvider.GetIgnoredNamespaces()) { if (validatorIgnoredNamespace == null) { Debug.LogWarning("Bad state - validatorIgnoredNamespace is null!"); continue; } if (objectType.Namespace.Contains(validatorIgnoredNamespace.Namespace)) { return; } } } } foreach (FieldInfo fieldInfo in TypeUtil.GetInspectorFields(objectType) .Where(f => typeof(UnityEventBase).IsAssignableFrom(f.FieldType)) .Where(f => !Attribute.IsDefined(f, typeof(OptionalAttribute)) && !Attribute.IsDefined(f, typeof(HideInInspector)))) { // NOTE (darren): check UnityEvents for all classes UnityEventBase unityEvent = (UnityEventBase)fieldInfo.GetValue(obj); if (unityEvent == null) { Debug.LogError("Unexpected null UnityEvent in GameObjectValidator!"); continue; } for (int i = 0; i < unityEvent.GetPersistentEventCount(); i++) { MethodInfo methodInfo = unityEvent.GetMethodInfoForIndex(i); if (methodInfo == null) { validationErrors = validationErrors ?? new List <IValidationError>(); validationErrors.Add(ValidationErrorFactory.Create(obj, objectType, fieldInfo, contextObject)); break; } } } bool whitelisted = ValidatorUnityWhitelist.IsTypeWhitelisted(objectType); if (kUnityAssemblies.Contains(objectType.Assembly) && !whitelisted) { return; } IEnumerable <MemberInfo> membersToCheck = null; if (whitelisted) { membersToCheck = ValidatorUnityWhitelist.GetWhitelistedMembersFor(objectType); } else { membersToCheck = TypeUtil.GetInspectorFields(objectType) .Where(f => !ValidatorBlacklistedClassProvider.GetBlacklistedClasses().Any(b => b.Class == f.DeclaringType.Name)) .Where(f => !Attribute.IsDefined(f, typeof(OptionalAttribute)) && !Attribute.IsDefined(f, typeof(HideInInspector))) .Where(f => !kUnityAssemblies.Contains(f.DeclaringType.Assembly)).Cast <MemberInfo>(); // NOTE (darren): this is to ignore fields that declared in super-classes out of our control (Unity) } foreach (MemberInfo memberInfo in membersToCheck) { IEnumerable <Predicate <object> > predicates = ValidatorPredicates.GetOptionalPredicatesFor(memberInfo); if (predicates != null) { bool shouldValidate = predicates.All(p => p.Invoke(obj)); if (!shouldValidate) { continue; } } IList <UnityEngine.Object> unityEngineObjects = GetUnityEngineObjects(memberInfo, obj); // TODO (darren): don't alloc memory for List<> if not necessary if (unityEngineObjects == null || unityEngineObjects.Count <= 0) { // NOTE (darren): if this is not a UnityEngine.Object // we might still have to recursively look through its fields // which might contain UnityEngine.Objects if (recursive) { IList <object> memberObjects = GetMemberObjects(memberInfo, obj); foreach (object memberObj in memberObjects) { // NOTE (darren): the LocalId is broken here because we lost // a reference to the original GameObject being validated // (as contextObject may be the scene for example). // Leaving this as-is as it's an edge case and nice-to-have. ValidateInternal(memberObj, contextObject, recursive, ref validationErrors, validatedObjects); } } continue; } int index = 0; foreach (UnityEngine.Object memberObject in unityEngineObjects) { if (memberObject == null) { validationErrors = validationErrors ?? new List <IValidationError>(); if (unityEngineObjects.Count > 1) { validationErrors.Add(ValidationErrorFactory.Create(obj, objectType, memberInfo, contextObject, index)); } else { validationErrors.Add(ValidationErrorFactory.Create(obj, objectType, memberInfo, contextObject)); } index++; continue; } if (recursive) { GameObject memberObjectAsGameObject = memberObject as GameObject; if (memberObjectAsGameObject != null) { PrefabType prefabType = PrefabUtility.GetPrefabType(memberObjectAsGameObject); if (prefabType == PrefabType.Prefab) { // switch context to the prefab we just recursed to object newContextObject = memberObjectAsGameObject; validatedObjects = validatedObjects ?? new HashSet <object>() { obj }; ValidateGameObjectInternal(memberObjectAsGameObject, newContextObject, recursive, ref validationErrors, validatedObjects); } } ScriptableObject memberObjectAsScriptableObject = memberObject as ScriptableObject; if (memberObjectAsScriptableObject != null) { // switch context to the scriptable object we just recursed to object newContextObject = memberObjectAsScriptableObject; validatedObjects = validatedObjects ?? new HashSet <object>() { obj }; ValidateInternal(memberObjectAsScriptableObject, newContextObject, recursive, ref validationErrors, validatedObjects); } } index++; } } }
public void ModelState_SingleRenamedProperty() { Assert.AreEqual("rp", ValidationErrorFactory.CreateModelError(viewModel, v => v.RenamedProperty, "").PropertyPath); }
public void ModelState_NestedViewModelExpression() { Assert.AreEqual("AnotherProperty().StringProp", ValidationErrorFactory.CreateModelError(viewModel, v => v.AnotherProperty.StringProp, "").PropertyPath); }
private string GetNumbers(int index) { return(ValidationErrorFactory.GetPathFromExpression( DotvvmTestHelper.DefaultConfig, (Expression <Func <TestViewModel, int> >)(vm => vm.Numbers[index]))); }
public void ModelState_SinglePropertyExpression() { Assert.AreEqual("MyProperty", ValidationErrorFactory.CreateModelError(viewModel, v => v.MyProperty, "").PropertyPath); }
private static ValidationErrorCollection BuildValidationErrorCollection(ErrorBlock errorBlock, ValidationErrorFactory errorFactory, ValidationErrorCollectionFactory errorCollectionFactory, List <string> path) { return(errorCollectionFactory(path, errorBlock.Errors == null ? new List <ValidationError>() : errorBlock.Errors.Select(error => errorFactory(path, error.Code, error.Format, error.Args)), errorBlock.Contents == null ? new List <KeyValuePair <string, ValidationErrorCollection> >() : errorBlock.Contents.Select( entry => new KeyValuePair <string, ValidationErrorCollection>(entry.Key, BuildValidationErrorCollection(entry.Value, errorFactory, errorCollectionFactory, path.Append(entry.Key).ToList()))))); }
public static RequestException ToRequestException(this ConnectionResponseException connectionException, string message, object request, ValidationErrorFactory errorFactory = null, ValidationErrorCollectionFactory errorCollectionFactory = null) { using (var response = connectionException.Response) { RequestException ex; if (response.Code == 500) { string content; try { var error = response.ReadAsStreamAsync(); error.Wait(); using (var streamReader = new StreamReader(error.Result)) { content = streamReader.ReadToEnd(); } } catch (Exception e) { content = $"Error reading error content: {e.Message}"; } ex = new RequestException($"Internal Server Error: {message}{Environment.NewLine}{content}"); ex.Data["request"] = request; return(ex); } else { try { var error = response.ReadAsync <API.CommonJson.ErrorResponse>(); error.Wait(); ex = error.Result.ToValidationException(errorFactory, errorCollectionFactory); ex.Data["request"] = request; } catch (AggregateException e) { ex = new RequestException($"Unexpected Response format. Http Code {response.Code}. {message}", e.InnerException); ex.Data["request"] = request; } } return(ex); } }
public CompositeTypeModelImpl(CompositeModel compositeModel, CompositeValidationResultMutable vResult) { var collectionsFactory = compositeModel.ApplicationModel.CollectionsFactory; this._publicCompositeGenericArguments = collectionsFactory.NewListProxy(GetCompositeModelPublicTypeGenericArguments(compositeModel).ToList()).CQ; var injThisTypes = compositeModel.GetAllInjectableModelsWithInjectionScope <ThisAttribute>() .Select(inj => new ThisTypeInfo(inj)) .ToArray(); var thisTypesInModel = compositeModel.Methods .Select(m => m.NativeInfo.DeclaringType) .Concat(compositeModel.PublicTypes) .Concat(injThisTypes.Select(inj => inj.resolvedTargetType)) .Concat(compositeModel.GetAllFragmentTypes().SelectMany(ft => ft.GetAllParentTypes(false))) .GetBottomTypes(); foreach (var injThisType in injThisTypes) { injThisType.resolvedTargetTypeFromModel = thisTypesInModel.First(tType => injThisType.resolvedTargetType.GetGenericDefinitionIfContainsGenericParameters().IsAssignableFrom_IgnoreGenericArgumentsForGenericTypes(tType)); } var thisTypesToProcess = new HashSet <ThisTypeInfo>(injThisTypes.GetBottomTypes(model => model.resolvedTargetType).Distinct(INJECTABLE_MODEL_EQ_COMPARER)); thisTypesToProcess.ExceptWith(thisTypesToProcess.Where(type => compositeModel.PublicTypes.Any(role => type.resolvedTargetType.GetGenericDefinitionIfGenericType().IsAssignableFrom_IgnoreGenericArgumentsForGenericTypes(role))).ToArray()); // TODO check that if type binding has more than one list with indirect bindings -> throw or add error. var privateComposites = new Dictionary <Type, TypeBindingInformationState>(); while (thisTypesToProcess.Any()) { var processedTypes = new HashSet <ThisTypeInfo>(GDEF_EQ_COMPARER); foreach (var thisType in thisTypesToProcess) { if (this.ModifyTypeBindingInfoDictionary(privateComposites, this.NewTypeBindingInformation(null, collectionsFactory, compositeModel, null, thisType.resolvedTargetTypeFromModel, thisType.resolvedTargetType, GetBottommostDeclaringType(thisType.model), privateComposites))) { processedTypes.Add(thisType); } } thisTypesToProcess.ExceptWith(thisTypesToProcess.Where(t => processedTypes.Any(p => t.resolvedTargetType.GetGenericDefinitionIfContainsGenericParameters().Equals(p.resolvedTargetType.GetGenericDefinitionIfContainsGenericParameters()))).ToArray()); if (processedTypes.Count == 0) { // We are stuck vResult.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Could not deduce generic bindings for types " + String.Join(", ", thisTypesToProcess.Select(ttp => ttp.resolvedDeclaringType)), compositeModel)); break; } else { processedTypes.Clear(); } } var fragmentTypeInfos = new Dictionary <Type, TypeBindingInformationState>(); foreach (var fragmentType in compositeModel.GetAllFragmentTypes()) { // TODO check - if any parent is public or private composite type (genericdefifgenerictype), error if (fragmentType.IsGenericType()) { var it = FindImplementingTypeFrom(fragmentType, compositeModel.PublicTypes); if (it != null || !fragmentType.ContainsGenericParameters()) { this.ModifyTypeBindingInfoDictionary(fragmentTypeInfos, this.NewTypeBindingInformation(vResult, collectionsFactory, compositeModel, null, fragmentType, fragmentType, fragmentType, privateComposites)); } else { // Private composite fragment // Process all base types + injectable models of this fragment, and all their generic arguments as DFS var dependentStates = Enumerable.Repeat <Tuple <Int32, TypeBindingInformationState> >(null, fragmentType.GetGenericArguments().Length).ToList(); foreach (var typeToProcess in fragmentType.GetAllParentTypes(false) .Concat( compositeModel.GetAllInjectableModels() .Where(inj => fragmentType.GetClassHierarchy().Contains(inj.DeclaringType)) .Select(inj => inj.TargetType) )) { if (dependentStates.Any(item => item == null)) { var gArgs = typeToProcess.GetGenericArguments(); for (var i = 0; i < gArgs.Length; ++i) { foreach (var typeOrGArg in gArgs[i].AsDepthFirstEnumerable(t => t.GetGenericArgumentsSafe())) { if (typeOrGArg.IsGenericParameter && dependentStates[typeOrGArg.GenericParameterPosition] == null) { TypeBindingInformationState other; if (!privateComposites.TryGetValue(typeToProcess.GetGenericDefinitionIfContainsGenericParameters(), out other) && compositeModel.PublicTypes.Contains(typeToProcess) ) { other = new TypeBindingInformationState(collectionsFactory); other.NativeInfo = typeToProcess; } if (other != null) { dependentStates[typeOrGArg.GenericParameterPosition] = Tuple.Create(i, other); } } } } } else { break; } } if (!dependentStates.Any(item => item == null)) { var state = new TypeBindingInformationState(collectionsFactory); state.NativeInfo = fragmentType; var max = Math.Max(1, dependentStates.Max(dState => dState.Item2.Bindings.CQ.Count)); if (dependentStates.Select(dState => dState.Item2.Bindings.CQ.Count).Where(c => c > 1).Distinct().Count() > 1) { throw new NotImplementedException("Very complex private type binding is not yet supported."); } else { for (var i = 0; i < max; ++i) { state.Bindings.Add(collectionsFactory.NewListProxy(dependentStates.Select(dState => { AbstractGenericTypeBinding gtb; if (dState.Item2.Bindings.CQ.Any()) { // Private composite binding gtb = dState.Item2.Bindings.CQ[i].CQ[dState.Item1]; } else { var iState = new IndirectGenericTypeBindingState(); iState.GenericDefinition = dState.Item2.NativeInfo.GetGenericDefinitionIfGenericType(); iState.GenericIndex = dState.Item1; gtb = new IndirectGenericTypeBindingImpl(iState); } return(gtb); }).ToList())); } this.ModifyTypeBindingInfoDictionary(fragmentTypeInfos, state); } } } } else { var state = new TypeBindingInformationState(collectionsFactory); state.NativeInfo = fragmentType; this.ModifyTypeBindingInfoDictionary(fragmentTypeInfos, state); } } this._fragmentTypeInfos = collectionsFactory.NewDictionaryProxy(fragmentTypeInfos.ToDictionary(kvp => kvp.Key, kvp => (TypeBindingInformation) new TypeBindingInformationImpl(kvp.Value))).CQ; this._concernInvocationTypeInfos = collectionsFactory.NewDictionaryProxy(this.CreateInvocationInfos <ConcernForAttribute>(vResult, collectionsFactory, compositeModel, privateComposites).ToDictionary(kvp => kvp.Key, kvp => (TypeBindingInformation) new TypeBindingInformationImpl(kvp.Value))).CQ; this._sideEffectInvocationTypeInfos = collectionsFactory.NewDictionaryProxy(this.CreateInvocationInfos <SideEffectForAttribute>(vResult, collectionsFactory, compositeModel, privateComposites).ToDictionary(kvp => kvp.Key, kvp => (TypeBindingInformation) new TypeBindingInformationImpl(kvp.Value))).CQ; this._privateCompositeTypeInfos = collectionsFactory.NewDictionaryProxy(privateComposites.ToDictionary(kvp => kvp.Key, kvp => (TypeBindingInformation) new TypeBindingInformationImpl(kvp.Value))).CQ; }
public static ValidationException ToValidationException(this API.CommonJson.ErrorResponse errorResponse, ValidationErrorFactory errorFactory = null, ValidationErrorCollectionFactory errorCollectionFactory = null) { return(new ValidationException(errorResponse.Message, errorResponse.Code, errorResponse.Details.ToValidationErrorCollection(errorFactory, errorCollectionFactory))); }
public virtual void ValidateComposite(CompositeValidationResultMutable result, CompositeModel compositeModel) { // TODO check that all keys of the type model CompositeTypeInformations and FragmentTypeInformations are assignable from all methods of the composite model. this.ValidateCompositeTypeModel(result, compositeModel); if (compositeModel.MainCodeGenerationType == null) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Composite model main code generation type was null", compositeModel)); } else if (!compositeModel.PublicTypes.Contains(compositeModel.MainCodeGenerationType)) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Composite model main code generation type " + compositeModel.MainCodeGenerationType + " was not contained in its public types (" + String.Join(", ", compositeModel.PublicTypes) + ").", compositeModel)); } else { CompositeMethodModel[] unimplementedMethods = compositeModel.Methods .Where(methodModel => methodModel.Mixin == null) .ToArray(); if (unimplementedMethods.Any()) { foreach (CompositeMethodModel unimplementedMethod in unimplementedMethods) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("No implementation found for " + unimplementedMethod.NativeInfo + ".", compositeModel, unimplementedMethod)); } } else { foreach (FieldModel fieldModel in compositeModel.Fields) { this.ValidateField(result, compositeModel, fieldModel); } foreach (ConstructorModel constructorModel in compositeModel.Constructors) { foreach (ParameterModel parameterModel in constructorModel.Parameters) { this.ValidateParameter(result, compositeModel, parameterModel); } } foreach (CompositeMethodModel compositeMethod in compositeModel.Methods) { if (compositeMethod == null) { result.InternalValidationErrors.Add(ValidationErrorFactory.NewInternalError("Composite method model may not be null.", compositeModel)); } else { this.ValidateParameter(result, compositeModel, compositeMethod.Result); foreach (ParameterModel parameterModel in compositeMethod.Parameters) { this.ValidateParameter(result, compositeModel, parameterModel); } foreach (AbstractFragmentMethodModel fragmentMethod in compositeMethod.GetAllMethodModels().OfType <AbstractFragmentMethodModel>()) { this.ValidateFragmentMethod(result, compositeModel, compositeMethod, fragmentMethod); } foreach (ConstraintModel constraintModel in compositeMethod.Parameters.SelectMany(param => param.Constraints).Concat(compositeMethod.Result.Constraints)) { if (constraintModel.ConstraintType == null) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Could not bind parameter constraint " + constraintModel.ConstraintAttribute + ".", compositeModel, compositeMethod)); } else if (constraintModel.ConstraintType.GetConstructor(Empty <Type> .Array) == null) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Constraints must have constructor without parameters, but constraint of type " + constraintModel.ConstraintType + " does not.", compositeModel, compositeMethod)); } else if (constraintModel.ConstraintType.ContainsGenericParameters() && !constraintModel.ConstraintType.IsGenericTypeDefinition()) { result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Constraint type " + constraintModel.ConstraintType + " contains non-closed generic parameters but is not generic type definition.", compositeModel, compositeMethod)); } } } } foreach (var pModel in compositeModel.GetAllPropertyModels()) { this.ValidatePropertyModel(result, compositeModel, pModel); } foreach (SpecialMethodModel specialMethod in compositeModel.SpecialMethods) { this.ValidateSpecialMethodModel(result, compositeModel, specialMethod); } foreach (var constraintModel in compositeModel.GetAllConstraints()) { this.ValidateConstraintModel(result, compositeModel, constraintModel); } if (!result.IQ.HasAnyErrors()) { result.TypeModel = new CompositeTypeModelImpl(compositeModel, result); } } } }