Repository navigation
Closed
Description
The current API for retrieving recorded method calls is convenience-oriented, providing methods like constArgumentsFor() and hasNonConstArguments(). This leads users to forget to call hasNonConstArguments.
Proposed Solution:
Refactor the API to provide a single, powerful method that returns all recorded usages for a given method. The different kinds of calls should be represented by a sealed class hierarchy.
API Signature:
Iterable<CallReference> callsFor(Identifier id);
sealed class CallReference { ... }
// A direct call with arguments.
final class CallWithArguments extends CallReference {
// ... properties for positional and named arguments
}
// A tear-off of the method.
final class CallTearOff extends CallReference { ... }
// A potential dynamic invocation.
final class DynamicInvocation extends CallReference { ... }Example Usage
This example demonstrates a stricter approach where the presence of any non-const
usages is treated as a failure. It uses a custom Either type to return
either a list of errors (Left) or a list of the successfully extracted constant
values (Right).
import 'package:record_use/record_use.dart';
// A simple Either type to represent success (Right) or failure (Left).
sealed class Either<L, R> {}
class Left<L, R> extends Either<L, R> {
final L value;
Left(this.value);
}
class Right<L, R> extends Either<L, R> {
final R value;
Right(this.value);
}
Either<List<String>, List<Constant>> processMethodUsages(
Recordings recordings, Identifier methodId) {
final calls = recordings.callsFor(methodId);
final constValues = <Constant>[];
final errors = <String>[];
for (final call in calls) {
switch (call) {
case CallWithArguments(
location: final loc,
namedArguments: {'myArg': final Constant constArg}
):
constValues.add(constArg);
break;
case CallTearOff(location: final loc):
errors.add('Error: Found a tear-off at ${loc.uri}:${loc.line}.');
break;
case DynamicInvocation(location: final loc):
errors.add('Error: Found a dynamic invocation at ${loc.uri}:${loc.line}.');
break;
case CallWithArguments(
location: final loc,
namedArguments: {'myArg': null}
):
errors.add(
'Error: Call at ${loc.uri}:${loc.line} had a non-constant \'myArg\'.',
);
break;
case CallWithArguments(location: final loc):
errors.add(
'Error: Call at ${loc.uri}:${loc.line} did not provide the \'myArg\' argument.',
);
break;
}
}
if (errors.isNotEmpty) {
return Left(errors);
}
return Right(constValues);
}Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity
sagar-h007 commentedon Jan 21, 2026
@dcharkes I’d like to work on this.
I agree with the diagnosis: the current API is convenience-oriented in a way that makes it too easy to miss non-const usages. The issue isn’t missing data, but that the API encourages partial inspection instead of forcing callers to look at everything.
Approach:
-Introduce a single primitive API: Iterable callsFor(Identifier id);
-Represent all recorded method usages using a sealed CallReference hierarchy (CallWithArguments, CallTearOff, DynamicInvocation), with non-const arguments represented explicitly (e.g. Constant?).
-Rebuild existing helpers (constArgumentsFor, hasNonConstArguments, etc.) on top of callsFor and deprecate them, preserving behavior while nudging users toward exhaustive handling.
-Update docs and examples to use callsFor with pattern matching so non-const and dynamic cases are hard to ignore by accident.
If this sounds reasonable, I can start by sketching the sealed class model and a minimal callsFor implementation, then follow up with deprecations and example updates.
dcharkes commentedon Jan 21, 2026
@sagar-h007 I'm not looking for contributions on this right now. I'm actively working on this package and any breaking changes to the API need to be rolled into the Dart SDK. I will first get the internals right and then work on the API myself. If you want to contribute, please take a look at issues that are labeled with contributions welcome or good first issue.
[record_use] Public API deal with non-const (#3147)
[deps] Roll dart-lang/native
Squashed commit of the following: