In examples,
// Valid:
throw new Error( format( '%s %s', 'foo', 'bar' ) );
// Invalid:
throw new Error( format( '%s %s', 'foo' ) );
throw new Error( format( '%s %s', 'foo', 'bar', 'beep' ) );
In short, for all instances where string/format is invoked, we want the number of trailing arguments to match the number of placeholders in the input string.
When too few or too many arguments are provided, that is likely a user error.
We should skip the scenario where format is invoked via #.call or #.apply, which is very rare in the codebase.
Notes
- We should be able to use the
format-tokenize package to tokenize the first argument, resolve the number of placeholders, and then compare against the number of provided arguments.
- We should not blanket check against any usage of any
format symbol. While that is the common alias for string/format in code, we use format elsewhere; nor should format be considered a reserved word for this purpose.
- Instead, if a source file (source, test, benchmark, example, etc) contains a
string/format import statement, we should (a) resolve the assigned alias, (b) resolve all usages of that variable, taking note that we should guard against shadowing (meaning, it is not enough to simply grep for the assigned alias; you need to find all instances where that particular symbol, not any shadowed symbol, is used), and (c) compare the number of provided args to the number of placeholders. For (b), there have been a few instances where we've needed to resolve symbols in parent scopes which are relevant to a scoped content; we may be able to reuse them, or, better, create a common utility.
In examples,
In short, for all instances where
string/formatis invoked, we want the number of trailing arguments to match the number of placeholders in the input string.When too few or too many arguments are provided, that is likely a user error.
We should skip the scenario where
formatis invoked via#.callor#.apply, which is very rare in the codebase.Notes
format-tokenizepackage to tokenize the first argument, resolve the number of placeholders, and then compare against the number of provided arguments.formatsymbol. While that is the common alias forstring/formatin code, we useformatelsewhere; nor shouldformatbe considered a reserved word for this purpose.string/formatimport statement, we should (a) resolve the assigned alias, (b) resolve all usages of that variable, taking note that we should guard against shadowing (meaning, it is not enough to simplygrepfor the assigned alias; you need to find all instances where that particular symbol, not any shadowed symbol, is used), and (c) compare the number of provided args to the number of placeholders. For (b), there have been a few instances where we've needed to resolve symbols in parent scopes which are relevant to a scoped content; we may be able to reuse them, or, better, create a common utility.