Skip to content

Commit

Permalink
Use package:record_use
Browse files Browse the repository at this point in the history
- Rename resource identifiers in the VM to usage recordings.
- Use package:record_use for serialization.
- Rename and use the experimental flag for this feature.
- Recognize tear-offs and top-level methods as well.

Next steps:

- Add constant instance recording.
- Expose API in package:native_assets_cli's link callback.

TEST=pkg/vm/test/transformations/record_use_test.dart

Change-Id: I8af3625165f78925ae943711245af93a239d1012
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/383040
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Moritz Sümmermann <mosum@google.com>
  • Loading branch information
mosuem authored and Commit Queue committed Sep 12, 2024
1 parent 120dac3 commit 81daf8e
Show file tree
Hide file tree
Showing 104 changed files with 1,902 additions and 1,202 deletions.
14 changes: 7 additions & 7 deletions pkg/_fe_analyzer_shared/lib/src/experiments/flags.dart
Original file line number Diff line number Diff line change
Expand Up @@ -164,20 +164,20 @@ enum ExperimentalFlag {
experimentEnabledVersion: const Version(3, 0),
experimentReleasedVersion: const Version(3, 0)),

recordUse(
name: 'record-use',
isEnabledByDefault: false,
isExpired: false,
experimentEnabledVersion: defaultLanguageVersion,
experimentReleasedVersion: defaultLanguageVersion),

records(
name: 'records',
isEnabledByDefault: true,
isExpired: true,
experimentEnabledVersion: const Version(3, 0),
experimentReleasedVersion: const Version(3, 0)),

resourceIdentifiers(
name: 'resource-identifiers',
isEnabledByDefault: false,
isExpired: false,
experimentEnabledVersion: defaultLanguageVersion,
experimentReleasedVersion: defaultLanguageVersion),

sealedClass(
name: 'sealed-class',
isEnabledByDefault: true,
Expand Down
33 changes: 11 additions & 22 deletions pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15039,6 +15039,17 @@ const MessageCode messageRecordTypeZeroFieldsButTrailingComma =
correctionMessage: r"""Try removing the trailing comma.""",
);

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeRecordUseCannotBePlacedHere =
messageRecordUseCannotBePlacedHere;

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageRecordUseCannotBePlacedHere = const MessageCode(
"RecordUseCannotBePlacedHere",
problemMessage:
r"""`RecordUse` annotation cannot be placed on this element.""",
);

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeRecordUsedAsCallable = messageRecordUsedAsCallable;

Expand Down Expand Up @@ -15225,28 +15236,6 @@ const MessageCode messageRequiredParameterWithDefault = const MessageCode(
r"""Try removing the default value or making the parameter optional.""",
);

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeResourceIdentifiersMultiple =
messageResourceIdentifiersMultiple;

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageResourceIdentifiersMultiple = const MessageCode(
"ResourceIdentifiersMultiple",
problemMessage:
r"""Only one resource identifier pragma can be used at a time.""",
);

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeResourceIdentifiersNotStatic =
messageResourceIdentifiersNotStatic;

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode messageResourceIdentifiersNotStatic = const MessageCode(
"ResourceIdentifiersNotStatic",
problemMessage:
r"""Resource identifier pragma can be used on a static method only.""",
);

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeRestPatternInMapPattern = messageRestPatternInMapPattern;

Expand Down
49 changes: 24 additions & 25 deletions pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ final _knownFeatures = <String, ExperimentalFeature>{
ExperimentalFeatures.nonfunction_type_aliases,
EnableString.null_aware_elements: ExperimentalFeatures.null_aware_elements,
EnableString.patterns: ExperimentalFeatures.patterns,
EnableString.record_use: ExperimentalFeatures.record_use,
EnableString.records: ExperimentalFeatures.records,
EnableString.resource_identifiers: ExperimentalFeatures.resource_identifiers,
EnableString.sealed_class: ExperimentalFeatures.sealed_class,
EnableString.set_literals: ExperimentalFeatures.set_literals,
EnableString.spread_collections: ExperimentalFeatures.spread_collections,
Expand Down Expand Up @@ -123,12 +123,12 @@ class EnableString {
/// String to enable the experiment "patterns"
static const String patterns = 'patterns';

/// String to enable the experiment "record-use"
static const String record_use = 'record-use';

/// String to enable the experiment "records"
static const String records = 'records';

/// String to enable the experiment "resource-identifiers"
static const String resource_identifiers = 'resource-identifiers';

/// String to enable the experiment "sealed-class"
static const String sealed_class = 'sealed-class';

Expand Down Expand Up @@ -383,8 +383,18 @@ class ExperimentalFeatures {
releaseVersion: Version.parse('3.0.0'),
);

static final records = ExperimentalFeature(
static final record_use = ExperimentalFeature(
index: 22,
enableString: EnableString.record_use,
isEnabledByDefault: IsEnabledByDefault.record_use,
isExpired: IsExpired.record_use,
documentation: 'Output arguments used by static functions.',
experimentalReleaseVersion: null,
releaseVersion: null,
);

static final records = ExperimentalFeature(
index: 23,
enableString: EnableString.records,
isEnabledByDefault: IsEnabledByDefault.records,
isExpired: IsExpired.records,
Expand All @@ -393,16 +403,6 @@ class ExperimentalFeatures {
releaseVersion: Version.parse('3.0.0'),
);

static final resource_identifiers = ExperimentalFeature(
index: 23,
enableString: EnableString.resource_identifiers,
isEnabledByDefault: IsEnabledByDefault.resource_identifiers,
isExpired: IsExpired.resource_identifiers,
documentation: 'Output arguments used by static functions.',
experimentalReleaseVersion: null,
releaseVersion: null,
);

static final sealed_class = ExperimentalFeature(
index: 24,
enableString: EnableString.sealed_class,
Expand Down Expand Up @@ -565,12 +565,12 @@ class IsEnabledByDefault {
/// Default state of the experiment "patterns"
static const bool patterns = true;

/// Default state of the experiment "record-use"
static const bool record_use = false;

/// Default state of the experiment "records"
static const bool records = true;

/// Default state of the experiment "resource-identifiers"
static const bool resource_identifiers = false;

/// Default state of the experiment "sealed-class"
static const bool sealed_class = true;

Expand Down Expand Up @@ -669,12 +669,12 @@ class IsExpired {
/// Expiration status of the experiment "patterns"
static const bool patterns = true;

/// Expiration status of the experiment "record-use"
static const bool record_use = false;

/// Expiration status of the experiment "records"
static const bool records = true;

/// Expiration status of the experiment "resource-identifiers"
static const bool resource_identifiers = false;

/// Expiration status of the experiment "sealed-class"
static const bool sealed_class = true;

Expand Down Expand Up @@ -780,13 +780,12 @@ mixin _CurrentState {
/// Current state for the flag "patterns"
bool get patterns => isEnabled(ExperimentalFeatures.patterns);

/// Current state for the flag "record-use"
bool get record_use => isEnabled(ExperimentalFeatures.record_use);

/// Current state for the flag "records"
bool get records => isEnabled(ExperimentalFeatures.records);

/// Current state for the flag "resource-identifiers"
bool get resource_identifiers =>
isEnabled(ExperimentalFeatures.resource_identifiers);

/// Current state for the flag "sealed-class"
bool get sealed_class => isEnabled(ExperimentalFeatures.sealed_class);

Expand Down
19 changes: 5 additions & 14 deletions pkg/analyzer/lib/src/test_utilities/mock_packages.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,26 +154,17 @@ class Immutable {
const Immutable([this.reason = '']);
}
@experimental
class RecordUse {
const RecordUse();
}
class Required {
final String reason;
const Required([this.reason = '']);
}
@experimental
class ResourceIdentifier {
final Object? metadata;
const ResourceIdentifier([this.metadata])
: assert(
metadata == null ||
metadata is bool ||
metadata is num ||
metadata is String,
'Valid metadata types are bool, int, double, and String.',
);
}
@Target({
TargetKind.constructor,
TargetKind.field,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ const _Literal literal = _Literal();
/// any warnings.
///
/// An example use could be the arguments to functions annotated with
/// [ResourceIdentifier], as only constant arguments can be made available
/// [RecordUse], as only constant arguments can be made available
/// to the post-compile steps.
///
/// ```dart
Expand Down Expand Up @@ -539,6 +539,24 @@ class Immutable {
const Immutable([this.reason = '']);
}

/// Annotates a static method to be recorded.
///
/// Applies to static functions, top-level functions, or extension methods.
///
/// During compilation, all statically resolved calls to an annotated function
/// are registered, and information about the annotated functions, the calls,
/// and their arguments, is then made available to post-compile steps.
// TODO(srawlins): Enforce with `TargetKind.method`.
@experimental
class RecordUse {
/// Creates a [RecordUse] instance.
///
/// This annotation can be placed as an annotation on functions whose
/// statically resolved calls should be registered together with the optional
/// [metadata] information.
const RecordUse();
}

/// Used to annotate a named parameter `p` in a method or function `f`.
///
/// See [required] for more details.
Expand Down Expand Up @@ -567,38 +585,6 @@ class Required {
const Required([this.reason = '']);
}

/// Annotates a static method as referencing a native resource.
///
/// Applies to static functions, top-level functions, or extension methods.
///
/// During compilation, all statically resolved calls to an annotated function
/// are registered, and information about the annotated functions, the calls,
/// and their arguments, is then made available to post-compile steps.
// TODO(srawlins): Enforce with `TargetKind.method`.
@experimental
class ResourceIdentifier {
/// Information which is stored together with the function call.
///
/// This could, for example, be the name of the package containing the
/// function annotated with this annotation. Allowed types are [bool], [int],
/// [double], and [String].
final Object? metadata;

/// Creates a [ResourceIdentifier] instance.
///
/// This annotation can be placed as an annotation on functions whose
/// statically resolved calls should be registered together with the optional
/// [metadata] information.
const ResourceIdentifier([this.metadata])
: assert(
metadata == null ||
metadata is bool ||
metadata is num ||
metadata is String,
'Valid metadata types are bool, int, double, and String.',
);
}

/// See [useResult] for more details.
@Target({
TargetKind.constructor,
Expand Down
9 changes: 5 additions & 4 deletions pkg/dart2native/lib/dart2native.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ Future<ProcessResult> markExecutable(String outputFile) {

/// Generates kernel by running the provided [genKernel] path.
///
/// Also takes a path to the [resourcesFile] JSON file, where the method calls
/// to static functions annotated with `@ResourceIdentifier` will be collected.
/// Also takes a path to the [recordedUsagesFile] JSON file, where the method
/// calls to static functions annotated with `@RecordUse` will be collected.
Future<ProcessResult> generateKernelHelper({
required String dartaotruntime,
String? sourceFile,
Expand All @@ -115,7 +115,7 @@ Future<ProcessResult> generateKernelHelper({
String? targetOS,
List<String> extraGenKernelOptions = const [],
String? nativeAssets,
String? resourcesFile,
String? recordedUsagesFile,
String? depFile,
bool enableAsserts = false,
bool fromDill = false,
Expand All @@ -138,7 +138,8 @@ Future<ProcessResult> generateKernelHelper({
...defines.map((d) => '-D$d'),
if (packages != null) '--packages=$packages',
if (nativeAssets != null) '--native-assets=$nativeAssets',
if (resourcesFile != null) '--resources-file=$resourcesFile',
if (recordedUsagesFile != null)
'--recorded-usages-file=$recordedUsagesFile',
if (depFile != null) '--depfile=$depFile',
'--output=$kernelFile',
...extraGenKernelOptions,
Expand Down
18 changes: 9 additions & 9 deletions pkg/dart2native/lib/generate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ extension type KernelGenerator._(_Generator _generator) {

/// Generate a kernel file,
///
/// [resourcesFile] is the path to `resources.json`, where the tree-shaking
/// information collected during kernel compilation is stored.
/// [recordedUsagesFile] is the path to `recorded_usages.json`, where the
/// tree-shaking information collected during kernel compilation is stored.
Future<SnapshotGenerator> generate({
String? resourcesFile,
String? recordedUsagesFile,
List<String>? extraOptions,
}) =>
_generator.generateKernel(
resourcesFile: resourcesFile,
recordedUsagesFile: recordedUsagesFile,
extraOptions: extraOptions,
);
}
Expand Down Expand Up @@ -192,7 +192,7 @@ class _Generator {
}

Future<SnapshotGenerator> generateKernel({
String? resourcesFile,
String? recordedUsagesFile,
List<String>? extraOptions,
}) async {
if (_verbose) {
Expand All @@ -219,7 +219,7 @@ class _Generator {
if (_depFile != null) '--depfile-target=$_outputPath',
...?extraOptions,
],
resourcesFile: resourcesFile,
recordedUsagesFile: recordedUsagesFile,
aot: true,
);
await _forwardOutput(kernelResult);
Expand Down Expand Up @@ -366,7 +366,7 @@ class _Generator {
///
/// [nativeAssets] is the path to `native_assets.yaml`.
///
/// [resourcesFile] is the path to `resources.json`.
/// [recordedUsagesFile] is the path to `recorded_usages.json`.
Future<void> generateKernel({
required String sourceFile,
required String outputFile,
Expand All @@ -382,7 +382,7 @@ Future<void> generateKernel({
bool product = true,
bool verbose = false,
String? nativeAssets,
String? resourcesFile,
String? recordedUsagesFile,
String? depFile,
List<String>? extraOptions,
}) async {
Expand All @@ -407,7 +407,7 @@ Future<void> generateKernel({
...?extraOptions,
],
nativeAssets: nativeAssets,
resourcesFile: resourcesFile,
recordedUsagesFile: recordedUsagesFile,
product: product,
);
await _forwardOutput(kernelResult);
Expand Down
6 changes: 5 additions & 1 deletion pkg/dartdev/lib/dartdev.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ class DartdevRunner extends CommandRunner<int> {
final nativeAssetsExperimentEnabled =
nativeAssetsEnabled(vmEnabledExperiments);
if (nativeAssetsExperimentEnabled) {
addCommand(BuildCommand(verbose: verbose));
final recordUseExperimentEnabled = recordUseEnabled(vmEnabledExperiments);
addCommand(BuildCommand(
verbose: verbose,
recordUseEnabled: recordUseExperimentEnabled,
));
}
addCommand(CompileCommand(
verbose: verbose,
Expand Down
Loading

0 comments on commit 81daf8e

Please sign in to comment.