in lib/src/intl_message.dart [133:230]
String checkValidity(MethodInvocation node, List arguments, String outerName,
FormalParameterList outerArgs,
{bool nameAndArgsGenerated: false, bool examplesRequired: false}) {
// If we have parameters, we must specify args and name.
NamedExpression args = arguments.firstWhere(
(each) => each is NamedExpression && each.name.label.name == 'args',
orElse: () => null);
var parameterNames =
outerArgs.parameters.map((x) => x.identifier.name).toList();
var hasArgs = args != null;
var hasParameters = !outerArgs.parameters.isEmpty;
if (!nameAndArgsGenerated && !hasArgs && hasParameters) {
return "The 'args' argument for Intl.message must be specified for "
"messages with parameters. Consider using rewrite_intl_messages.dart";
}
if (!checkArgs(args, parameterNames)) {
return "The 'args' argument must match the message arguments,"
" e.g. args: ${parameterNames}";
}
var messageNameArgument = arguments.firstWhere(
(eachArg) =>
eachArg is NamedExpression && eachArg.name.label.name == 'name',
orElse: () => null);
var nameExpression = messageNameArgument?.expression;
String messageName;
String givenName;
//TODO(alanknight): If we generalize this to messages with parameters
// this check will need to change.
if (nameExpression == null) {
if (!hasParameters) {
// No name supplied, no parameters. Use the message as the name.
messageName = _evaluateAsString(arguments[0]);
outerName = messageName;
} else {
// We have no name and parameters, but the transformer generates the
// name.
if (nameAndArgsGenerated) {
givenName = outerName;
messageName = givenName;
} else {
return "The 'name' argument for Intl.message must be supplied for "
"messages with parameters. Consider using "
"rewrite_intl_messages.dart";
}
}
} else {
// Name argument is supplied, use it.
givenName = _evaluateAsString(nameExpression);
messageName = givenName;
}
if (messageName == null) {
return "The 'name' argument for Intl.message must be a string literal";
}
var hasOuterName = outerName != null;
var simpleMatch = outerName == givenName || givenName == null;
var classPlusMethod = Message.classPlusMethodName(node, outerName);
var classMatch = classPlusMethod != null && (givenName == classPlusMethod);
if (!(hasOuterName && (simpleMatch || classMatch))) {
return "The 'name' argument for Intl.message must match either "
"the name of the containing function or <ClassName>_<methodName> ("
"was '$givenName' but must be '$outerName' or '$classPlusMethod')";
}
var simpleArguments = arguments.where((each) =>
each is NamedExpression &&
["desc", "name"].contains(each.name.label.name));
var values = simpleArguments.map((each) => each.expression).toList();
for (var arg in values) {
if (_evaluateAsString(arg) == null) {
return ("Intl.message arguments must be string literals: $arg");
}
}
if (hasParameters) {
var exampleArg = arguments.where((each) =>
each is NamedExpression && each.name.label.name == "examples");
var examples = exampleArg.map((each) => each.expression).toList();
if (examples.isEmpty && examplesRequired) {
return "Examples must be provided for messages with parameters";
}
if (examples.isNotEmpty) {
var example = examples.first;
var map = _evaluateAsMap(example);
if (map == null) {
return "Examples must be a const Map literal.";
}
if (example.constKeyword == null) {
return "Examples must be const.";
}
}
}
return null;
}