public static ValidationErrors ValidateTypeReferences(this DataSchema schema, IEnumerable <string> predefinedTypes) { // note that predefined types can not collide with defined ones, they are overridden var typeNames = new HashSet <string>(schema.Types.Select(tt => tt.Name).Concat(predefinedTypes)); ValidationErrors validateRef(TypeRef t) => t.Match(actual: tt => typeNames.Contains(tt.TypeName) ? ValidationErrors.Valid : ValidationErrors.Create($"Type '{tt.TypeName}' is not defined."), nullable: tt => validateRef(tt.Type).Nest("type"), list: tt => validateRef(tt.Type).Nest("type") ); ValidationErrors validateFields(TypeField field) => validateRef(field.Type).Nest("type"); var typeErrors = schema.Types.ValidateList(type => type.Core.Match( primitive: p => ValidationErrors.Valid, union: u => u.Options.ValidateList(validateRef).Nest("options"), @interface: i => i.Fields.ValidateList(validateFields).Nest("fields"), composite: c => ValidationErrors.Join( c.Implements.ValidateList(validateRef).Nest("implements"), c.Fields.ValidateList(validateFields).Nest("fields") ) ).Nest("core")).Nest("types"); return(ValidationErrors.Join(typeErrors)); }
public static Either <DomainError, TR> ToEither <TR>(this Validation <ValidationError, TR> validation, string correlationId) => validation.ToEither().MapLeft(errors => (DomainError)ValidationErrors.Create(correlationId, errors));
public static Func <IL.ILInstruction> InitializeObject(IType expectedType, JToken json) { switch (json.Type) { case JTokenType.Integer: if (expectedType.IsKnownType(KnownTypeCode.Int32)) { return(() => new IL.LdcI4(json.Value <int>())); } else { goto default; } case JTokenType.Float: if (expectedType.IsKnownType(KnownTypeCode.Single)) { return(() => new IL.LdcF4(json.Value <float>())); } else if (expectedType.IsKnownType(KnownTypeCode.Double)) { return(() => new IL.LdcF8(json.Value <double>())); } else { goto default; } case JTokenType.String: if (expectedType.IsKnownType(KnownTypeCode.String)) { return(() => new IL.LdStr(json.Value <string>())); } else { goto default; } case JTokenType.Boolean: if (expectedType.IsKnownType(KnownTypeCode.Boolean)) { return(() => new IL.LdcI4(json.Value <bool>() ? 1 : 0)); } else { goto default; } case JTokenType.Null: if (expectedType.IsReferenceType == true || expectedType.GetDefinition().IsKnownType(KnownTypeCode.NullableOfT)) { return(() => new IL.LdNull()); } else { goto default; } case JTokenType.Undefined: case JTokenType.Date: case JTokenType.Raw: case JTokenType.Bytes: case JTokenType.Guid: case JTokenType.Uri: case JTokenType.TimeSpan: case JTokenType.None: case JTokenType.Object: case JTokenType.Array: case JTokenType.Constructor: case JTokenType.Property: case JTokenType.Comment: default: throw new ValidationErrorException(ValidationErrors.Create($"Json token of type {json.Type} is not supported when type {expectedType.FullName} is expected.")); } }
static partial void ValidateObjectExtension(ref ValidationErrorsBuilder e, MethodDef obj) { if (obj.Implements.IsDefault) { e.AddErr("default(ImmutableArray<...>) is not allowed value", "implements"); } var sgn = obj.Signature; if (obj.Body is object && obj.Body.Type() != sgn.ResultType) { e.Add(ValidationErrors.Create($"Method body was expected to return {sgn.ResultType}, not {obj.Body.Type()}").Nest("body")); // TODO: expression type validation } var isWithoutBody = obj.Signature.IsAbstract || obj.Signature.DeclaringType.Kind == "interface"; if (obj.Body is null && !isWithoutBody) { e.Add(ValidationErrors.Create($"Method is not abstract, so it must contain a body.")); } if (obj.Body is object && isWithoutBody) { e.Add(ValidationErrors.Create($"Method is abstract, so it must not contain a body. Did you intent to use MethodDef.InterfaceDef?")); } if (!isWithoutBody) { if (obj.ArgumentParams.IsDefault) { e.AddErr("default(ImmutableArray<...>) is not allowed value", "argumentParams"); } var expectedArgs = obj.Signature.Params.Select(p => p.Type).ToImmutableArray(); if (!sgn.IsStatic) { expectedArgs = expectedArgs.Insert(0, sgn.DeclaringType.SpecializeByItself()); } if (obj.ArgumentParams.Length != expectedArgs.Length) { e.Add(ValidationErrors.Create($"Expected {expectedArgs.Length} arguments, got {obj.ArgumentParams.Length}: {FmtToken.FormatArray(obj.ArgumentParams)}").Nest("length").Nest("argumentParams")); } for (int i = 0; i < Math.Min(obj.ArgumentParams.Length, expectedArgs.Length); i++) { if (obj.ArgumentParams[i].Type.UnwrapReference() != expectedArgs[i].UnwrapReference()) { e.Add(ValidationErrors.Create($"Argument type {expectedArgs[i]} was expected instead of {obj.ArgumentParams[i].Type}.") .Nest("type").Nest(i.ToString()).Nest("argumentParams") ); } } if (!sgn.IsStatic) { var firstArgument = obj.ArgumentParams.First(); if (sgn.DeclaringType.IsValueType) { if (TypeReference.ByReferenceType(sgn.DeclaringType.SpecializeByItself()) != firstArgument.Type) { e.AddErr($"Method on value type should have this of a reference type: {firstArgument.Type}&", "argumentParams", "0", "type"); } } } } // TODO: deep validate expression in the context }
private DomainError CreateValidationError() { var error = new ValidationError(nameof(TryGet), new[] { "Seasons list is empty" }); return(ValidationErrors.Create($"{nameof(GetLatestSeasonHandler)}.{nameof(TryGet)}", new[] { error })); }