Пример #1
0
        public static SignaturePart MaybeConvertDecl([NotNull] string pattern)
        {
            // TODO: this should parse the <OR...> instead of doing a hacky regex match

            if (pattern.StartsWith("'", StringComparison.Ordinal))
            {
                return(LiteralPart.From(pattern.Substring(1)));
            }

            var match = orDeclRegex.Match(pattern);

            if (!match.Success)
            {
                return(null);
            }

#if NET471
            var captures = match.Groups[1].Captures.Cast <Capture>();
#else
            var captures = match.Groups[1].Captures;
#endif
            var alts = captures.Select(c => MaybeConvertDecl(c.Value)).ToArray();
            if (alts.Length > 0 && alts.All(a => a != null))
            {
                return(Alternatives(alts));
            }

            return(null);
        }
Пример #2
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");
            }
        }