Exemplo n.º 1
0
        public static ISignature FromBuiltinSpec([NotNull] BuiltinSpec spec)
        {
            var pis = spec.Method.GetParameters();

            var parts = pis
                        .Skip(spec.Attr.Data == null ? 1 : 2)
                        .Select(ConvertBuiltinParam)
                        .ToArray();

            var returnPart = ConvertBuiltinParam(
                spec.Method.ReturnParameter ??
                throw new InvalidOperationException($"Missing {nameof(spec.Method.ReturnParameter)}"));

            return(new ZBuiltinSignature(
                       spec.MinArgs, spec.MaxArgs,
                       spec.Attr.MinVersion, spec.Attr.MaxVersion,
                       parts,
                       returnPart));

            // helper
            SignaturePart ConvertBuiltinParam(ParameterInfo pi)
            {
                var type = pi.ParameterType;

                if (type == typeof(void))
                {
                    if (spec.CallType == typeof(VoidCall))
                    {
                        return(LiteralPart.From("T"));
                    }

                    var part = SignatureBuilder.Constrained(
                        SignatureBuilder.Identifier("$return"),
                        spec.CallType == typeof(PredCall) ? Constraint.Boolean : Constraint.AnyObject);

                    return(ApplyParamAttributes(part, pi));
                }

                if (ParameterTypeHandler.Handlers.TryGetValue(type, out var handler))
                {
                    return(ConvertWithHandler(handler, pi));
                }

                // ReSharper disable once PatternAlwaysOfType
                if (type.IsArray && type.GetElementType() is Type t &&
                    ParameterTypeHandler.Handlers.TryGetValue(t, out handler))
                {
                    var part = ConvertWithHandler(handler, pi);
                    return(SignatureBuilder.VarArgs(part, false));
                }

                throw new InvalidOperationException("Unexpected builtin param type");
            }
        }
Exemplo n.º 2
0
        static SignaturePart ConstrainByType([NotNull] SignaturePart part, [NotNull] Type elementType)
        {
            System.Diagnostics.Debug.Assert(!elementType.IsArray);

            // treat Nullable<Foo> as an optional Foo
            bool isOptional             = false;
            var  nullableUnderlyingType = Nullable.GetUnderlyingType(elementType);

            if (nullableUnderlyingType != null)
            {
                isOptional  = true;
                elementType = nullableUnderlyingType;
            }

            // treat LocalEnvironment as an optional ZilEnvironment
            if (elementType == typeof(LocalEnvironment))
            {
                isOptional  = true;
                elementType = typeof(ZilEnvironment);
            }

            // find an appropriate type or primtype constraint for the element type
            if (!StandardTypeConstraints.TryGetValue(elementType, out var constraint))
            {
                BuiltinPrimTypeAttribute primTypeAttr;
                if ((primTypeAttr = elementType.GetCustomAttribute <BuiltinPrimTypeAttribute>(false)) != null)
                {
                    constraint = Constraint.OfPrimType(primTypeAttr.PrimType);
                }
                else
                {
                    BuiltinTypeAttribute typeAttr;
                    if ((typeAttr = elementType.GetCustomAttribute <BuiltinTypeAttribute>(false)) != null)
                    {
                        constraint = Constraint.OfType(typeAttr.Name);
                    }
                    else
                    {
                        throw new UnhandledCaseException(elementType.Name);
                    }
                }
            }

            part = SignatureBuilder.Constrained(part, constraint);
            return(isOptional ? SignatureBuilder.Optional(part) : part);
        }
Exemplo n.º 3
0
        static SignaturePart ApplyParamAttributes([NotNull] SignaturePart part, [NotNull] ParameterInfo pi)
        {
            // TODO: also handle VariableAttribute?

            if (pi.IsDefined(typeof(TableAttribute), false))
            {
                part = SignatureBuilder.Constrained(part, Constraint.OfPrimType(PrimType.TABLE));
            }

            if (pi.IsDefined(typeof(ObjectAttribute), false))
            {
                part = SignatureBuilder.Constrained(part, Constraint.OfType(StdAtom.OBJECT));
            }

            if (pi.IsOptional)
            {
                part = SignatureBuilder.Optional(part);
            }

            return(part);
        }