Does anybody have a good way to automate the setting of SyntaxInformation for any custom function? I have a ton of functions for which I want to set SyntaxInformation, and doing it by hand seems a little pointless. Here's what I've come up with so far:
SetSyntaxInformation[symbol_Symbol] :=
Module[{argcounts, transposecounts, argpatt},
argcounts = With[{sym = symbol},
Cases[
DownValues[sym],
HoldPattern[Verbatim[HoldPattern][sym[args___]] :> _] :> CountArguments[args]
]
];
transposecounts = Transpose@PadRight[argcounts];
argpatt = ArgumentCountToPattern@Union[#] & /@ transposecounts;
SyntaxInformation[symbol] = {"ArgumentsPattern" -> argpatt}
];
ArgumentCountToPattern[{1}]=_;
ArgumentCountToPattern[{0,1}]=_.;
ArgumentCountToPattern[{0,Infinity}]=___;
CountArguments[args___] := CountArgument /@ {args};
CountArgument[Verbatim[PatternTest][pat_, _]] := CountArgument[pat];
CountArgument[Verbatim[Pattern][_,(Verbatim[Blank] | _)[___]]] = 1;
CountArgument[Verbatim[Pattern][_,Verbatim[BlankSequence][___]]] = Sequence[1,Infinity];
CountArgument[Verbatim[Pattern][_,Verbatim[BlankNullSequence][___]]]=Sequence[Infinity];
This attempts to count the number of arguments for each downvalue of a given symbol, and turns this into a "ArgumentsPattern"
type list which is subsequently set. Here's an example:
F[x_] := x^2
F[x_, y_] := x^2 + y^2
SetSyntaxInformation[F]
(* {"ArgumentsPattern" -> {_, _.}} *)
Although this seems to get the job done, the code seems a little bit unwieldy and might not be that robust, as it's certainly missing a few cases (like e.g. options).
So my question is: is there any better way to tackle this problem? (And does anybody have something similar for setting argx messages?)