Signature.parseMethodSignature constructor
Signature.parseMethodSignature(
- String signature
Parses a Dart method signature string and returns a Signature instance.
The signature string should follow the standard Dart method signature syntax, including return type, method name, and parameter list enclosed in parentheses. This parser attempts to correctly identify positional, optional positional, required named, and optional named parameters, extracting only their names. It handles basic type annotations and default values but might not cover all edge cases of complex Dart type syntax.
Example:
final signatureString = '''String greet(String name,
[String? greeting = "Hello"])''';
final signature = Signature.parseMethodSignature(signatureString);
print(signature.positionalParameters); // Output: [name]
print(signature.positionalOptionalParameters); // Output: [greeting]
print(signature.namedParameters); // Output: []
print(signature.namedOptionalParameters); // Output: []
Throws a FormatException if the provided signature string does not
match the expected basic method signature format.
Implementation
factory Signature.parseMethodSignature(String signature) {
var firstParensIndex = signature.indexOf('(');
int? lastParensIndex = signature.lastIndexOf(')');
if (firstParensIndex == -1 || lastParensIndex == -1) {
throw const FormatException('Invalid signature format');
}
final parameterString = signature
.substring(firstParensIndex + 1, lastParensIndex)
.split('\n')
.map((line) => line.trim())
.whereNot((line) => line.startsWith('//'))
.join('\n');
final positionalParams = <String>[];
final positionalOptionalParams = <String>[];
final namedParams = <String>[];
final namedOptionalParams = <String>[];
if (parameterString.isNotEmpty) {
var inOptionalPositional = false;
var inNamed = false;
var i = 0;
while (i < parameterString.length) {
var start = i;
var bracketCounter = 0;
for (; i < parameterString.length; i++) {
if (parameterString[i] == '<') {
bracketCounter++;
} else if (parameterString[i] == '>') {
bracketCounter--;
} else if (parameterString[i] == ',' && bracketCounter == 0) {
break;
}
}
var param = parameterString.substring(start, i);
i++;
param = param.trim();
if (param.isEmpty) {
continue;
}
if (param.startsWith('[')) {
inOptionalPositional = true;
param = param.substring(1).trim();
} else if (param.startsWith('{')) {
inNamed = true;
param = param.substring(1).trim();
}
if (param.endsWith(']')) {
param = param.substring(0, param.length - 1).trim();
} else if (param.endsWith('}')) {
param = param.substring(0, param.length - 1).trim();
}
if (inOptionalPositional) {
positionalOptionalParams.add(_extractParameterName(param));
} else if (inNamed) {
var req = 'required ';
if (param.startsWith(req)) {
namedParams.add(_extractParameterName(param.substring(req.length)));
} else {
namedOptionalParams.add(_extractParameterName(param));
}
} else {
positionalParams.add(_extractParameterName(param));
}
}
}
// Extract only the name for positional parameters
final positionalNames =
positionalParams.map(_extractParameterName).toList();
final positionalOptionalNames =
positionalOptionalParams.map(_extractParameterName).toList();
return Signature(
positionalParameters: positionalNames,
positionalOptionalParameters: positionalOptionalNames,
namedParameters: namedParams,
namedOptionalParameters: namedOptionalParams,
);
}