示例#1
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);
        }
示例#2
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);
        }
示例#3
0
        static SignaturePart ConvertForSubr(
            [NotNull] Type paramType,
            [NotNull] string name,
            // ReSharper disable once SuggestBaseTypeForParameter
            [NotNull][ItemNotNull] object[] attrs,
            bool isOptional,
            // ReSharper disable once UnusedParameter.Local
            object defaultValue)
        {
            // [Either], [Required], and [Decl] go on the parameter
            var isRequired = attrs.OfType <RequiredAttribute>().Any();

            if (isRequired && isOptional)
            {
                throw new InvalidOperationException("A parameter can't be both required and optional");
            }

            var eitherAttr = attrs.OfType <EitherAttribute>().SingleOrDefault();
            var declAttr   = attrs.OfType <DeclAttribute>().SingleOrDefault();

            // [ZilStructuredParam] and [ZilSequenceParam] go on the element type
            var(isArray, elementType) = CheckArray(paramType);
            var structAttr = elementType.GetCustomAttribute <ZilStructuredParamAttribute>(false);
            var seqAttr    = elementType.GetCustomAttribute <ZilSequenceParamAttribute>(false);

            int attrCount =
                (eitherAttr != null ? 1 : 0) +
                (declAttr != null ? 1 : 0) +
                (structAttr != null ? 1 : 0) +
                (seqAttr != null ? 1 : 0);

            if (attrCount > 1)
            {
                throw new InvalidOperationException(
                          nameof(EitherAttribute) + ", " +
                          nameof(DeclAttribute) + ", " +
                          nameof(ZilStructuredParamAttribute) + ", or " +
                          nameof(ZilSequenceParamAttribute) + ": pick at most one");
            }

            SignaturePart elemPart = null;

            if (eitherAttr != null)
            {
                elemPart = ConvertEither(eitherAttr.Types, eitherAttr.DefaultParamDesc ?? name);
            }
            else if (declAttr != null)
            {
                elemPart = SignatureBuilder.MaybeConvertDecl(declAttr);
            }
            else if (structAttr != null)
            {
                elemPart = ConvertStruct(elementType, structAttr, name);
            }
            else if (seqAttr != null)
            {
                elemPart = ConvertSequence(elementType, name);
            }

            if (elemPart == null)
            {
                elemPart = SignatureBuilder.Identifier(name);

                if (elementType != typeof(ZilObject))
                {
                    elemPart = ConstrainByType(elemPart, elementType);
                }
            }

            if (isArray)
            {
                elemPart = SignatureBuilder.VarArgs(elemPart, isRequired);
            }

            if (isOptional)
            {
                //XXX use defaultValue somehow?
                elemPart = SignatureBuilder.Optional(elemPart);
            }

            return(elemPart);
        }