static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, MethodSignature m) { if (m.Params.IsDefault) { e.AddErr("default(ImmutableArray<...>) is not allowed value", "params"); } if (m.IsConstructor() && m.IsStatic) { e.Add(ValidationErrors.Create($"Constructor '{m}' can't be static").Nest("isStatic")); } if (m.IsStaticConstructor() && !m.IsStatic) { e.Add(ValidationErrors.Create($"Static constructor '{m}' must be static").Nest("isStatic")); } if (m.IsAbstract && m.DeclaringType?.IsAbstract == false) { e.Add(ValidationErrors.Create($"Can not declare abstract method in {m.DeclaringType}").Nest("isAbstract")); } if (m.IsAbstract && !m.IsVirtual) { e.Add(ValidationErrors.Create($"Can not declare abstract method that is not virtual").Nest("isVirtual")); } if (m.Accessibility == Accessibility.APrivate && (m.IsVirtual || m.IsOverride)) { e.Add(ValidationErrors.Create($"Can not declare virtual or override method that is private").Nest("accessibility")); } if (m.IsStatic) { if (m.IsVirtual) { e.Add(ValidationErrors.Create($"Can not declare virtual static method").Nest("isVirtual")); } if (m.IsOverride) { e.Add(ValidationErrors.Create($"Can not declare override static method").Nest("isOverride")); } if (m.IsAbstract) { e.Add(ValidationErrors.Create($"Can not declare abstract static method").Nest("isAbstract")); } } if (!m.DeclaringType.CanOverride) { if (m.IsVirtual) { e.Add(ValidationErrors.Create($"Can not declare virtual method in {m.DeclaringType}").Nest("isVirtual")); } // if (m.IsOverride) e.Add(ValidationErrors.Create($"Can not declare override method in {m.DeclaringType}").Nest("isOverride")); if (m.IsAbstract) { e.Add(ValidationErrors.Create($"Can not declare abstract method in {m.DeclaringType}").Nest("isAbstract")); } if (m.DeclaringType.IsAbstract && !m.IsStatic) { e.Add(ValidationErrors.Create($"Can not declare non-stattic method in {m.DeclaringType}").Nest("isStatic")); } } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, FieldAccessExpression obj) { if (obj.Field is null) { return; } var f = obj.Field; if (f.Signature.IsStatic && obj.Target is object) { e.Add(ValidationErrors.Create($"Static field must not have target set.").Nest("target")); } if (!f.Signature.IsStatic && obj.Target is null) { e.Add(ValidationErrors.Create($"Instance fields must have target set.").Nest("target")); } if (!f.Signature.IsStatic && obj.Target is object) { if (f.DeclaringType() != obj.Target.Type().UnwrapReference()) { e.Add(ValidationErrors.Create($"Instance field declared on '{f.DeclaringType()}' can not be invoked with target of type '{obj.Target.Type().UnwrapReference()}'").Nest("target")); } } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, NotExpression obj) { if (obj.Expr != null && obj.Expr.Type() != TypeSignature.Boolean) { e.Add(ValidationErrors.Create($"Not expression can only handle expr of type bool, not '{obj.Expr.Type()}'").Nest("expr")); // TODO: expression type validation } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, NewObjectExpression ne) { if (ne.Ctor is null) { return; } var m = ne.Ctor; if (!m.Signature.IsConstructor()) { e.Add(ValidationErrors.Create($"{m} must be a constructor").Nest("ctor")); } if (m.Signature.DeclaringType.IsAbstract) { e.Add(ValidationErrors.Create($"Can not create instance of abstract type '{m.DeclaringType()}'").Nest("isAbstract").Nest("signature").Nest("ctor")); } if (ne.Args.Length != m.Signature.Params.Length) { e.Add(ValidationErrors.Create($"Can not call constructor '{m}' with {ne.Args.Length} arguments.")); } else { var p = m.Params(); for (int i = 0; i < ne.Args.Length; i++) { if (ne.Args[i] is object && p[i].Type != ne.Args[i].Type()) { e.Add(ValidationErrors.Create($"Constructor '{m}' does not accept value of type {ne.Args[i].Type()}.").Nest(i.ToString()).Nest("args")); } } } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, InvokeExpression ie) { if (ie.Function is null) { return; } var ftype = (ie.Function.Type() as TypeReference.FunctionTypeCase)?.Item; if (ftype is null) { e.Add(ValidationErrors.Create($"Invoked function must be of function type, got '{ie.Function.Type()}'. Maybe, you can use FunctionConversion to convert delegate to a function type.").Nest("function")); return; } if (ie.Args.Length != ftype.Params.Length) { e.Add(ValidationErrors.Create($"Can not invoke function '{ftype}' with {ie.Args.Length} arguments.")); } else { var p = ftype.Params; for (int i = 0; i < p.Length; i++) { if (ie.Args[i] is object && p[i].Type != ie.Args[i].Type()) { e.Add(ValidationErrors.Create($"Function '{ftype}' does not accept value of type {ie.Args[i].Type()}.").Nest(i.ToString()).Nest("args")); } } } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, ConditionalExpression obj) { if (obj.Condition is object && obj.Condition.Type() != TypeSignature.Boolean) { e.Add(ValidationErrors.Create($"condition can only handle expr of type bool, not '{obj.Condition.Type()}'").Nest("condition")); } if (obj.IfFalse is object && obj.IfTrue is object && obj.IfFalse.Type() != obj.IfTrue.Type()) { e.Add(ValidationErrors.Create($"true and false branches must have the same type. true: '{obj.IfTrue.Type()}', false: '{obj.IfFalse.Type()}'").Nest("ifFalse")); } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, TypeDef t) { for (int i = 0; i < t.Members.Length; i++) { var sgn = t.Members[i].Signature; if (sgn.DeclaringType() != t.Signature) e.Add(ValidationErrors.Create($"Can not contain member {sgn} with declaring type {sgn.DeclaringType()}.").Nest("declaringType").Nest("signature").Nest(i.ToString()).Nest("members")); } if (t.Extends is SpecializedType { Type : var baseType })
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, SpecializedType t) { if (t.Type is null) { return; } var expectedCount = t.Type.TotalParameterCount(); if (expectedCount != t.TypeArguments.Length) { e.Add(ValidationErrors.Create($"Type {t.Type} expected {expectedCount} parameters, got [{string.Join(", ", t.TypeArguments)}]")); } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, PropertyReference p) { if (p.Signature is null) { return; } var expectedCount = p.Signature.DeclaringType.TotalParameterCount(); if (expectedCount != p.TypeArguments.Length) { e.Add(ValidationErrors.Create($"Type {p.Signature.DeclaringType} expected {expectedCount} parameters, got [{string.Join(", ", p.TypeArguments)}]")); } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, ReferenceAssignExpression obj) { if (obj.Target is null || obj.Value is null) { return; } var type = obj.Target.Type().UnwrapReference(); // the reference is checked by previous validations if (type != obj.Value.Type()) { e.Add(ValidationErrors.Create($"Can not assign '{obj.Value.Type()}' into reference '{obj.Target.Type()}'. The types must match")); } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, MethodCallExpression me) { if (me.Method is null) { return; } var m = me.Method; if (m.Signature.IsStatic && me.Target is object) { e.Add(ValidationErrors.Create($"Static method must not have target set.").Nest("target")); } if (!m.Signature.IsStatic && me.Target is null) { e.Add(ValidationErrors.Create($"Instance method must have target set.").Nest("target")); } if (!m.Signature.IsStatic && me.Target is object) { if (m.DeclaringType() != me.Target.Type().UnwrapReference()) { e.Add(ValidationErrors.Create($"Instance method declared on '{m.DeclaringType()}' can not be invoked with target of type '{me.Target.Type()}'").Nest("target")); } } if (me.Args.Length != m.Signature.Params.Length) { e.Add(ValidationErrors.Create($"Can not call method '{m}' with {me.Args.Length} arguments.")); } else { var p = m.Params(); for (int i = 0; i < me.Args.Length; i++) { if (me.Args[i] is object && p[i].Type != me.Args[i].Type()) { e.Add(ValidationErrors.Create($"Method '{m}' does not accept value of type {me.Args[i].Type()}.").Nest(i.ToString()).Nest("args")); } } } if (m.Signature.HasSpecialName) { e.Add(m.Signature.Name switch { ".cctor" => ValidationErrors.Create("Can not call static constructor from expression").Nest("signature").Nest("method"), ".ctor" => (me.Target is Expression.ParameterCase) || (me.Target is Expression.ReferenceConversionCase rce && rce.Item.Value is Expression.ParameterCase) ? null : ValidationErrors.Create("Constructor can only be invoked directly on this parameter").Nest("signature").Nest("method"), _ => null });
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, BreakExpression b) { if (e.HasErrors) { return; } if (b.Value.Type() != b.Target.Type) { e.Add(ValidationErrors.Create( $"BreakExpression has value of type {b.Value.Type()}, but must return the same type type as target {b.Target}" ).Nest("value")); // TODO: validation path for expression type } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, TypeSignature t) { if (t.IsValueType) { if (t.CanOverride) { e.Add(ValidationErrors.Create($"Can not override value type {t}").Nest("canOverride")); } if (t.IsAbstract) { e.Add(ValidationErrors.Create($"Can not have abstract value type {t}").Nest("isAbstract")); } } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, BreakableExpression b) { if (e.HasErrors) { return; } if (b.Expression.Type() != b.Label.Type) { e.Add(ValidationErrors.Create( $"BreakableExpression returns {b.Expression.Type()}, but must return the same type type as {b.Label}" ).Nest("expression")); // TODO: validation path for expression type } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, NewArrayExpression obj) { if (obj.Type != null && obj.Type.Dimensions != obj.Dimensions.Length) { e.Add(ValidationErrors.Create($"Expected {obj.Type.Dimensions} dimension parameters for construction of {obj.Type}, got {obj.Dimensions.Length}").Nest("dimensions")); } for (int i = 0; i < obj.Dimensions.Length; i++) { var d = obj.Dimensions[i]; if (Array.IndexOf(AllowedDimensionTypes, d.Type()) < 0) { e.Add(ValidationErrors.Create($"Array dimensions are expected to be of type int or long, not {d.Type()}").Nest(i.ToString()).Nest("dimensions")); // TODO: expression type validation } } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, ConstantExpression obj) { if (obj.Type is null) { return; } if (obj.Value is null) { if (obj.Type.IsReferenceType == false && !obj.Type.IsNullableValueType()) { e.Add(ValidationErrors.Create($"Can not have constant null for non-nullable type '{obj.Type}'. Use Expression.Default for default value.")); } return; } // TODO: somehow check primitiveness }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, MethodReference m) { if (m.Signature is null) { return; } var expectedCount = m.Signature.DeclaringType.TotalParameterCount(); if (expectedCount != m.TypeArguments.Length) { e.Add(ValidationErrors.Create($"Type {m.Signature.DeclaringType} expected {expectedCount} parameters, got [{string.Join(", ", m.TypeArguments)}]")); } if (m.Signature.TypeParameters.Length != m.MethodTypeArguments.Length) { e.Add(ValidationErrors.Create($"Method {m.Signature} expected {expectedCount} type parameters, got [{string.Join(", ", m.MethodTypeArguments)}]")); } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, ArrayIndexExpression obj) { if (obj.Array == null) { return; } var t = (obj.Array.Type() as TypeReference.ArrayTypeCase).Item; if (t is null) { e.Add(ValidationErrors.Create($"Expected expression of array type, got '{obj.Array.Type()}'").Nest("array")); } else if (t.Dimensions != obj.Indices.Length) { e.Add(ValidationErrors.Create($"Expected {t.Dimensions} index parameters for indexing {t}, got {obj.Indices.Length}").Nest("indices")); } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, NumericConversionExpression n) { if (e.HasErrors) { return; } bool isNumericSignature(TypeSignature ts) => ts == TypeSignature.Byte || ts == TypeSignature.SByte || ts == TypeSignature.Int16 || ts == TypeSignature.UInt16 || ts == TypeSignature.Int32 || ts == TypeSignature.UInt32 || ts == TypeSignature.Int64 || ts == TypeSignature.UInt64 || ts == TypeSignature.IntPtr || ts == TypeSignature.UIntPtr || ts == TypeSignature.Single || ts == TypeSignature.Double; bool isNumericType(TypeReference t) => t.Match( s => isNumericSignature(s.Type), array => false, byRef => false, ptr => true, generic => true, func => false); var from = n.Value.Type(); var to = n.Type; if (!isNumericType(from)) { e.AddErr($"Can not apply numeric conversion on expression of type {from}", "value"); // TODO: expression type validation path } if (!isNumericType(to)) { e.AddErr($"Can not use numeric conversion to convert to type {to}", "type"); } }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, ReferenceConversionExpression obj) { if (obj.Type is null || obj.Value is null) { return; } var from = obj.Value.Type().UnwrapReference(); var into = obj.Type; if (from == into) { return; // this is valid } if (from.IsSealed() && into.IsSealed()) { e.Add(ValidationErrors.Create($"Can not convert from '{from}' to '{into}' since both types are sealed.")); } // yes, there is room for other checks }
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, FunctionConversionExpression obj) { if (obj.Type is null || obj.Value is null) { return; } var from = obj.Value.Type().UnwrapReference(); var into = obj.Type; if (!IsFunctionType(from)) { e.Add(ValidationErrors.Create($"Function conversion can only convert functions and delegates, but value has type '{from}'").Nest("value")); } if (!IsFunctionType(into)) { e.Add(ValidationErrors.Create($"Function conversion can only convert functions and delegates, but target has type '{into}'").Nest("target")); } if (from is TypeReference.FunctionTypeCase { Item : var from_f } && into is TypeReference.FunctionTypeCase {
static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, FieldSignature f) { }