示例#1
0
        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"));
                }
            }
        }
示例#2
0
        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"));
                }
            }
        }
示例#3
0
 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
     }
 }
示例#4
0
        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"));
                    }
                }
            }
        }
示例#5
0
        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"));
                    }
                }
            }
        }
示例#6
0
 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"));
     }
 }
示例#7
0
 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
     })
示例#8
0
        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)}]"));
            }
        }
示例#9
0
        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)}]"));
            }
        }
示例#10
0
        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"));
            }
        }
示例#11
0
        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
                });
示例#12
0
        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
            }
        }
示例#13
0
 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"));
         }
     }
 }
示例#14
0
        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
            }
        }
示例#15
0
        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
                }
            }
        }
示例#16
0
        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
        }
示例#17
0
        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)}]"));
            }
        }
示例#18
0
        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"));
            }
        }
示例#19
0
        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
        }
示例#21
0
        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 {
示例#22
0
 static partial void ValidateObjectExtension(ref CoreLib.ValidationErrorsBuilder e, FieldSignature f)
 {
 }