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); }
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"); } }