First step into making both dart2js and the vm output the same for recorded uses. This CL changes the output format to be the same. It does not - change the annotations which are read, - add support for named arguments, - add support for const source locations, and - test feature parity. Bug: https://github.com/dart-lang/native/issues/2717 Internal customers are migrated in cl/830421816. TEST=pkg/dartdev/test/native_assets/compile_test.dart Change-Id: I67b5e3d4aebac6c22b185c77f5cb69025d746a32 Cq-Include-Trybots: luci.dart.try:pkg-linux-debug-try,pkg-linux-release-arm64-try,pkg-linux-release-try,pkg-mac-release-arm64-try,pkg-mac-release-try,pkg-win-release-arm64-try,pkg-win-release-try,dart2js-canary-linux-try,dart2js-hostasserts-linux-d8-try,dart2js-linux-chrome-try,dart2js-linux-firefox-try,dart2js-mac-chrome-try,dart2js-mac-safari-try,dart2js-minified-csp-linux-chrome-try,dart2js-minified-linux-d8-try,dart2js-unit-linux-x64-release-try,dart2js-win-chrome-try,dart2wasm-linux-jscm-chrome-try,dart2wasm-linux-optimized-jsc-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416000 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Mayank Patke <fishythefish@google.com> Reviewed-by: Moritz Sümmermann <mosum@google.com> Reviewed-by: Nate Bosch <nbosch@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Liam Appelbe <liama@google.com>
Caution
This is an experimental package, and it's API can break at any time. Use at your own discretion.
This package provides the data classes for the usage recording feature in the Dart SDK.
Dart objects with the @RecordUse annotation are being recorded at compile
time, providing the user with information. The information depends on the object
being recorded.
- If placed on a static method, the annotation means that arguments passed to the method will be recorded, as far as they can be inferred at compile time.
- If placed on a class with a constant constructor, the annotation means that any constant instance of the class will be recorded. This is particularly useful when using the class as an annotation.
Example
import 'package:meta/meta.dart' show RecordUse;
void main() {
print(SomeClass.stringMetadata(42));
print(SomeClass.doubleMetadata(42));
print(SomeClass.intMetadata(42));
print(SomeClass.boolMetadata(42));
}
class SomeClass {
@RecordMetadata('leroyjenkins')
@RecordUse()
static stringMetadata(int i) {
return i + 1;
}
@RecordMetadata(3.14)
@RecordUse()
static doubleMetadata(int i) {
return i + 1;
}
@RecordMetadata(42)
@RecordUse()
static intMetadata(int i) {
return i + 1;
}
@RecordMetadata(true)
@RecordUse()
static boolMetadata(int i) {
return i + 1;
}
}
@RecordUse()
class RecordMetadata {
final Object metadata;
const RecordMetadata(this.metadata);
}
This code will generate a data file that contains both the metadata values of
the RecordMetadata instances, as well as the arguments for the different
methods annotated with @RecordUse().
This information can then be accessed in a link hook as follows:
import 'dart:convert';
import 'package:hooks/hooks.dart';
import 'package:record_use/record_use_internal.dart';
final methodId = Identifier(
uri: 'myfile.dart',
name: 'myMethod',
);
final classId = Identifier(
uri: 'myfile.dart',
name: 'myClass',
);
void main(List<String> arguments){
link(arguments, (config, output) async {
final usesUri = config.recordedUses;
final usesJson = await File,fromUri(usesUri).readAsString();
final uses = UsageRecord.fromJson(jsonDecode(usesJson));
final args = uses.argumentsTo(methodId));
//[args] is an iterable of arguments, in this case containing "42"
final fields = uses.instancesOf(classId);
//[fields] is an iterable of the fields of the class, in this case
//containing
// {"arguments": "leroyjenkins"}
// {"arguments": 3.14}
// {"arguments": 42}
// {"arguments": true}
... // Do something with the information, such as tree-shaking native assets
});
}
Limitations
As this is designed to work on both web and native platforms, we have to adapt to the platform pecularities. One of them is that javascript does not support named arguments, so the dart2js compiler rewrites functions to only accept named parameters. While you can use named parameters to record functions, we advise caution as the retrieval behavior might change once we work around this dart2js limitation and implement separate positional and named parameters.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.