Version 2.13.0-151.0.dev
Merge commit 'c665bac02dc33807e8d048244657b92811254723' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 827df09..3c23620 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,8 +12,12 @@
#### Linter
-Updated the Linter to `1.0.0`, which includes:
+Updated the Linter to `1.1.0`, which includes:
+- fixed `prefer_mixin` to properly make exceptions for `dart.collection`
+ legacy mixins.
+- new lint: `use_build_context_synchronously` (experimental).
+- new lint: `avoid_multiple_declarations_per_line`.
- full library migration to null-safety.
- new lint: `use_if_null_to_convert_nulls_to_bools`.
- new lint: `deprecated_consistency`.
diff --git a/DEPS b/DEPS
index ffe4f75..f148696 100644
--- a/DEPS
+++ b/DEPS
@@ -119,7 +119,7 @@
"intl_tag": "0.17.0-nullsafety",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_rev": "b8dfe403fd8528fd14399dee3a6527b55802dd4d",
- "linter_tag": "1.0.0",
+ "linter_tag": "1.1.0",
"logging_rev": "e2f633b543ef89c54688554b15ca3d7e425b86a2",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
"markdown_rev": "9c4beaac96d8f008078e00b027915f81b665d2de",
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
index 6c06628..633c72f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -925,29 +925,54 @@
/// promotion, to retrieve information about why [target] was not promoted.
/// This call must be made right after visiting [target].
///
- /// The returned value is a map whose keys are types that the user might have
- /// been expecting the target to be promoted to, and whose values are reasons
- /// why the corresponding promotion did not occur. The caller is expected to
- /// select which non-promotion reason to report to the user by seeing which
- /// promotion would have prevented the error. (For example, if an error
- /// occurs due to the target having a nullable type, the caller should report
- /// a non-promotion reason associated with non-promotion to a non-nullable
- /// type).
- Map<Type, NonPromotionReason> whyNotPromoted(Expression target);
+ /// The returned value is a function yielding a map whose keys are types that
+ /// the user might have been expecting the target to be promoted to, and whose
+ /// values are reasons why the corresponding promotion did not occur. The
+ /// caller is expected to select which non-promotion reason to report to the
+ /// user by seeing which promotion would have prevented the error. (For
+ /// example, if an error occurs due to the target having a nullable type, the
+ /// caller should report a non-promotion reason associated with non-promotion
+ /// to a non-nullable type).
+ ///
+ /// This method is expected to execute fairly efficiently; the bulk of the
+ /// expensive computation is deferred to the function it returns. The reason
+ /// for this is that in certain cases, it's not possible to know whether "why
+ /// not promoted" information will be needed until long after visiting a node.
+ /// (For example, in resolving a call like
+ /// `(x as Future<T>).then(y, onError: z)`, we don't know whether an error
+ /// should be reported at `y` until we've inferred the type argument to
+ /// `then`, which doesn't occur until after visiting `z`). So the caller may
+ /// freely call this method after any expression for which an error *might*
+ /// need to be generated, and then defer invoking the returned function until
+ /// it is determined that an error actually occurred.
+ Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target);
/// Call this method when an error occurs that may be due to a lack of type
/// promotion, to retrieve information about why an implicit reference to
/// `this` was not promoted. [staticType] is the (unpromoted) type of `this`.
///
- /// The returned value is a map whose keys are types that the user might have
- /// been expecting the target to be promoted to, and whose values are reasons
- /// why the corresponding promotion did not occur. The caller is expected to
- /// select which non-promotion reason to report to the user by seeing which
- /// promotion would have prevented the error. (For example, if an error
- /// occurs due to the target having a nullable type, the caller should report
- /// a non-promotion reason associated with non-promotion to a non-nullable
- /// type).
- Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType);
+ /// The returned value is a function yielding a map whose keys are types that
+ /// the user might have been expecting `this` to be promoted to, and whose
+ /// values are reasons why the corresponding promotion did not occur. The
+ /// caller is expected to select which non-promotion reason to report to the
+ /// user by seeing which promotion would have prevented the error. (For
+ /// example, if an error occurs due to the target having a nullable type, the
+ /// caller should report a non-promotion reason associated with non-promotion
+ /// to a non-nullable type).
+ ///
+ /// This method is expected to execute fairly efficiently; the bulk of the
+ /// expensive computation is deferred to the function it returns. The reason
+ /// for this is that in certain cases, it's not possible to know whether "why
+ /// not promoted" information will be needed until long after visiting a node.
+ /// (For example, in resolving a call like
+ /// `(x as Future<T>).then(y, onError: z)`, we don't know whether an error
+ /// should be reported at `y` until we've inferred the type argument to
+ /// `then`, which doesn't occur until after visiting `z`). So the caller may
+ /// freely call this method after any expression for which an error *might*
+ /// need to be generated, and then defer invoking the returned function until
+ /// it is determined that an error actually occurred.
+ Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+ Type staticType);
/// Register write of the given [variable] in the current state.
/// [writtenType] should be the type of the value that was written.
@@ -1467,14 +1492,15 @@
}
@override
- Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
+ Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target) {
return _wrap(
'whyNotPromoted($target)', () => _wrapped.whyNotPromoted(target),
isQuery: true);
}
@override
- Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType) {
+ Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+ Type staticType) {
return _wrap('whyNotPromotedImplicitThis($staticType)',
() => _wrapped.whyNotPromotedImplicitThis(staticType),
isQuery: true);
@@ -2512,7 +2538,7 @@
/// Gets a map of non-promotion reasons associated with this reference. This
/// is the map that will be returned from [FlowAnalysis.whyNotPromoted].
- Map<Type, NonPromotionReason> getNonPromotionReasons(
+ Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
Map<Variable?, VariableModel<Variable, Type>> variableInfo,
Type staticType,
TypeOperations<Variable, Type> typeOperations);
@@ -3245,13 +3271,16 @@
VariableReference(this.variable);
@override
- Map<Type, NonPromotionReason> getNonPromotionReasons(
+ Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
Map<Variable?, VariableModel<Variable, Type>> variableInfo,
Type staticType,
TypeOperations<Variable, Type> typeOperations) {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
VariableModel<Variable, Type>? currentVariableInfo = variableInfo[variable];
- if (currentVariableInfo != null) {
+ if (currentVariableInfo == null) {
+ return () => {};
+ }
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
Type currentType = currentVariableInfo.promotedTypes?.last ??
typeOperations.variableType(variable);
NonPromotionHistory? nonPromotionHistory =
@@ -3263,8 +3292,8 @@
}
nonPromotionHistory = nonPromotionHistory.previous;
}
- }
- return result;
+ return result;
+ };
}
@override
@@ -3279,6 +3308,8 @@
variableInfo[variable];
}
+class WhyNotPromotedInfo {}
+
/// [_FlowContext] representing an assert statement or assert initializer.
class _AssertContext<Variable extends Object, Type extends Object>
extends _SimpleContext<Variable, Type> {
@@ -4152,17 +4183,18 @@
}
@override
- Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
+ Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target) {
ReferenceWithType<Variable, Type>? referenceWithType = _expressionReference;
if (referenceWithType != null) {
return referenceWithType.reference.getNonPromotionReasons(
_current.variableInfo, referenceWithType.type, typeOperations);
}
- return {};
+ return () => {};
}
@override
- Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType) {
+ Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+ Type staticType) {
return new _ThisReference<Variable, Type>().getNonPromotionReasons(
_current.variableInfo, staticType, typeOperations);
}
@@ -4752,13 +4784,14 @@
void whileStatement_end() {}
@override
- Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
- return {};
+ Map<Type, NonPromotionReason> Function() whyNotPromoted(Expression target) {
+ return () => {};
}
@override
- Map<Type, NonPromotionReason> whyNotPromotedImplicitThis(Type staticType) {
- return {};
+ Map<Type, NonPromotionReason> Function() whyNotPromotedImplicitThis(
+ Type staticType) {
+ return () => {};
}
@override
@@ -4910,18 +4943,21 @@
_PropertyGetReference(this.target, this.propertyName);
@override
- Map<Type, NonPromotionReason> getNonPromotionReasons(
+ Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
Map<Variable?, VariableModel<Variable, Type>> variableInfo,
Type staticType,
TypeOperations<Variable, Type> typeOperations) {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
if (promotedTypes != null) {
- for (Type type in promotedTypes) {
- result[type] = new PropertyNotPromoted(propertyName, staticType);
- }
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ for (Type type in promotedTypes) {
+ result[type] = new PropertyNotPromoted(propertyName, staticType);
+ }
+ return result;
+ };
}
- return result;
+ return () => {};
}
@override
@@ -4982,18 +5018,21 @@
class _ThisReference<Variable extends Object, Type extends Object>
extends Reference<Variable, Type> {
@override
- Map<Type, NonPromotionReason> getNonPromotionReasons(
+ Map<Type, NonPromotionReason> Function() getNonPromotionReasons(
Map<Variable?, VariableModel<Variable, Type>> variableInfo,
Type staticType,
TypeOperations<Variable, Type> typeOperations) {
- Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
List<Type>? promotedTypes = _getInfo(variableInfo)?.promotedTypes;
if (promotedTypes != null) {
- for (Type type in promotedTypes) {
- result[type] = new ThisNotPromoted();
- }
+ return () {
+ Map<Type, NonPromotionReason> result = <Type, NonPromotionReason>{};
+ for (Type type in promotedTypes) {
+ result[type] = new ThisNotPromoted();
+ }
+ return result;
+ };
}
- return result;
+ return () => {};
}
@override
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
index 6edf9f6..cae9a5f 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_mini_ast.dart
@@ -1713,7 +1713,7 @@
var type = target._visit(h, flow);
flow.forwardExpression(this, target);
Type.withComparisonsAllowed(() {
- callback(flow.whyNotPromoted(this));
+ callback(flow.whyNotPromoted(this)());
});
return type;
}
@@ -1736,7 +1736,7 @@
void _visit(
Harness h, FlowAnalysis<Node, Statement, Expression, Var, Type> flow) {
Type.withComparisonsAllowed(() {
- callback(flow.whyNotPromotedImplicitThis(staticType));
+ callback(flow.whyNotPromotedImplicitThis(staticType)());
});
}
}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 8c5161c..9fcb9a9 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -4762,6 +4762,18 @@
The one-based index of the column containing the first character of
the range.
</p>
+ </dd><dt class="field"><b>endLine: int</b></dt><dd>
+
+ <p>
+ The one-based index of the line containing the character immediately
+ following the range.
+ </p>
+ </dd><dt class="field"><b>endColumn: int</b></dt><dd>
+
+ <p>
+ The one-based index of the column containing the character immediately
+ following the range.
+ </p>
</dd></dl></dd><dt class="typeDefinition"><a name="type_NavigationRegion">NavigationRegion: object</a></dt><dd>
<p>
A description of a region from which the user can navigate to the
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index d32f2dd..3ac7ec6 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -132,6 +132,8 @@
RequestStatisticsHelper requestStatistics,
DiagnosticServer diagnosticServer,
this.detachableFileSystemManager,
+ // Disable to avoid using this in unit tests.
+ bool enableBazelWatcher = false,
}) : super(
options,
sdkManager,
@@ -142,6 +144,7 @@
httpClient,
NotificationManager(channel, baseResourceProvider.pathContext),
requestStatistics: requestStatistics,
+ enableBazelWatcher: enableBazelWatcher,
) {
var contextManagerCallbacks =
ServerContextManagerCallbacks(this, resourceProvider);
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 22595fe..2d17fe4 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -140,6 +140,7 @@
http.Client httpClient,
this.notificationManager, {
this.requestStatistics,
+ bool enableBazelWatcher,
}) : resourceProvider = OverlayResourceProvider(baseResourceProvider),
pubApi = PubApi(instrumentationService, httpClient,
Platform.environment['PUB_HOSTED_URL']) {
@@ -192,6 +193,7 @@
analysisPerformanceLogger,
analysisDriverScheduler,
instrumentationService,
+ enableBazelWatcher: enableBazelWatcher,
);
searchEngine = SearchEngineImpl(driverMap.values);
}
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 01a7d23..c3fb5d8 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -8,7 +8,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart' as engine;
-import 'package:analyzer/source/line_info.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
/// A computer for [CompilationUnit] outline.
@@ -80,10 +79,14 @@
}
Location _getLocationOffsetLength(int offset, int length) {
- CharacterLocation lineLocation = resolvedUnit.lineInfo.getLocation(offset);
- var startLine = lineLocation.lineNumber;
- var startColumn = lineLocation.columnNumber;
- return Location(resolvedUnit.path, offset, length, startLine, startColumn);
+ var startLocation = resolvedUnit.lineInfo.getLocation(offset);
+ var startLine = startLocation.lineNumber;
+ var startColumn = startLocation.columnNumber;
+ var endLocation = resolvedUnit.lineInfo.getLocation(offset + length);
+ var endLine = endLocation.lineNumber;
+ var endColumn = endLocation.columnNumber;
+ return Location(resolvedUnit.path, offset, length, startLine, startColumn,
+ endLine, endColumn);
}
Outline _newClassOutline(ClassDeclaration node, List<Outline> classContents) {
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index ec9494ef..b0164f2 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -27,8 +27,10 @@
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/bazel_watcher.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as pathos;
import 'package:watcher/watcher.dart';
import 'package:yaml/yaml.dart';
@@ -39,7 +41,9 @@
/// functionality due its performance issues. We plan to benchmark and optimize
/// it and re-enable it everywhere.
/// Not private to enable testing.
-var experimentalEnableBazelWatching = false;
+/// NB: If you set this to `false` remember to disable the
+/// `test/integration/serve/bazel_changes_test.dart`.
+var experimentalEnableBazelWatching = true;
/// Class that maintains a mapping from included/excluded paths to a set of
/// folders that should correspond to analysis contexts.
@@ -185,20 +189,35 @@
final Map<Folder, StreamSubscription<WatchEvent>> changeSubscriptions =
<Folder, StreamSubscription<WatchEvent>>{};
- /// For each root directory stores subscriptions and watchers that we
- /// established to detect changes to Bazel generated files.
- final Map<Folder, _BazelWorkspaceSubscription> bazelSubscriptions =
- <Folder, _BazelWorkspaceSubscription>{};
+ /// For each folder, stores the subscription to the Bazel workspace so that we
+ /// can establish watches for the generated files.
+ final bazelSearchSubscriptions =
+ <Folder, StreamSubscription<BazelSearchInfo>>{};
- ContextManagerImpl(
- this.resourceProvider,
- this.sdkManager,
- this._byteStore,
- this._performanceLog,
- this._scheduler,
- this._instrumentationService,
- ) {
+ /// The watcher service running in a separate isolate to watch for changes
+ /// to files generated by Bazel.
+ ///
+ /// Might be `null` if watching Bazel files is not enabled.
+ BazelFileWatcherService bazelWatcherService;
+
+ /// The subscription to changes in the files watched by [bazelWatcherService].
+ ///
+ /// Might be `null` if watching Bazel files is not enabled.
+ StreamSubscription<List<WatchEvent>> bazelWatcherSubscription;
+
+ /// For each [Folder] store which files are being watched. This allows us to
+ /// clean up when we destroy a context.
+ final bazelWatchedPathsPerFolder = <Folder, _BazelWatchedFiles>{};
+
+ ContextManagerImpl(this.resourceProvider, this.sdkManager, this._byteStore,
+ this._performanceLog, this._scheduler, this._instrumentationService,
+ {@required enableBazelWatcher}) {
pathContext = resourceProvider.pathContext;
+ if (enableBazelWatcher) {
+ bazelWatcherService = BazelFileWatcherService(_instrumentationService);
+ bazelWatcherSubscription = bazelWatcherService.events
+ .listen((events) => _handleBazelWatchEvents(events));
+ }
}
@override
@@ -444,10 +463,14 @@
/// Clean up and destroy the context associated with the given folder.
void _destroyAnalysisContext(DriverBasedAnalysisContext context) {
context.driver.dispose();
-
var rootFolder = context.contextRoot.root;
changeSubscriptions.remove(rootFolder)?.cancel();
- bazelSubscriptions.remove(rootFolder)?.cancel();
+ var watched = bazelWatchedPathsPerFolder.remove(rootFolder);
+ if (watched != null) {
+ for (var path in watched.paths) {
+ bazelWatcherService.stopWatching(watched.workspace, path);
+ }
+ }
driverMap.remove(rootFolder);
}
@@ -465,39 +488,29 @@
///
/// Whenever the files change, we trigger re-analysis. This allows us to react
/// to creation/modification of files that were generated by Bazel.
- void _handleBazelFileNotification(
- Folder folder, BazelFileNotification notification) {
- var fileSubscriptions = bazelSubscriptions[folder].fileSubscriptions;
- if (fileSubscriptions.containsKey(notification.requested)) {
- // We have already established a Watcher for this particular path.
- return;
- }
- var watcher = notification.watcher(
- pollingDelayShort: Duration(seconds: 10),
- pollingDelayLong: Duration(seconds: 30));
- var subscription = watcher.events.listen(_handleBazelWatchEvent);
- fileSubscriptions[notification.requested] =
- _BazelFilesSubscription(watcher, subscription);
- watcher.start();
+ void _handleBazelSearchInfo(
+ Folder folder, String workspace, BazelSearchInfo info) {
+ var watched = bazelWatchedPathsPerFolder.putIfAbsent(
+ folder, () => _BazelWatchedFiles(workspace));
+ var added = watched.paths.add(info.requestedPath);
+ if (added) bazelWatcherService.startWatching(workspace, info);
}
/// Notifies the drivers that a generated Bazel file has changed.
- void _handleBazelWatchEvent(WatchEvent event) {
- if (event.type == ChangeType.ADD) {
- for (var driver in driverMap.values) {
- driver.addFile(event.path);
- // Since the file has been created after we've searched for it, the
- // URI resolution is likely wrong, so we need to reset it.
- driver.resetUriResolution();
+ void _handleBazelWatchEvents(List<WatchEvent> events) {
+ for (var driver in driverMap.values) {
+ var needsUriReset = false;
+ for (var event in events) {
+ if (event.type == ChangeType.ADD) {
+ driver.addFile(event.path);
+ needsUriReset = true;
+ }
+ if (event.type == ChangeType.MODIFY) driver.changeFile(event.path);
+ if (event.type == ChangeType.REMOVE) driver.removeFile(event.path);
}
- } else if (event.type == ChangeType.MODIFY) {
- for (var driver in driverMap.values) {
- driver.changeFile(event.path);
- }
- } else if (event.type == ChangeType.REMOVE) {
- for (var driver in driverMap.values) {
- driver.removeFile(event.path);
- }
+ // Since the file has been created after we've searched for it, the
+ // URI resolution is likely wrong, so we need to reset it.
+ if (needsUriReset) driver.resetUriResolution();
}
}
@@ -584,43 +597,17 @@
if (!experimentalEnableBazelWatching) return;
var workspace = analysisDriver.analysisContext.contextRoot.workspace;
if (workspace is BazelWorkspace &&
- !bazelSubscriptions.containsKey(folder)) {
- var subscription = workspace.bazelCandidateFiles.listen(
- (notification) => _handleBazelFileNotification(folder, notification));
- bazelSubscriptions[folder] = _BazelWorkspaceSubscription(subscription);
+ !bazelSearchSubscriptions.containsKey(folder)) {
+ var searchSubscription = workspace.bazelCandidateFiles.listen(
+ (notification) =>
+ _handleBazelSearchInfo(folder, workspace.root, notification));
+ bazelSearchSubscriptions[folder] = searchSubscription;
}
}
}
-/// A watcher with subscription used to detect changes to some file.
-class _BazelFilesSubscription {
- final BazelFileWatcher watcher;
- final StreamSubscription<WatchEvent> subscription;
-
- _BazelFilesSubscription(this.watcher, this.subscription);
-
- void cancel() {
- subscription.cancel();
- watcher.stop();
- }
-}
-
-/// A subscription to notifications from a Bazel workspace.
-class _BazelWorkspaceSubscription {
- final StreamSubscription<BazelFileNotification> workspaceSubscription;
-
- /// For each absolute path that we searched for, provides the subscriptions
- /// that we established to watch for changes.
- ///
- /// Note that the absolute path used when searching for a file is not
- /// necessarily the actual path of the file (see [BazelWorkspace.findFile] for
- /// details on how the files are searched).
- final fileSubscriptions = <String, _BazelFilesSubscription>{};
-
- _BazelWorkspaceSubscription(this.workspaceSubscription);
-
- void cancel() {
- workspaceSubscription.cancel();
- fileSubscriptions.values.forEach((sub) => sub.cancel());
- }
+class _BazelWatchedFiles {
+ final String workspace;
+ final paths = <String>{};
+ _BazelWatchedFiles(this.workspace);
}
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index 79e549c..d671c03 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -266,6 +266,8 @@
0, // length
declaration.locationStartLine,
declaration.locationStartColumn,
+ declaration.locationStartLine, // endLine
+ declaration.locationStartColumn, // endColumn
),
parameters: declaration.parameters,
returnType: declaration.returnType,
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
index bb4643f..c9fd823 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_listener.dart
@@ -79,9 +79,16 @@
/// Return the [Location] representing the specified offset and length
/// in the given compilation unit.
Location locationFor(ResolvedUnitResult result, int offset, int length) {
- final locInfo = result.unit.lineInfo.getLocation(offset);
- final location = Location(
- result.path, offset, length, locInfo.lineNumber, locInfo.columnNumber);
- return location;
+ var lineInfo = result.unit.lineInfo;
+ var startLocation = lineInfo.getLocation(offset);
+ var endLocation = lineInfo.getLocation(offset + length);
+ return Location(
+ result.path,
+ offset,
+ length,
+ startLocation.lineNumber,
+ startLocation.columnNumber,
+ endLocation.lineNumber,
+ endLocation.columnNumber);
}
}
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index 19afc27..e5e609d 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -137,6 +137,8 @@
InstrumentationService instrumentationService, {
http.Client httpClient,
DiagnosticServer diagnosticServer,
+ // Disable to avoid using this in unit tests.
+ bool enableBazelWatcher = false,
}) : super(
options,
sdkManager,
@@ -146,6 +148,7 @@
instrumentationService,
httpClient,
LspNotificationManager(channel, baseResourceProvider.pathContext),
+ enableBazelWatcher: enableBazelWatcher,
) {
notificationManager.server = this;
messageHandler = UninitializedStateMessageHandler(this);
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
index 832f432..419fe43 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
@@ -68,12 +68,14 @@
stateLocation: analysisServerOptions.cacheFolder);
analysisServer = LspAnalysisServer(
- serverChannel,
- resourceProvider,
- analysisServerOptions,
- sdkManager,
- CrashReportingAttachmentsBuilder.empty,
- instrumentationService,
- diagnosticServer: diagnosticServer);
+ serverChannel,
+ resourceProvider,
+ analysisServerOptions,
+ sdkManager,
+ CrashReportingAttachmentsBuilder.empty,
+ instrumentationService,
+ diagnosticServer: diagnosticServer,
+ enableBazelWatcher: true,
+ );
}
}
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 598e99d..b330f89 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -15,7 +15,6 @@
import 'package:analyzer/error/error.dart' as engine;
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/source.dart' as engine;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -116,15 +115,23 @@
var length = error.length;
var startLine = -1;
var startColumn = -1;
+ var endLine = -1;
+ var endColumn = -1;
var lineInfo = result.lineInfo;
if (lineInfo != null) {
- CharacterLocation lineLocation = lineInfo.getLocation(offset);
- if (lineLocation != null) {
- startLine = lineLocation.lineNumber;
- startColumn = lineLocation.columnNumber;
+ var startLocation = lineInfo.getLocation(offset);
+ if (startLocation != null) {
+ startLine = startLocation.lineNumber;
+ startColumn = startLocation.columnNumber;
+ }
+ var endLocation = lineInfo.getLocation(offset + length);
+ if (endLocation != null) {
+ endLine = endLocation.lineNumber;
+ endColumn = endLocation.columnNumber;
}
}
- location = Location(file, offset, length, startLine, startColumn);
+ location = Location(
+ file, offset, length, startLine, startColumn, endLine, endColumn);
}
// Default to the error's severity if none is specified.
@@ -158,12 +165,18 @@
var offset = message.offset;
var length = message.length;
- var lineLocation = result.lineInfo.getLocation(offset);
- var startLine = lineLocation.lineNumber;
- var startColumn = lineLocation.columnNumber;
+ var startLocation = result.lineInfo.getLocation(offset);
+ var startLine = startLocation.lineNumber;
+ var startColumn = startLocation.columnNumber;
+
+ var endLocation = result.lineInfo.getLocation(offset + length);
+ var endLine = endLocation.lineNumber;
+ var endColumn = endLocation.columnNumber;
return DiagnosticMessage(
- message.message, Location(file, offset, length, startLine, startColumn));
+ message.message,
+ Location(
+ file, offset, length, startLine, startColumn, endLine, endColumn));
}
/// Create a Location based on an [engine.Element].
@@ -286,17 +299,23 @@
engine.CompilationUnitElement unitElement, engine.SourceRange range) {
var startLine = 0;
var startColumn = 0;
+ var endLine = 0;
+ var endColumn = 0;
try {
var lineInfo = unitElement.lineInfo;
if (lineInfo != null) {
- CharacterLocation offsetLocation = lineInfo.getLocation(range.offset);
- startLine = offsetLocation.lineNumber;
- startColumn = offsetLocation.columnNumber;
+ var startLocation = lineInfo.getLocation(range.offset);
+ startLine = startLocation.lineNumber;
+ startColumn = startLocation.columnNumber;
+
+ var endLocation = lineInfo.getLocation(range.end);
+ endLine = endLocation.lineNumber;
+ endColumn = endLocation.columnNumber;
}
} on AnalysisException {
// TODO(brianwilkerson) It doesn't look like the code in the try block
// should be able to throw an exception. Try removing the try statement.
}
return Location(unitElement.source.fullName, range.offset, range.length,
- startLine, startColumn);
+ startLine, startColumn, endLine, endColumn);
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
index 5eaa1c5..efead5f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -154,10 +154,10 @@
if (id != null) {
name = id.name;
// TODO(danrubel) use lineInfo to determine startLine and startColumn
- location = Location(source.fullName, id.offset, id.length, 0, 0);
+ location = Location(source.fullName, id.offset, id.length, 0, 0, 0, 0);
} else {
name = '';
- location = Location(source.fullName, -1, 0, 1, 0);
+ location = Location(source.fullName, -1, 0, 1, 0, 1, 0);
}
var flags = protocol.Element.makeFlags(
isAbstract: isAbstract,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.dart b/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.dart
index 4ecdfcf..92fc7ad 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/assign_to_local_variable.dart
@@ -19,7 +19,6 @@
Future<void> compute(ChangeBuilder builder) async {
// prepare enclosing ExpressionStatement
ExpressionStatement expressionStatement;
- // ignore: unnecessary_this
for (var node = this.node; node != null; node = node.parent) {
if (node is ExpressionStatement) {
expressionStatement = node;
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index b86d18d..a72d97b 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -81,6 +81,7 @@
requestStatistics: requestStatistics,
diagnosticServer: diagnosticServer,
detachableFileSystemManager: detachableFileSystemManager,
+ enableBazelWatcher: true,
);
detachableFileSystemManager?.setAnalysisServer(analysisServer);
}
diff --git a/pkg/analysis_server/test/analysis/bazel_changes_test.dart b/pkg/analysis_server/test/analysis/bazel_changes_test.dart
deleted file mode 100644
index 896d08c..0000000
--- a/pkg/analysis_server/test/analysis/bazel_changes_test.dart
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-
-import 'package:analysis_server/protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol_constants.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/context_manager.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../analysis_abstract.dart';
-
-void main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(BazelChangesTest);
- });
-}
-
-@reflectiveTest
-class BazelChangesTest extends AbstractAnalysisTest {
- Map<String, List<AnalysisError>> filesErrors = {};
- Completer<void> processedNotification;
-
- @override
- void processNotification(Notification notification) {
- if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
- var decoded = AnalysisErrorsParams.fromNotification(notification);
- filesErrors[decoded.file] = decoded.errors;
- processedNotification?.complete();
- }
- }
-
- @override
- void setUp() {
- super.setUp();
-
- experimentalEnableBazelWatching = true;
-
- projectPath = convertPath('/workspaceRoot/third_party/dart/project');
- testFile =
- convertPath('/workspaceRoot/third_party/dart/project/lib/test.dart');
- newFile('/workspaceRoot/WORKSPACE');
- newFolder('/workspaceRoot/bazel-lib/project');
- newFolder('/workspaceRoot/bazel-genfiles/project');
- }
-
- @override
- void tearDown() {
- // Make sure to destroy all the contexts and cancel all subscriptions to
- // file watchers.
- server.contextManager.setRoots([], []);
-
- experimentalEnableBazelWatching = false;
-
- super.tearDown();
- }
-
- Future<void> test_findingFileInGenfiles() async {
- processedNotification = Completer();
-
- newFile(testFile, content: r'''
-import 'generated.dart';
-void main() { fun(); }
-''');
- createProject();
-
- // We should have some errors since the `generated.dart` is not there yet.
- await processedNotification.future;
- expect(filesErrors[testFile], isNotEmpty);
-
- // Clear errors, so that we'll notice new results.
- filesErrors.clear();
- processedNotification = Completer();
-
- // Simulate the creation of a generated file.
- newFile(
- '/workspaceRoot/bazel-genfiles/'
- 'third_party/dart/project/lib/generated.dart',
- content: 'fun() {}');
-
- // No errors.
- await processedNotification.future;
- expect(filesErrors[testFile], isEmpty);
- }
-}
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 3329d7f..1187065 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -4,7 +4,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'bazel_changes_test.dart' as bazel_changes;
import 'get_errors_test.dart' as get_errors;
import 'get_hover_test.dart' as get_hover;
import 'get_navigation_test.dart' as get_navigation;
@@ -27,7 +26,6 @@
void main() {
defineReflectiveSuite(() {
- bazel_changes.main();
get_errors.main();
get_hover.main();
get_navigation.main();
diff --git a/pkg/analysis_server/test/client/impl/expect_mixin.dart b/pkg/analysis_server/test/client/impl/expect_mixin.dart
index abbfe42..803a6858 100644
--- a/pkg/analysis_server/test/client/impl/expect_mixin.dart
+++ b/pkg/analysis_server/test/client/impl/expect_mixin.dart
@@ -30,7 +30,6 @@
} else if (x is _Predicate<Null>) {
// x is a unary predicate, but expects a specific type
// so wrap it.
- // ignore: unnecessary_lambdas
return predicate((a) => (x as dynamic)(a));
} else {
return equals(x);
diff --git a/pkg/analysis_server/test/constants.dart b/pkg/analysis_server/test/constants.dart
index 817f2a2..8c6d848 100644
--- a/pkg/analysis_server/test/constants.dart
+++ b/pkg/analysis_server/test/constants.dart
@@ -7,6 +7,8 @@
const String CONTEXT_MESSAGES = 'contextMessages';
const String CORRECTION = 'correction';
const String EDITS = 'edits';
+const String END_COLUMN = 'endColumn';
+const String END_LINE = 'endLine';
const String FILE = 'file';
const String FILE_STAMP = 'fileStamp';
const String HAS_FIX = 'hasFix';
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 7a0ca44..db742d8 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -70,7 +70,7 @@
var fixes = plugin.AnalysisErrorFixes(AnalysisError(
AnalysisErrorSeverity.ERROR,
AnalysisErrorType.HINT,
- Location('', 0, 0, 0, 0),
+ Location('', 0, 0, 0, 0, 0, 0),
'message',
'code'));
var result = plugin.EditGetFixesResult(<plugin.AnalysisErrorFixes>[fixes]);
diff --git a/pkg/analysis_server/test/integration/server/bazel_changes_test.dart b/pkg/analysis_server/test/integration/server/bazel_changes_test.dart
new file mode 100644
index 0000000..a70cd13
--- /dev/null
+++ b/pkg/analysis_server/test/integration/server/bazel_changes_test.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../support/integration_tests.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(BazelChangesTest);
+ });
+}
+
+@reflectiveTest
+class BazelChangesTest extends AbstractAnalysisServerIntegrationTest {
+ var processedNotification = Completer<void>();
+
+ /// Path to the `command.log` file.
+ ///
+ /// Writing to it should trigger our change detection to run.
+ String commandLogPath;
+
+ String bazelRoot;
+ String tmpPath;
+ String workspacePath;
+ String bazelOutPath;
+ String bazelBinPath;
+ String bazelGenfilesPath;
+ Directory oldSourceDirectory;
+
+ String inTmpDir(String relative) =>
+ path.join(tmpPath, relative.replaceAll('/', path.separator));
+
+ String inWorkspace(String relative) =>
+ path.join(workspacePath, relative.replaceAll('/', path.separator));
+
+ @override
+ Future setUp() async {
+ await super.setUp();
+ oldSourceDirectory = sourceDirectory;
+
+ tmpPath = Directory(Directory.systemTemp
+ .createTempSync('analysisServer')
+ .resolveSymbolicLinksSync())
+ .path;
+ workspacePath = inTmpDir('workspace_root');
+ writeFile(inWorkspace('WORKSPACE'), '');
+
+ sourceDirectory = Directory(inWorkspace('third_party/dart/project'));
+ sourceDirectory.createSync(recursive: true);
+
+ bazelRoot = inTmpDir('bazel_root');
+ Directory(bazelRoot).createSync(recursive: true);
+
+ bazelOutPath = '$bazelRoot/execroot/bazel_workspace/bazel-out';
+ bazelBinPath = '$bazelRoot/execroot/bazel_workspace/bazel-out/bin';
+ bazelGenfilesPath =
+ '$bazelRoot/execroot/bazel_workspace/bazel-out/genfiles';
+
+ Directory(inTmpDir(bazelOutPath)).createSync(recursive: true);
+ Directory(inTmpDir(bazelBinPath)).createSync(recursive: true);
+ Directory(inTmpDir(bazelGenfilesPath)).createSync(recursive: true);
+
+ Link(inWorkspace('bazel-out')).createSync(bazelOutPath);
+ Link(inWorkspace('bazel-bin')).createSync(bazelBinPath);
+ Link(inWorkspace('bazel-genfiles')).createSync(bazelGenfilesPath);
+
+ commandLogPath = inTmpDir('$bazelRoot/command.log');
+ }
+
+ @override
+ Future tearDown() async {
+ Directory(tmpPath).deleteSync(recursive: true);
+ sourceDirectory = oldSourceDirectory;
+ await super.tearDown();
+ }
+
+ // Add a bit more time -- the isolate take a while to start when the test is
+ // not run from a snapshot.
+ @TestTimeout(Timeout.factor(2))
+ Future<void> test_bazelChanges() async {
+ var testFile = inWorkspace('${sourceDirectory.path}/lib/test.dart');
+
+ var errors = <AnalysisError>[];
+ onAnalysisErrors.listen((event) {
+ if (event.file == testFile) {
+ errors.addAll(event.errors);
+ processedNotification.complete();
+ }
+ });
+ var resetCompleterAndErrors = () async {
+ // This is necessary because our polling uses modification timestamps
+ // whose resolution seems to be too small for a test like this (i.e., we
+ // write to the `command.log` file, but if the modification timestamp
+ // doesn't change, we won't detect the change).
+ await Future.delayed(Duration(seconds: 1));
+ errors.clear();
+ processedNotification = Completer();
+ };
+
+ writeFile(testFile, r'''
+import 'generated.dart';
+void main() { my_fun(); }
+''');
+ standardAnalysisSetup();
+
+ await processedNotification.future;
+ expect(errors, isNotEmpty);
+ expect(errors[0].message, contains('generated.dart'));
+
+ // This seems to be necessary (at least when running the test from source),
+ // because it takes a while for the watcher isolate to start.
+ await Future.delayed(Duration(seconds: 10));
+
+ await resetCompleterAndErrors();
+ var generatedFilePath = inWorkspace(
+ '$bazelGenfilesPath/third_party/dart/project/lib/generated.dart');
+ writeFile(generatedFilePath, 'my_fun() {}');
+ writeFile(commandLogPath, 'Build completed successfully');
+
+ await processedNotification.future;
+ expect(errors, isEmpty);
+
+ // Now let's write a file that does not define `my_fun` -- we should get an
+ // error again.
+ await resetCompleterAndErrors();
+ writeFile(generatedFilePath, 'different_fun() {}');
+ writeFile(commandLogPath, 'Build completed successfully');
+
+ await processedNotification.future;
+ expect(errors, isNotEmpty);
+
+ // Now delete the file completely.
+ await resetCompleterAndErrors();
+ File(generatedFilePath).deleteSync();
+ writeFile(commandLogPath, 'Build completed successfully');
+
+ await processedNotification.future;
+ expect(errors, isNotEmpty);
+
+ // And finally re-add the correct file -- errors should go away once again.
+ await resetCompleterAndErrors();
+ writeFile(generatedFilePath, 'my_fun() {}');
+ writeFile(commandLogPath, 'Build completed successfully');
+
+ await processedNotification.future;
+ expect(errors, isEmpty);
+ }
+}
diff --git a/pkg/analysis_server/test/integration/server/test_all.dart b/pkg/analysis_server/test/integration/server/test_all.dart
index 0a23427..92ae2b1 100644
--- a/pkg/analysis_server/test/integration/server/test_all.dart
+++ b/pkg/analysis_server/test/integration/server/test_all.dart
@@ -4,6 +4,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'bazel_changes_test.dart' as bazel_changes_test;
import 'get_version_test.dart' as get_version_test;
import 'set_subscriptions_invalid_service_test.dart'
as set_subscriptions_invalid_service_test;
@@ -13,6 +14,7 @@
void main() {
defineReflectiveSuite(() {
+ bazel_changes_test.main();
get_version_test.main();
set_subscriptions_test.main();
set_subscriptions_invalid_service_test.main();
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 49e185e..4a8e453 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -1122,13 +1122,17 @@
/// "length": int
/// "startLine": int
/// "startColumn": int
+/// "endLine": int
+/// "endColumn": int
/// }
final Matcher isLocation = LazyMatcher(() => MatchesJsonObject('Location', {
'file': isFilePath,
'offset': isInt,
'length': isInt,
'startLine': isInt,
- 'startColumn': isInt
+ 'startColumn': isInt,
+ 'endLine': isInt,
+ 'endColumn': isInt
}));
/// NavigationRegion
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index 5adeef9..741c410 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -33,12 +33,12 @@
final pluginError = plugin.AnalysisError(
plugin.AnalysisErrorSeverity.ERROR,
plugin.AnalysisErrorType.STATIC_TYPE_WARNING,
- plugin.Location(pluginAnalyzedFilePath, 0, 6, 0, 0),
+ plugin.Location(pluginAnalyzedFilePath, 0, 6, 0, 0, 0, 6),
'Test error from plugin',
'ERR1',
contextMessages: [
plugin.DiagnosticMessage('Related error',
- plugin.Location(pluginAnalyzedFilePath, 31, 4, 1, 12))
+ plugin.Location(pluginAnalyzedFilePath, 31, 4, 1, 12, 1, 16))
],
);
final pluginResult =
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 8378710..4b290ce 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -71,7 +71,9 @@
OFFSET: 10,
LENGTH: 20,
START_LINE: 3,
- START_COLUMN: 2
+ START_COLUMN: 2,
+ END_LINE: 4,
+ END_COLUMN: 11,
},
MESSAGE: 'my message',
CODE: 'ambiguous_export',
@@ -84,7 +86,9 @@
OFFSET: 30,
LENGTH: 5,
START_LINE: 4,
- START_COLUMN: 11
+ START_COLUMN: 11,
+ END_LINE: 4,
+ END_COLUMN: 16,
}
}
],
@@ -103,7 +107,9 @@
OFFSET: 10,
LENGTH: 20,
START_LINE: 3,
- START_COLUMN: 2
+ START_COLUMN: 2,
+ END_LINE: 4,
+ END_COLUMN: 11,
},
MESSAGE: 'my message',
CORRECTION: 'my correction',
@@ -129,7 +135,9 @@
OFFSET: 10,
LENGTH: 20,
START_LINE: 3,
- START_COLUMN: 2
+ START_COLUMN: 2,
+ END_LINE: 4,
+ END_COLUMN: 11,
},
MESSAGE: 'my message',
CODE: 'test_error',
@@ -154,7 +162,9 @@
OFFSET: 10,
LENGTH: 20,
START_LINE: 3,
- START_COLUMN: 2
+ START_COLUMN: 2,
+ END_LINE: 4,
+ END_COLUMN: 11,
},
MESSAGE: 'my message',
CODE: 'my_lint',
@@ -174,7 +184,9 @@
OFFSET: 10,
LENGTH: 20,
START_LINE: 3,
- START_COLUMN: 2
+ START_COLUMN: 2,
+ END_LINE: 4,
+ END_COLUMN: 11,
},
MESSAGE: 'my message',
CODE: 'ambiguous_export',
@@ -197,7 +209,9 @@
OFFSET: 10,
LENGTH: 20,
START_LINE: -1,
- START_COLUMN: -1
+ START_COLUMN: -1,
+ END_LINE: -1,
+ END_COLUMN: -1,
},
MESSAGE: 'my message',
CODE: 'ambiguous_export',
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index 96fb856..0e00b19 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -98,7 +98,7 @@
}
void test_addFatalError_withLocation() {
- var location = Location('/test.dart', 1, 2, 3, 4);
+ var location = Location('/test.dart', 1, 2, 3, 4, 5, 6);
var refactoringStatus = RefactoringStatus();
// initial state
expect(refactoringStatus.severity, null);
@@ -211,7 +211,7 @@
}
void test_newError() {
- var location = Location('/test.dart', 1, 2, 3, 4);
+ var location = Location('/test.dart', 1, 2, 3, 4, 5, 6);
var refactoringStatus = RefactoringStatus.error('msg', location);
expect(refactoringStatus.severity, RefactoringProblemSeverity.ERROR);
expect(refactoringStatus.problem.message, 'msg');
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
index 124af22..5f6c972 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -70,7 +70,9 @@
"offset": 6,
"length": 0,
"startLine": 1,
- "startColumn": 7
+ "startColumn": 7,
+ "endLine": 1,
+ "endColumn": 7
},
"flags": 0
},
@@ -93,7 +95,9 @@
"offset": 14,
"length": 0,
"startLine": 2,
- "startColumn": 5
+ "startColumn": 5,
+ "endLine": 2,
+ "endColumn": 5
},
"flags": 0,
"parameters": "()",
@@ -140,7 +144,9 @@
"offset": 15,
"length": 0,
"startLine": 1,
- "startColumn": 16
+ "startColumn": 16,
+ "endLine": 1,
+ "endColumn": 16
},
"flags": 1
},
@@ -163,7 +169,9 @@
"offset": 40,
"length": 0,
"startLine": 3,
- "startColumn": 13
+ "startColumn": 13,
+ "endLine": 3,
+ "endColumn": 13
},
"flags": 0,
"parameters": "()",
@@ -209,7 +217,9 @@
"offset": 21,
"length": 0,
"startLine": 2,
- "startColumn": 7
+ "startColumn": 7,
+ "endLine": 2,
+ "endColumn": 7
},
"flags": 0
},
@@ -234,7 +244,9 @@
"offset": 24,
"length": 0,
"startLine": 2,
- "startColumn": 7
+ "startColumn": 7,
+ "endLine": 2,
+ "endColumn": 7
},
"flags": 0
},
@@ -271,7 +283,9 @@
"offset": 5,
"length": 0,
"startLine": 1,
- "startColumn": 6
+ "startColumn": 6,
+ "endLine": 1,
+ "endColumn": 6
},
"flags": 0
},
@@ -294,7 +308,9 @@
"offset": 16,
"length": 0,
"startLine": 2,
- "startColumn": 3
+ "startColumn": 3,
+ "endLine": 2,
+ "endColumn": 3
},
"flags": 0
},
@@ -318,7 +334,9 @@
"offset": 23,
"length": 0,
"startLine": 3,
- "startColumn": 3
+ "startColumn": 3,
+ "endLine": 3,
+ "endColumn": 3
},
"flags": 0
},
@@ -356,7 +374,9 @@
"offset": 4,
"length": 0,
"startLine": 1,
- "startColumn": 5
+ "startColumn": 5,
+ "endLine": 1,
+ "endColumn": 5
},
"flags": 0,
"returnType": ""
@@ -380,7 +400,9 @@
"offset": 23,
"length": 0,
"startLine": 2,
- "startColumn": 5
+ "startColumn": 5,
+ "endLine": 2,
+ "endColumn": 5
},
"flags": 0,
"returnType": ""
@@ -404,7 +426,9 @@
"offset": 37,
"length": 0,
"startLine": 3,
- "startColumn": 5
+ "startColumn": 5,
+ "endLine": 3,
+ "endColumn": 5
},
"flags": 0,
"returnType": ""
@@ -428,7 +452,9 @@
"offset": 56,
"length": 0,
"startLine": 4,
- "startColumn": 5
+ "startColumn": 5,
+ "endLine": 4,
+ "endColumn": 5
},
"flags": 0,
"returnType": ""
diff --git a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
index ce4d3c4..3d84f35 100644
--- a/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
+++ b/pkg/analysis_server/test/src/plugin/protocol_test_utilities.dart
@@ -79,7 +79,7 @@
Element element(int stringIndex, int intIndex, {ElementKind kind}) =>
Element(kind ?? ElementKind.CLASS, strings[stringIndex++], intIndex++,
location: Location(fileName(stringIndex++), intIndex++, intIndex++,
- intIndex++, intIndex++),
+ intIndex++, intIndex++, intIndex++, intIndex++),
parameters: strings[stringIndex++],
returnType: strings[stringIndex++],
typeParameters: strings[stringIndex++]);
@@ -98,6 +98,8 @@
intIndex++,
intIndex++,
intIndex++,
+ intIndex++,
+ intIndex++,
intIndex++);
/// On return, increment [stringIndex] by 5 and [intIndex] by 7.
diff --git a/pkg/analysis_server/test/src/plugin/result_merger_test.dart b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
index bb31233..934e335 100644
--- a/pkg/analysis_server/test/src/plugin/result_merger_test.dart
+++ b/pkg/analysis_server/test/src/plugin/result_merger_test.dart
@@ -29,7 +29,7 @@
AnalysisError createError(int offset) {
var severity = AnalysisErrorSeverity.ERROR;
var type = AnalysisErrorType.HINT;
- var location = Location('test.dart', offset, 2, 3, 4);
+ var location = Location('test.dart', offset, 2, 3, 4, 5, 6);
return AnalysisError(severity, type, location, '', '');
}
@@ -68,7 +68,7 @@
AnalysisError createError(int offset) {
var severity = AnalysisErrorSeverity.ERROR;
var type = AnalysisErrorType.HINT;
- var location = Location('test.dart', offset, 2, 3, 4);
+ var location = Location('test.dart', offset, 2, 3, 4, 5, 6);
return AnalysisError(severity, type, location, '', '');
}
@@ -265,7 +265,7 @@
void test_mergeOutline() {
Element element(ElementKind kind, int offset) {
- var location = Location('', offset, 0, 0, 0);
+ var location = Location('', offset, 0, 0, 0, 0, 0);
return Element(kind, '', 0, location: location);
}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/Location.java b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
index 2daf9de..1df7d78 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/Location.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/Location.java
@@ -61,14 +61,26 @@
private final int startColumn;
/**
+ * The one-based index of the line containing the character immediately following the range.
+ */
+ private final int endLine;
+
+ /**
+ * The one-based index of the column containing the character immediately following the range.
+ */
+ private final int endColumn;
+
+ /**
* Constructor for {@link Location}.
*/
- public Location(String file, int offset, int length, int startLine, int startColumn) {
+ public Location(String file, int offset, int length, int startLine, int startColumn, int endLine, int endColumn) {
this.file = file;
this.offset = offset;
this.length = length;
this.startLine = startLine;
this.startColumn = startColumn;
+ this.endLine = endLine;
+ this.endColumn = endColumn;
}
@Override
@@ -80,7 +92,9 @@
other.offset == offset &&
other.length == length &&
other.startLine == startLine &&
- other.startColumn == startColumn;
+ other.startColumn == startColumn &&
+ other.endLine == endLine &&
+ other.endColumn == endColumn;
}
return false;
}
@@ -91,7 +105,9 @@
int length = jsonObject.get("length").getAsInt();
int startLine = jsonObject.get("startLine").getAsInt();
int startColumn = jsonObject.get("startColumn").getAsInt();
- return new Location(file, offset, length, startLine, startColumn);
+ int endLine = jsonObject.get("endLine").getAsInt();
+ int endColumn = jsonObject.get("endColumn").getAsInt();
+ return new Location(file, offset, length, startLine, startColumn, endLine, endColumn);
}
public static List<Location> fromJsonArray(JsonArray jsonArray) {
@@ -107,6 +123,20 @@
}
/**
+ * The one-based index of the column containing the character immediately following the range.
+ */
+ public int getEndColumn() {
+ return endColumn;
+ }
+
+ /**
+ * The one-based index of the line containing the character immediately following the range.
+ */
+ public int getEndLine() {
+ return endLine;
+ }
+
+ /**
* The file containing the range.
*/
public String getFile() {
@@ -149,6 +179,8 @@
builder.append(length);
builder.append(startLine);
builder.append(startColumn);
+ builder.append(endLine);
+ builder.append(endColumn);
return builder.toHashCode();
}
@@ -159,6 +191,8 @@
jsonObject.addProperty("length", length);
jsonObject.addProperty("startLine", startLine);
jsonObject.addProperty("startColumn", startColumn);
+ jsonObject.addProperty("endLine", endLine);
+ jsonObject.addProperty("endColumn", endColumn);
return jsonObject;
}
@@ -175,7 +209,11 @@
builder.append("startLine=");
builder.append(startLine + ", ");
builder.append("startColumn=");
- builder.append(startColumn);
+ builder.append(startColumn + ", ");
+ builder.append("endLine=");
+ builder.append(endLine + ", ");
+ builder.append("endColumn=");
+ builder.append(endColumn);
builder.append("]");
return builder.toString();
}
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
index dc0fead..13e33f1 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart
@@ -3495,6 +3495,8 @@
/// "length": int
/// "startLine": int
/// "startColumn": int
+/// "endLine": int
+/// "endColumn": int
/// }
///
/// Clients may not extend, implement or mix-in this class.
@@ -3509,6 +3511,10 @@
int _startColumn;
+ int _endLine;
+
+ int _endColumn;
+
/// The file containing the range.
String get file => _file;
@@ -3558,13 +3564,37 @@
_startColumn = value;
}
- Location(
- String file, int offset, int length, int startLine, int startColumn) {
+ /// The one-based index of the line containing the character immediately
+ /// following the range.
+ int get endLine => _endLine;
+
+ /// The one-based index of the line containing the character immediately
+ /// following the range.
+ set endLine(int value) {
+ assert(value != null);
+ _endLine = value;
+ }
+
+ /// The one-based index of the column containing the character immediately
+ /// following the range.
+ int get endColumn => _endColumn;
+
+ /// The one-based index of the column containing the character immediately
+ /// following the range.
+ set endColumn(int value) {
+ assert(value != null);
+ _endColumn = value;
+ }
+
+ Location(String file, int offset, int length, int startLine, int startColumn,
+ int endLine, int endColumn) {
this.file = file;
this.offset = offset;
this.length = length;
this.startLine = startLine;
this.startColumn = startColumn;
+ this.endLine = endLine;
+ this.endColumn = endColumn;
}
factory Location.fromJson(
@@ -3603,7 +3633,21 @@
} else {
throw jsonDecoder.mismatch(jsonPath, 'startColumn');
}
- return Location(file, offset, length, startLine, startColumn);
+ int endLine;
+ if (json.containsKey('endLine')) {
+ endLine = jsonDecoder.decodeInt(jsonPath + '.endLine', json['endLine']);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, 'endLine');
+ }
+ int endColumn;
+ if (json.containsKey('endColumn')) {
+ endColumn =
+ jsonDecoder.decodeInt(jsonPath + '.endColumn', json['endColumn']);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, 'endColumn');
+ }
+ return Location(
+ file, offset, length, startLine, startColumn, endLine, endColumn);
} else {
throw jsonDecoder.mismatch(jsonPath, 'Location', json);
}
@@ -3617,6 +3661,8 @@
result['length'] = length;
result['startLine'] = startLine;
result['startColumn'] = startColumn;
+ result['endLine'] = endLine;
+ result['endColumn'] = endColumn;
return result;
}
@@ -3630,7 +3676,9 @@
offset == other.offset &&
length == other.length &&
startLine == other.startLine &&
- startColumn == other.startColumn;
+ startColumn == other.startColumn &&
+ endLine == other.endLine &&
+ endColumn == other.endColumn;
}
return false;
}
@@ -3643,6 +3691,8 @@
hash = JenkinsSmiHash.combine(hash, length.hashCode);
hash = JenkinsSmiHash.combine(hash, startLine.hashCode);
hash = JenkinsSmiHash.combine(hash, startColumn.hashCode);
+ hash = JenkinsSmiHash.combine(hash, endLine.hashCode);
+ hash = JenkinsSmiHash.combine(hash, endColumn.hashCode);
return JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/analyzer/lib/src/context/packages.dart b/pkg/analyzer/lib/src/context/packages.dart
index f3dad37..d63d228 100644
--- a/pkg/analyzer/lib/src/context/packages.dart
+++ b/pkg/analyzer/lib/src/context/packages.dart
@@ -5,7 +5,6 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/package_config_json.dart';
import 'package:analyzer/src/util/uri.dart';
-// ignore: import_of_legacy_library_into_null_safe
import 'package:package_config/src/packages_file.dart'
as package_config_packages_file;
import 'package:pub_semver/pub_semver.dart';
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 986e5a0..f9d86f5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -438,27 +438,24 @@
var excludeOptions =
analyzerOptions.valueAt(AnalyzerOptions.exclude);
if (excludeOptions is YamlList) {
- List<String>? excludeList = toStringList(excludeOptions);
- if (excludeList != null) {
- var pathContext = resourceProvider.pathContext;
+ var pathContext = resourceProvider.pathContext;
- void addGlob(List<String> components) {
- var pattern = posix.joinAll(components);
- patterns.add(Glob(pattern, context: pathContext));
+ void addGlob(List<String> components) {
+ var pattern = posix.joinAll(components);
+ patterns.add(Glob(pattern, context: pathContext));
+ }
+
+ for (String excludedPath in excludeOptions.whereType<String>()) {
+ var excludedComponents = posix.split(excludedPath);
+ if (pathContext.isRelative(excludedPath)) {
+ excludedComponents = [
+ ...pathContext.split(optionsFile.parent2.path),
+ ...excludedComponents,
+ ];
}
-
- for (String excludedPath in excludeList) {
- var excludedComponents = posix.split(excludedPath);
- if (pathContext.isRelative(excludedPath)) {
- excludedComponents = [
- ...pathContext.split(optionsFile.parent2.path),
- ...excludedComponents,
- ];
- }
- addGlob(excludedComponents);
- if (excludedComponents.last == '**') {
- addGlob(excludedComponents..removeLast());
- }
+ addGlob(excludedComponents);
+ if (excludedComponents.last == '**') {
+ addGlob(excludedComponents..removeLast());
}
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index b90401a..0703381 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -80,7 +80,7 @@
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 130;
+ static const int DATA_VERSION = 132;
/// The length of the list returned by [_computeDeclaredVariablesSignature].
static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index b2a37c1..a656852 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1235,9 +1235,8 @@
if (linkedNode != null) {
var containerRef = reference!.getChild('@enum');
- var linkedNode = this.linkedNode as CompilationUnit;
_enums =
- linkedNode.declarations.whereType<EnumDeclarationImpl>().map((node) {
+ _linkedUnitDeclarations.whereType<EnumDeclarationImpl>().map((node) {
var name = node.name.name;
var reference = containerRef.getChild(name);
var element = node.declaredElement;
@@ -1264,11 +1263,10 @@
}
if (linkedNode != null) {
- var linkedNode = this.linkedNode as CompilationUnit;
var containerRef = reference!.getChild('@extension');
_extensions = <ExtensionElement>[];
var nextUnnamedExtensionId = 0;
- for (var node in linkedNode.declarations) {
+ for (var node in _linkedUnitDeclarations) {
if (node is ExtensionDeclarationImpl) {
var nameIdentifier = node.name;
var refName = nameIdentifier != null
@@ -1303,7 +1301,7 @@
if (linkedNode != null) {
var containerRef = reference!.getChild('@function');
- return _functions = linkedContext!.unit_withDeclarations.declarations
+ return _functions = _linkedUnitDeclarations
.whereType<FunctionDeclarationImpl>()
.where((node) => !node.isGetter && !node.isSetter)
.map((node) {
@@ -1373,9 +1371,8 @@
}
if (linkedNode != null) {
- var linkedNode = this.linkedNode as CompilationUnit;
var containerRef = reference!.getChild('@mixin');
- var declarations = linkedNode.declarations;
+ var declarations = _linkedUnitDeclarations;
return _mixins =
declarations.whereType<MixinDeclarationImpl>().map((node) {
var name = node.name.name;
@@ -1432,7 +1429,7 @@
if (linkedNode != null) {
var containerRef = reference!.getChild('@typeAlias');
_typeAliases = <TypeAliasElement>[];
- for (var node in linkedContext!.unit_withDeclarations.declarations) {
+ for (var node in _linkedUnitDeclarations) {
String name;
if (node is FunctionTypeAlias) {
name = node.name.name;
@@ -1473,7 +1470,8 @@
if (linkedNode != null) {
var containerRef = reference!.getChild('@class');
_types = <ClassElement>[];
- for (var node in linkedContext!.unit_withDeclarations.declarations) {
+ var declarations = _linkedUnitDeclarations;
+ for (var node in declarations) {
if (node is ClassDeclaration) {
var name = node.name.name;
var reference = containerRef.getChild(name);
@@ -1508,6 +1506,10 @@
_types = types;
}
+ List<CompilationUnitMember> get _linkedUnitDeclarations {
+ return linkedContext!.unit_withDeclarations.declarations;
+ }
+
@override
bool operator ==(Object object) =>
object is CompilationUnitElementImpl && source == object.source;
@@ -4337,7 +4339,6 @@
@override
T? accept<T>(ElementVisitor<T> visitor) {
- // ignore: deprecated_member_use_from_same_package
visitor.visitFunctionTypeAliasElement(this);
return visitor.visitTypeAliasElement(this);
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
index 7294a2a..39fe163 100644
--- a/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart
@@ -2,15 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/constant/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/resolver/property_element_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -23,18 +25,14 @@
ErrorReporter get _errorReporter => _resolver.errorReporter;
+ bool get _genericMetadataIsEnabled =>
+ _definingLibrary.featureSet.isEnabled(Feature.generic_metadata);
+
void resolve(AnnotationImpl node) {
AstNode parent = node.parent;
- _resolve1(node);
-
- node.constructorName?.accept(_resolver);
- var element = node.element;
- if (element is ExecutableElement) {
- InferenceContext.setType(node.arguments, element.type);
- }
node.typeArguments?.accept(_resolver);
- node.arguments?.accept(_resolver);
+ _resolve(node);
var elementAnnotationImpl =
node.elementAnnotation as ElementAnnotationImpl?;
@@ -46,6 +44,136 @@
}
}
+ void _classGetter(
+ AnnotationImpl node,
+ ClassElement classElement,
+ SimpleIdentifierImpl? getterName,
+ ) {
+ ExecutableElement? getter;
+ if (getterName != null) {
+ getter = classElement.getGetter(getterName.name);
+ getter = _resolver.toLegacyElement(getter);
+ // Recovery, try to find a constructor.
+ getter ??= classElement.getNamedConstructor(getterName.name);
+ } else {
+ getter = classElement.unnamedConstructor;
+ }
+
+ getterName?.staticElement = getter;
+ node.element = getter;
+
+ if (getterName != null && getter is PropertyAccessorElement) {
+ _propertyAccessorElement(node, getterName, getter);
+ _resolveAnnotationElementGetter(node, getter);
+ } else if (getter is! ConstructorElement) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INVALID_ANNOTATION,
+ node,
+ );
+ }
+
+ node.arguments?.accept(_resolver);
+ }
+
+ void _constructorInvocation(
+ AnnotationImpl node,
+ ClassElement classElement,
+ SimpleIdentifierImpl? constructorName,
+ ArgumentList argumentList,
+ ) {
+ ConstructorElement? constructorElement;
+ if (constructorName != null) {
+ constructorElement = classElement.getNamedConstructor(
+ constructorName.name,
+ );
+ } else {
+ constructorElement = classElement.unnamedConstructor;
+ }
+
+ constructorElement = _resolver.toLegacyElement(constructorElement);
+ constructorName?.staticElement = constructorElement;
+ node.element = constructorElement;
+
+ if (constructorElement == null) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INVALID_ANNOTATION,
+ node,
+ );
+ argumentList.accept(_resolver);
+ return;
+ }
+
+ var typeParameters = classElement.typeParameters;
+
+ // If no type parameters, the elements are correct.
+ if (typeParameters.isEmpty) {
+ _resolveConstructorInvocationArguments(node);
+ InferenceContext.setType(argumentList, constructorElement.type);
+ argumentList.accept(_resolver);
+ return;
+ }
+
+ void resolveWithFixedTypeArguments(
+ List<DartType> typeArguments,
+ ConstructorElement constructorElement,
+ ) {
+ var type = classElement.instantiate(
+ typeArguments: typeArguments,
+ nullabilitySuffix: _resolver.noneOrStarSuffix,
+ );
+ constructorElement = ConstructorMember.from(constructorElement, type);
+ constructorName?.staticElement = constructorElement;
+ node.element = constructorElement;
+ _resolveConstructorInvocationArguments(node);
+
+ InferenceContext.setType(argumentList, constructorElement.type);
+ argumentList.accept(_resolver);
+ }
+
+ if (!_genericMetadataIsEnabled) {
+ var typeArguments = List.filled(
+ typeParameters.length,
+ DynamicTypeImpl.instance,
+ );
+ resolveWithFixedTypeArguments(typeArguments, constructorElement);
+ return;
+ }
+
+ var typeArgumentList = node.typeArguments;
+ if (typeArgumentList != null) {
+ List<DartType> typeArguments;
+ if (typeArgumentList.arguments.length == typeParameters.length) {
+ typeArguments = typeArgumentList.arguments
+ .map((element) => element.typeOrThrow)
+ .toList();
+ } else {
+ typeArguments = List.filled(
+ typeParameters.length,
+ DynamicTypeImpl.instance,
+ );
+ }
+ resolveWithFixedTypeArguments(typeArguments, constructorElement);
+ return;
+ }
+
+ argumentList.accept(_resolver);
+
+ var constructorRawType = _resolver.typeAnalyzer
+ .constructorToGenericFunctionType(constructorElement);
+
+ var inferred = _resolver.inferenceHelper.inferGenericInvoke(
+ node, constructorRawType, typeArgumentList, argumentList, node,
+ isConst: true)!;
+
+ constructorElement = ConstructorMember.from(
+ constructorElement,
+ inferred.returnType as InterfaceType,
+ );
+ constructorName?.staticElement = constructorElement;
+ node.element = constructorElement;
+ _resolveConstructorInvocationArguments(node);
+ }
+
/// Return a newly created cloner that can be used to clone constant
/// expressions.
///
@@ -54,218 +182,144 @@
return ConstantAstCloner();
}
- InterfaceType _instantiateAnnotationClass(ClassElement element) {
- return element.instantiate(
- typeArguments: List.filled(
- element.typeParameters.length,
- DynamicTypeImpl.instance,
- ),
- nullabilitySuffix: _resolver.noneOrStarSuffix,
- );
+ void _extensionGetter(
+ AnnotationImpl node,
+ ExtensionElement extensionElement,
+ SimpleIdentifierImpl? getterName,
+ ) {
+ ExecutableElement? getter;
+ if (getterName != null) {
+ getter = extensionElement.getGetter(getterName.name);
+ getter = _resolver.toLegacyElement(getter);
+ }
+
+ getterName?.staticElement = getter;
+ node.element = getter;
+
+ if (getterName != null && getter is PropertyAccessorElement) {
+ _propertyAccessorElement(node, getterName, getter);
+ _resolveAnnotationElementGetter(node, getter);
+ } else {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INVALID_ANNOTATION,
+ node,
+ );
+ }
+
+ node.arguments?.accept(_resolver);
}
- void _resolve1(AnnotationImpl node) {
- var nodeName = node.name;
+ void _propertyAccessorElement(
+ AnnotationImpl node,
+ SimpleIdentifierImpl name,
+ PropertyAccessorElement element,
+ ) {
+ element = _resolver.toLegacyElement(element);
+ name.staticElement = element;
+ node.element = element;
- if (nodeName is PrefixedIdentifierImpl) {
- var prefix = nodeName.prefix;
- var identifier = nodeName.identifier;
+ _resolveAnnotationElementGetter(node, element);
+ node.arguments?.accept(_resolver);
+ }
- prefix.accept(_resolver);
- var prefixElement = prefix.staticElement;
+ void _resolve(AnnotationImpl node) {
+ SimpleIdentifierImpl name1;
+ SimpleIdentifierImpl? name2;
+ SimpleIdentifierImpl? name3;
+ var nameNode = node.name;
+ if (nameNode is PrefixedIdentifierImpl) {
+ name1 = nameNode.prefix;
+ name2 = nameNode.identifier;
+ name3 = node.constructorName;
+ } else {
+ name1 = nameNode as SimpleIdentifierImpl;
+ name2 = node.constructorName;
+ }
+ var argumentList = node.arguments;
- if (prefixElement is ClassElement && node.arguments != null) {
- var element = prefixElement.getNamedConstructor(identifier.name);
- element = _resolver.toLegacyElement(element);
+ var element1 = _resolver.nameScope.lookup(name1.name).getter;
+ name1.staticElement = element1;
- identifier.staticElement = element;
- // TODO(scheglov) error?
- } else if (prefixElement is PrefixElement) {
- var resolver = PropertyElementResolver(_resolver);
- var result = resolver.resolvePrefixedIdentifier(
- node: nodeName,
- hasRead: true,
- hasWrite: false,
- forAnnotation: true,
- );
+ if (element1 == null) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.UNDEFINED_ANNOTATION,
+ node,
+ [name1.name],
+ );
+ node.arguments?.accept(_resolver);
+ return;
+ }
- var element = result.readElement;
- identifier.staticElement = element;
+ // Class(args) or Class.CONST
+ if (element1 is ClassElement) {
+ if (argumentList != null) {
+ _constructorInvocation(node, element1, name2, argumentList);
+ } else {
+ _classGetter(node, element1, name2);
+ }
+ return;
+ }
- if (element == null) {
+ // Extension.CONST
+ if (element1 is ExtensionElement) {
+ _extensionGetter(node, element1, name2);
+ return;
+ }
+
+ // prefix.*
+ if (element1 is PrefixElement) {
+ if (name2 != null) {
+ var element2 = element1.scope.lookup(name2.name).getter;
+ name2.staticElement = element2;
+ // prefix.Class(args) or prefix.Class.CONST
+ if (element2 is ClassElement) {
+ if (argumentList != null) {
+ _constructorInvocation(node, element2, name3, argumentList);
+ } else {
+ _classGetter(node, element2, name3);
+ }
+ return;
+ }
+ // prefix.Extension.CONST
+ if (element2 is ExtensionElement) {
+ _extensionGetter(node, element2, name3);
+ return;
+ }
+ // prefix.CONST
+ if (element2 is PropertyAccessorElement) {
+ _propertyAccessorElement(node, name2, element2);
+ return;
+ }
+ // undefined
+ if (element2 == null) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_ANNOTATION,
node,
- [identifier.name],
+ [name2.name],
);
- }
- } else {
- var resolver = PropertyElementResolver(_resolver);
- var result = resolver.resolvePrefixedIdentifier(
- node: nodeName,
- hasRead: true,
- hasWrite: false,
- forAnnotation: true,
- );
-
- var element = result.readElement;
- identifier.staticElement = element;
- }
- } else {
- var identifier = nodeName as SimpleIdentifierImpl;
-
- var resolver = PropertyElementResolver(_resolver);
- var result = resolver.resolveSimpleIdentifier(
- node: identifier,
- hasRead: true,
- hasWrite: false,
- );
-
- var element = result.readElement;
- identifier.staticElement = element;
-
- if (element == null) {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.UNDEFINED_ANNOTATION,
- node,
- [identifier.name],
- );
- }
- }
-
- _resolveAnnotationElement(node);
- }
-
- void _resolveAnnotationConstructorInvocationArguments(
- AnnotationImpl annotation, ConstructorElement constructor) {
- var argumentList = annotation.arguments;
- // error will be reported in ConstantVerifier
- if (argumentList == null) {
- return;
- }
- // resolve arguments to parameters
- var parameters = _resolveArgumentsToFunction(argumentList, constructor);
- if (parameters != null) {
- argumentList.correspondingStaticParameters = parameters;
- }
- }
-
- /// Continues resolution of the given [annotation].
- void _resolveAnnotationElement(AnnotationImpl annotation) {
- late final SimpleIdentifier nameNode1;
- SimpleIdentifierImpl? nameNode2;
- {
- Identifier annName = annotation.name;
- if (annName is PrefixedIdentifierImpl) {
- nameNode1 = annName.prefix;
- nameNode2 = annName.identifier;
- } else {
- nameNode1 = annName as SimpleIdentifier;
- nameNode2 = null;
- }
- }
- SimpleIdentifierImpl? nameNode3 = annotation.constructorName;
- ConstructorElement? constructor;
- bool undefined = false;
- //
- // CONST or Class(args)
- //
- if (nameNode2 == null && nameNode3 == null) {
- var element1 = nameNode1.staticElement;
- // TODO(scheglov) Must be const.
- if (element1 is VariableElement) {
- return;
- }
- // CONST
- if (element1 is PropertyAccessorElement) {
- _resolveAnnotationElementGetter(annotation, element1);
- return;
- }
- // Class(args)
- if (element1 is ClassElement) {
- constructor = _instantiateAnnotationClass(element1)
- .lookUpConstructor(null, _definingLibrary);
- constructor = _resolver.toLegacyElement(constructor);
- } else if (element1 == null) {
- undefined = true;
- }
- }
- //
- // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args)
- //
- if (nameNode2 != null && nameNode3 == null) {
- var element1 = nameNode1.staticElement;
- var element2 = nameNode2.staticElement;
- // Class.CONST - not resolved yet
- if (element1 is ClassElement) {
- element2 = element1.lookUpGetter(nameNode2.name, _definingLibrary);
- element2 = _resolver.toLegacyElement(element2);
- }
- // prefix.CONST or Class.CONST
- if (element2 is PropertyAccessorElement) {
- nameNode2.staticElement = element2;
- annotation.element = element2;
- _resolveAnnotationElementGetter(annotation, element2);
- return;
- }
- // prefix.Class()
- if (element2 is ClassElement) {
- constructor = element2.unnamedConstructor;
- constructor = _resolver.toLegacyElement(constructor);
- }
- // Class.constructor(args)
- if (element1 is ClassElement) {
- constructor = _instantiateAnnotationClass(element1)
- .lookUpConstructor(nameNode2.name, _definingLibrary);
- constructor = _resolver.toLegacyElement(constructor);
- nameNode2.staticElement = constructor;
- }
- if (element1 is PrefixElement && element2 == null) {
- undefined = true;
- }
- if (element1 == null && element2 == null) {
- undefined = true;
- }
- }
- //
- // prefix.Class.CONST or prefix.Class.constructor(args)
- //
- if (nameNode2 != null && nameNode3 != null) {
- var element2 = nameNode2.staticElement;
- // element2 should be ClassElement
- if (element2 is ClassElement) {
- String name3 = nameNode3.name;
- // prefix.Class.CONST
- var getter = element2.lookUpGetter(name3, _definingLibrary);
- if (getter != null) {
- getter = _resolver.toLegacyElement(getter)!;
- nameNode3.staticElement = getter;
- annotation.element = getter;
- _resolveAnnotationElementGetter(annotation, getter);
+ node.arguments?.accept(_resolver);
return;
}
- // prefix.Class.constructor(args)
- constructor = _instantiateAnnotationClass(element2)
- .lookUpConstructor(name3, _definingLibrary);
- constructor = _resolver.toLegacyElement(constructor);
- nameNode3.staticElement = constructor;
- } else if (element2 == null) {
- undefined = true;
}
}
- // we need constructor
- if (constructor == null) {
- if (!undefined) {
- // If the class was not found then we've already reported the error.
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
- }
+
+ // CONST
+ if (element1 is PropertyAccessorElement) {
+ _propertyAccessorElement(node, name1, element1);
return;
}
- // record element
- annotation.element = constructor;
- // resolve arguments
- _resolveAnnotationConstructorInvocationArguments(annotation, constructor);
+
+ // TODO(scheglov) Must be const.
+ if (element1 is VariableElement) {
+ return;
+ }
+
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INVALID_ANNOTATION,
+ node,
+ );
+
+ node.arguments?.accept(_resolver);
}
void _resolveAnnotationElementGetter(
@@ -309,4 +363,20 @@
return ResolverVisitor.resolveArgumentsToParameters(
argumentList, parameters, _errorReporter.reportErrorForNode);
}
+
+ void _resolveConstructorInvocationArguments(AnnotationImpl node) {
+ var argumentList = node.arguments;
+ // error will be reported in ConstantVerifier
+ if (argumentList == null) {
+ return;
+ }
+ // resolve arguments to parameters
+ var constructor = node.element;
+ if (constructor is ConstructorElement) {
+ var parameters = _resolveArgumentsToFunction(argumentList, constructor);
+ if (parameters != null) {
+ argumentList.correspondingStaticParameters = parameters;
+ }
+ }
+ }
}
diff --git a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
index 8239ccd..461b264 100644
--- a/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/invocation_inference_helper.dart
@@ -114,7 +114,7 @@
/// This takes into account both the context type, as well as information from
/// the argument types.
FunctionType? inferGenericInvoke(
- Expression node,
+ AstNode node,
DartType? fnType,
TypeArgumentList? typeArguments,
ArgumentList argumentList,
diff --git a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
index b189618..5c6b1ab 100644
--- a/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/type_property_resolver.dart
@@ -120,12 +120,12 @@
if (flow != null) {
if (receiver != null) {
messages = _resolver.computeWhyNotPromotedMessages(
- receiver, nameErrorEntity, flow.whyNotPromoted(receiver));
+ receiver, nameErrorEntity, flow.whyNotPromoted(receiver)());
} else {
var thisType = _resolver.thisType;
if (thisType != null) {
messages = _resolver.computeWhyNotPromotedMessages(receiver,
- nameErrorEntity, flow.whyNotPromotedImplicitThis(thisType));
+ nameErrorEntity, flow.whyNotPromotedImplicitThis(thisType)());
}
}
}
diff --git a/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart b/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart
index 87f07b8..cc053b6 100644
--- a/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart
+++ b/pkg/analyzer/lib/src/error/nullable_dereference_verifier.dart
@@ -68,7 +68,7 @@
List<DiagnosticMessage>? messages;
if (errorNode is Expression) {
messages = _resolver.computeWhyNotPromotedMessages(errorNode, errorNode,
- _resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode));
+ _resolver.flowAnalysis?.flow?.whyNotPromoted(errorNode)());
}
report(errorNode, receiverType, errorCode: errorCode, messages: messages);
return true;
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 14eda22..13bb784 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -383,7 +383,6 @@
}
// Append boolean flags.
- // ignore: deprecated_member_use_from_same_package
buffer.addBool(implicitCasts);
buffer.addBool(implicitDynamic);
buffer.addBool(strictInference);
diff --git a/pkg/analyzer/lib/src/generated/error_detection_helpers.dart b/pkg/analyzer/lib/src/generated/error_detection_helpers.dart
new file mode 100644
index 0000000..92b0652
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/error_detection_helpers.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/extensions.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:analyzer/src/error/codes.dart';
+
+/// Methods useful in detecting errors. This mixin exists to allow code to be
+/// more easily shared between the two visitors that do the majority of error
+/// reporting (ResolverVisitor and ErrorVerifier).
+mixin ErrorDetectionHelpers {
+ ErrorReporter get errorReporter;
+
+ TypeSystemImpl get typeSystem;
+
+ /// Verify that the given [expression] can be assigned to its corresponding
+ /// parameters. The [expectedStaticType] is the expected static type of the
+ /// parameter. The [actualStaticType] is the actual static type of the
+ /// argument.
+ void checkForArgumentTypeNotAssignable(
+ Expression expression,
+ DartType? expectedStaticType,
+ DartType actualStaticType,
+ ErrorCode errorCode) {
+ // Warning case: test static type information
+ if (expectedStaticType != null) {
+ if (!expectedStaticType.isVoid && checkForUseOfVoidResult(expression)) {
+ return;
+ }
+
+ checkForAssignableExpressionAtType(
+ expression, actualStaticType, expectedStaticType, errorCode);
+ }
+ }
+
+ /// Verify that the given [argument] can be assigned to its corresponding
+ /// parameter.
+ ///
+ /// This method corresponds to
+ /// [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument].
+ ///
+ /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
+ void checkForArgumentTypeNotAssignableForArgument(Expression argument,
+ {bool promoteParameterToNullable = false}) {
+ checkForArgumentTypeNotAssignableForArgument2(
+ argument: argument,
+ parameter: argument.staticParameterElement,
+ promoteParameterToNullable: promoteParameterToNullable,
+ );
+ }
+
+ void checkForArgumentTypeNotAssignableForArgument2({
+ required Expression argument,
+ required ParameterElement? parameter,
+ required bool promoteParameterToNullable,
+ }) {
+ var staticParameterType = parameter?.type;
+ if (promoteParameterToNullable && staticParameterType != null) {
+ staticParameterType =
+ typeSystem.makeNullable(staticParameterType as TypeImpl);
+ }
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
+ staticParameterType, CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
+ }
+
+ bool checkForAssignableExpressionAtType(
+ Expression expression,
+ DartType actualStaticType,
+ DartType expectedStaticType,
+ ErrorCode errorCode) {
+ if (!typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) {
+ AstNode getErrorNode(AstNode node) {
+ if (node is CascadeExpression) {
+ return getErrorNode(node.target);
+ }
+ if (node is ParenthesizedExpression) {
+ return getErrorNode(node.expression);
+ }
+ return node;
+ }
+
+ errorReporter.reportErrorForNode(
+ errorCode,
+ getErrorNode(expression),
+ [actualStaticType, expectedStaticType],
+ );
+ return false;
+ }
+ return true;
+ }
+
+ /// Check for situations where the result of a method or function is used,
+ /// when it returns 'void'. Or, in rare cases, when other types of expressions
+ /// are void, such as identifiers.
+ ///
+ /// See [StaticWarningCode.USE_OF_VOID_RESULT].
+ bool checkForUseOfVoidResult(Expression expression) {
+ if (!identical(expression.staticType, VoidTypeImpl.instance)) {
+ return false;
+ }
+
+ if (expression is MethodInvocation) {
+ SimpleIdentifier methodName = expression.methodName;
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.USE_OF_VOID_RESULT, methodName, []);
+ } else {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.USE_OF_VOID_RESULT, expression, []);
+ }
+
+ return true;
+ }
+
+ /// Verify that the given [expression] can be assigned to its corresponding
+ /// parameters.
+ ///
+ /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
+ /// [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
+ /// [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
+ /// [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
+ /// [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
+ /// [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
+ /// [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
+ void _checkForArgumentTypeNotAssignableWithExpectedTypes(
+ Expression expression,
+ DartType? expectedStaticType,
+ ErrorCode errorCode) {
+ checkForArgumentTypeNotAssignable(
+ expression, expectedStaticType, expression.typeOrThrow, errorCode);
+ }
+}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 11f7424..4dd8078 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -38,6 +38,7 @@
import 'package:analyzer/src/error/type_arguments_verifier.dart';
import 'package:analyzer/src/generated/element_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error_detection_helpers.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/this_access_tracker.dart';
@@ -142,9 +143,11 @@
/// A visitor used to traverse an AST structure looking for additional errors
/// and warnings not covered by the parser and resolver.
-class ErrorVerifier extends RecursiveAstVisitor<void> {
+class ErrorVerifier extends RecursiveAstVisitor<void>
+ with ErrorDetectionHelpers {
/// The error reporter by which errors will be reported.
- final ErrorReporter _errorReporter;
+ @override
+ final ErrorReporter errorReporter;
/// The current library that is being analyzed.
final LibraryElementImpl _currentLibrary;
@@ -159,7 +162,8 @@
final TypeProvider _typeProvider;
/// The type system primitives
- late final TypeSystemImpl _typeSystem;
+ @override
+ late final TypeSystemImpl typeSystem;
/// The manager for the inheritance mappings.
final InheritanceManager3 _inheritanceManager;
@@ -248,10 +252,9 @@
late final ReturnTypeVerifier _returnTypeVerifier;
/// Initialize a newly created error verifier.
- ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
- this._typeProvider, this._inheritanceManager)
- : _errorReporter = errorReporter,
- _uninstantiatedBoundChecker =
+ ErrorVerifier(this.errorReporter, this._currentLibrary, this._typeProvider,
+ this._inheritanceManager)
+ : _uninstantiatedBoundChecker =
_UninstantiatedBoundChecker(errorReporter),
_requiredParametersVerifier = RequiredParametersVerifier(errorReporter),
_duplicateDefinitionVerifier =
@@ -262,18 +265,18 @@
_isInStaticVariableDeclaration = false;
_isInConstructorInitializer = false;
_intType = _typeProvider.intType;
- _typeSystem = _currentLibrary.typeSystem;
+ typeSystem = _currentLibrary.typeSystem;
_options = _currentLibrary.context.analysisOptions as AnalysisOptionsImpl;
_typeArgumentsVerifier =
- TypeArgumentsVerifier(_options, _currentLibrary, _errorReporter);
+ TypeArgumentsVerifier(_options, _currentLibrary, errorReporter);
_constructorFieldsVerifier = ConstructorFieldsVerifier(
- typeSystem: _typeSystem,
- errorReporter: _errorReporter,
+ typeSystem: typeSystem,
+ errorReporter: errorReporter,
);
_returnTypeVerifier = ReturnTypeVerifier(
typeProvider: _typeProvider as TypeProviderImpl,
- typeSystem: _typeSystem,
- errorReporter: _errorReporter,
+ typeSystem: typeSystem,
+ errorReporter: errorReporter,
);
}
@@ -313,14 +316,6 @@
}
@override
- void visitArgumentList(ArgumentList node) {
- if (node.parent is! ExtensionOverride) {
- _checkForArgumentTypesNotAssignableInList(node);
- }
- super.visitArgumentList(node);
- }
-
- @override
void visitAsExpression(AsExpression node) {
_checkForTypeAnnotationDeferredClass(node.type);
super.visitAsExpression(node);
@@ -348,7 +343,7 @@
_checkForInvalidAssignment(lhs, rhs);
}
} else {
- _checkForArgumentTypeNotAssignableForArgument(rhs);
+ checkForArgumentTypeNotAssignableForArgument(rhs);
}
if (operatorType == TokenType.QUESTION_QUESTION_EQ) {
_checkForDeadNullCoalesce(node.readType as TypeImpl, node.rightHandSide);
@@ -367,11 +362,11 @@
@override
void visitAwaitExpression(AwaitExpression node) {
if (!_enclosingExecutable.isAsynchronous) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
}
if (_isNonNullableByDefault) {
- _checkForUseOfVoidResult(node.expression);
+ checkForUseOfVoidResult(node.expression);
}
_checkForAwaitInLateLocalVariableInitializer(node);
super.visitAwaitExpression(node);
@@ -382,14 +377,14 @@
Token operator = node.operator;
TokenType type = operator.type;
if (type == TokenType.AMPERSAND_AMPERSAND || type == TokenType.BAR_BAR) {
- _checkForUseOfVoidResult(node.rightOperand);
+ checkForUseOfVoidResult(node.rightOperand);
} else if (type == TokenType.EQ_EQ || type == TokenType.BANG_EQ) {
- _checkForArgumentTypeNotAssignableForArgument(node.rightOperand,
+ checkForArgumentTypeNotAssignableForArgument(node.rightOperand,
promoteParameterToNullable: true);
} else if (type != TokenType.QUESTION_QUESTION) {
- _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
+ checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
} else {
- _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
+ checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
}
if (type == TokenType.QUESTION_QUESTION) {
@@ -397,7 +392,7 @@
node.leftOperand.staticType as TypeImpl, node.rightOperand);
}
- _checkForUseOfVoidResult(node.leftOperand);
+ checkForUseOfVoidResult(node.leftOperand);
super.visitBinaryExpression(node);
}
@@ -426,7 +421,7 @@
if (labelNode != null) {
var labelElement = labelNode.staticElement;
if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode);
}
}
@@ -564,7 +559,7 @@
var labelElement = labelNode.staticElement;
if (labelElement is LabelElementImpl &&
labelElement.isOnSwitchStatement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode);
}
}
@@ -619,8 +614,8 @@
_checkForFinalNotInitializedInClass(node.members);
GetterSetterTypesVerifier(
- typeSystem: _typeSystem,
- errorReporter: _errorReporter,
+ typeSystem: typeSystem,
+ errorReporter: errorReporter,
).checkExtension(node);
final name = node.name;
@@ -641,7 +636,7 @@
!node.isStatic && !node.fields.isLate;
if (!_isInStaticVariableDeclaration) {
if (fields.isConst) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.CONST_INSTANCE_FIELD, fields.keyword!);
}
}
@@ -679,7 +674,7 @@
DeclaredIdentifier loopVariable = node.loopVariable;
if (_checkForEachParts(node, loopVariable.identifier)) {
if (loopVariable.isConst) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE,
loopVariable.keyword!);
}
@@ -722,8 +717,8 @@
TypeAnnotation? returnType = node.returnType;
if (node.isGetter) {
GetterSetterTypesVerifier(
- typeSystem: _typeSystem,
- errorReporter: _errorReporter,
+ typeSystem: typeSystem,
+ errorReporter: errorReporter,
).checkGetter(
node.name, node.declaredElement as PropertyAccessorElement);
}
@@ -796,10 +791,8 @@
DartType parameterType = node.declaredElement!.type;
if (parameterType is FunctionType &&
parameterType.returnType.isDynamic) {
- _errorReporter.reportErrorForNode(
- LanguageCode.IMPLICIT_DYNAMIC_RETURN,
- node.identifier,
- [node.identifier]);
+ errorReporter.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_RETURN,
+ node.identifier, [node.identifier]);
}
}
@@ -890,14 +883,14 @@
@override
void visitInterpolationExpression(InterpolationExpression node) {
- _checkForUseOfVoidResult(node.expression);
+ checkForUseOfVoidResult(node.expression);
super.visitInterpolationExpression(node);
}
@override
void visitIsExpression(IsExpression node) {
_checkForTypeAnnotationDeferredClass(node.type);
- _checkForUseOfVoidResult(node.expression);
+ checkForUseOfVoidResult(node.expression);
super.visitIsExpression(node);
}
@@ -915,8 +908,8 @@
var returnType = node.returnType;
if (node.isStatic && node.isGetter) {
GetterSetterTypesVerifier(
- typeSystem: _typeSystem,
- errorReporter: _errorReporter,
+ typeSystem: typeSystem,
+ errorReporter: errorReporter,
).checkGetter(
node.name, node.declaredElement as PropertyAccessorElement);
}
@@ -997,7 +990,7 @@
// TODO(brianwilkerson) Figure out the right rule for when 'native' is
// allowed.
if (!_isInSystemLibrary) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node);
}
super.visitNativeClause(node);
@@ -1013,7 +1006,7 @@
void visitPostfixExpression(PostfixExpression node) {
var operand = node.operand;
if (node.operator.type == TokenType.BANG) {
- _checkForUseOfVoidResult(node);
+ checkForUseOfVoidResult(node);
_checkForUnnecessaryNullAware(operand, node.operator);
} else {
_checkForAssignmentToFinal(operand);
@@ -1048,7 +1041,7 @@
if (operatorType.isIncrementOperator) {
_checkForAssignmentToFinal(operand);
}
- _checkForUseOfVoidResult(operand);
+ checkForUseOfVoidResult(operand);
_checkForIntNotAssignable(operand);
}
if (operand is IndexExpression) {
@@ -1196,7 +1189,7 @@
@override
void visitThrowExpression(ThrowExpression node) {
_checkForConstEvalThrowsException(node);
- _checkForUseOfVoidResult(node.expression);
+ checkForUseOfVoidResult(node.expression);
_checkForThrowOfInvalidType(node);
super.visitThrowExpression(node);
}
@@ -1338,7 +1331,7 @@
for (int i = 0; i < count; i++) {
var deferredToken = directives[i].deferredKeyword;
if (deferredToken != null) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken);
}
}
@@ -1348,11 +1341,11 @@
void _checkForAbstractOrExternalFieldConstructorInitializer(
AstNode node, FieldElement fieldElement) {
if (fieldElement.isAbstract) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ABSTRACT_FIELD_CONSTRUCTOR_INITIALIZER, node);
}
if (fieldElement.isExternal) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTERNAL_FIELD_CONSTRUCTOR_INITIALIZER, node);
}
}
@@ -1363,16 +1356,16 @@
if (node.initializer != null) {
if (declaredElement is FieldElement) {
if (declaredElement.isAbstract) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ABSTRACT_FIELD_INITIALIZER, node.name);
}
if (declaredElement.isExternal) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTERNAL_FIELD_INITIALIZER, node.name);
}
} else if (declaredElement is TopLevelVariableElement) {
if (declaredElement.isExternal) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTERNAL_VARIABLE_INITIALIZER, node.name);
}
}
@@ -1450,7 +1443,7 @@
if (redirectedConstructor.name != null) {
constructorStrName += ".${redirectedConstructor.name!.name}";
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
redirectedConstructor,
[constructorStrName, redirectedType]);
@@ -1463,16 +1456,16 @@
// Report specific problem when return type is incompatible
FunctionType constructorType = declaration.declaredElement!.type;
DartType constructorReturnType = constructorType.returnType;
- if (!_typeSystem.isAssignableTo(
+ if (!typeSystem.isAssignableTo(
redirectedReturnType, constructorReturnType)) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.REDIRECT_TO_INVALID_RETURN_TYPE,
redirectedConstructor,
[redirectedReturnType, constructorReturnType]);
return;
- } else if (!_typeSystem.isSubtypeOf(redirectedType, constructorType)) {
+ } else if (!typeSystem.isSubtypeOf(redirectedType, constructorType)) {
// Check parameters.
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.REDIRECT_TO_INVALID_FUNCTION_TYPE,
redirectedConstructor,
[redirectedType, constructorType]);
@@ -1499,7 +1492,7 @@
var element = definedNames[name]!;
var prevElement = _exportedElements[name];
if (prevElement != null && prevElement != element) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.AMBIGUOUS_EXPORT, directive.uri, [
name,
prevElement.library!.definingCompilationUnit.source.uri,
@@ -1522,125 +1515,18 @@
var libraryNames =
conflictingMembers.map((e) => _getLibraryName(e)).toList();
libraryNames.sort();
- _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_IMPORT,
+ errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_IMPORT,
node, [name, StringUtilities.printListOfQuotedNames(libraryNames)]);
}
}
- /// Verify that the given [expression] can be assigned to its corresponding
- /// parameters. The [expectedStaticType] is the expected static type of the
- /// parameter. The [actualStaticType] is the actual static type of the
- /// argument.
- void _checkForArgumentTypeNotAssignable(
- Expression expression,
- DartType? expectedStaticType,
- DartType actualStaticType,
- ErrorCode errorCode) {
- // Warning case: test static type information
- if (expectedStaticType != null) {
- if (!expectedStaticType.isVoid && _checkForUseOfVoidResult(expression)) {
- return;
- }
-
- _checkForAssignableExpressionAtType(
- expression, actualStaticType, expectedStaticType, errorCode);
- }
- }
-
- /// Verify that the given [argument] can be assigned to its corresponding
- /// parameter.
- ///
- /// This method corresponds to
- /// [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument].
- ///
- /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
- void _checkForArgumentTypeNotAssignableForArgument(Expression argument,
- {bool promoteParameterToNullable = false}) {
- _checkForArgumentTypeNotAssignableForArgument2(
- argument: argument,
- parameter: argument.staticParameterElement,
- promoteParameterToNullable: promoteParameterToNullable,
- );
- }
-
- void _checkForArgumentTypeNotAssignableForArgument2({
- required Expression argument,
- required ParameterElement? parameter,
- required bool promoteParameterToNullable,
- }) {
- var staticParameterType = parameter?.type;
- if (promoteParameterToNullable && staticParameterType != null) {
- staticParameterType =
- _typeSystem.makeNullable(staticParameterType as TypeImpl);
- }
- _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
- staticParameterType, CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
- }
-
- /// Verify that the given [expression] can be assigned to its corresponding
- /// parameters.
- ///
- /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
- /// [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
- /// [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
- /// [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
- /// [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
- /// [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
- /// [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
- void _checkForArgumentTypeNotAssignableWithExpectedTypes(
- Expression expression,
- DartType? expectedStaticType,
- ErrorCode errorCode) {
- _checkForArgumentTypeNotAssignable(
- expression, expectedStaticType, expression.typeOrThrow, errorCode);
- }
-
- /// Verify that the arguments in the given [argumentList] can be assigned to
- /// their corresponding parameters.
- ///
- /// This method corresponds to
- /// [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList].
- ///
- /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
- void _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) {
- for (Expression argument in argumentList.arguments) {
- _checkForArgumentTypeNotAssignableForArgument(argument);
- }
- }
-
bool _checkForAssignableExpression(
Expression expression, DartType expectedStaticType, ErrorCode errorCode) {
DartType actualStaticType = expression.typeOrThrow;
- return _checkForAssignableExpressionAtType(
+ return checkForAssignableExpressionAtType(
expression, actualStaticType, expectedStaticType, errorCode);
}
- bool _checkForAssignableExpressionAtType(
- Expression expression,
- DartType actualStaticType,
- DartType expectedStaticType,
- ErrorCode errorCode) {
- if (!_typeSystem.isAssignableTo(actualStaticType, expectedStaticType)) {
- AstNode getErrorNode(AstNode node) {
- if (node is CascadeExpression) {
- return getErrorNode(node.target);
- }
- if (node is ParenthesizedExpression) {
- return getErrorNode(node.expression);
- }
- return node;
- }
-
- _errorReporter.reportErrorForNode(
- errorCode,
- getErrorNode(expression),
- [actualStaticType, expectedStaticType],
- );
- return false;
- }
- return true;
- }
-
/// Verify that the given [expression] is not final.
///
/// See [StaticWarningCode.ASSIGNMENT_TO_CONST],
@@ -1673,7 +1559,7 @@
// check if element is assignable
if (element is VariableElement) {
if (element.isConst) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
expression,
);
@@ -1681,7 +1567,7 @@
if (_isNonNullableByDefault) {
// Handled during resolution, with flow analysis.
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_LOCAL,
expression,
[element.name],
@@ -1691,40 +1577,40 @@
} else if (element is PropertyAccessorElement && element.isGetter) {
var variable = element.variable;
if (variable.isConst) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_CONST,
expression,
);
} else if (variable is FieldElement && variable.isSynthetic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL_NO_SETTER,
highlightedNode,
[variable.name, variable.enclosingElement.displayName],
);
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_FINAL,
highlightedNode,
[variable.name],
);
}
} else if (element is FunctionElement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_FUNCTION, expression);
} else if (element is MethodElement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_METHOD, expression);
} else if (element is ClassElement ||
element is DynamicElementImpl ||
element is TypeParameterElement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, expression);
}
}
void _checkForAwaitInLateLocalVariableInitializer(AwaitExpression node) {
if (_isInLateLocalVariable.last) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.AWAIT_IN_LATE_LOCAL_VARIABLE_INITIALIZER,
node.awaitKeyword,
);
@@ -1738,14 +1624,14 @@
var withClause = node.withClause;
if (node.name.name == "Function") {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
HintCode.DEPRECATED_FUNCTION_CLASS_DECLARATION, node.name);
}
if (extendsClause != null) {
var superElement = extendsClause.superclass.name.staticElement;
if (superElement != null && superElement.name == "Function") {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
HintCode.DEPRECATED_EXTENDS_FUNCTION, extendsClause.superclass);
}
}
@@ -1754,7 +1640,7 @@
for (TypeName type in withClause.mixinTypes) {
var mixinElement = type.name.staticElement;
if (mixinElement != null && mixinElement.name == "Function") {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
HintCode.DEPRECATED_MIXIN_FUNCTION, type);
}
}
@@ -1772,7 +1658,7 @@
SimpleIdentifier identifier, ErrorCode errorCode) {
Token token = identifier.token;
if (token.type.isKeyword && token.keyword?.isPseudo != true) {
- _errorReporter
+ errorReporter
.reportErrorForNode(errorCode, identifier, [identifier.name]);
}
}
@@ -1815,7 +1701,7 @@
}
}
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.CASE_BLOCK_NOT_TERMINATED, switchCase.keyword);
}
@@ -1859,14 +1745,14 @@
_enclosingClass!, Name(libraryUri, '$name='));
if (method.isStatic && inherited != null) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, method, [
_enclosingClass!.displayName,
name,
inherited.enclosingElement.displayName,
]);
} else if (inherited is PropertyAccessorElement) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD, method, [
_enclosingClass!.displayName,
name,
@@ -1886,14 +1772,14 @@
_enclosingClass!, Name(libraryUri, '$name='));
if (accessor.isStatic && inherited != null) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, accessor, [
_enclosingClass!.displayName,
name,
inherited.enclosingElement.displayName,
]);
} else if (inherited is MethodElement) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD, accessor, [
_enclosingClass!.displayName,
name,
@@ -1914,7 +1800,7 @@
String name = typeParameter.name;
// name is same as the name of the enclosing class
if (_enclosingClass!.name == name) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS,
typeParameter,
[name]);
@@ -1923,7 +1809,7 @@
if (_enclosingClass!.getMethod(name) != null ||
_enclosingClass!.getGetter(name) != null ||
_enclosingClass!.getSetter(name) != null) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS,
typeParameter,
[name]);
@@ -1941,7 +1827,7 @@
String name = typeParameter.name;
// name is same as the name of the enclosing class
if (_enclosingExtension!.name == name) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION,
typeParameter,
[name]);
@@ -1950,7 +1836,7 @@
if (_enclosingExtension!.getMethod(name) != null ||
_enclosingExtension!.getGetter(name) != null ||
_enclosingExtension!.getSetter(name) != null) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
typeParameter,
[name]);
@@ -1966,7 +1852,7 @@
for (var error in errors) {
if (error is IncompatibleInterfacesClassHierarchyError) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
node,
[
@@ -2005,7 +1891,7 @@
}
if (instanceFields.length == 1) {
var field = instanceFields.single;
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
constructor.returnType,
["'${field.enclosingElement.name}.${field.name}'"]);
@@ -2014,7 +1900,7 @@
var fieldNames = instanceFields
.map((field) => "'${field.enclosingElement.name}.${field.name}'")
.join(', ');
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS,
constructor.returnType,
[fieldNames]);
@@ -2028,7 +1914,7 @@
if (element == null || element.isConst) {
return;
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
initializer,
[element.enclosingElement.displayName]);
@@ -2049,7 +1935,7 @@
}
// default constructor is not 'const', report problem
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
constructor.returnType,
[supertype]);
@@ -2073,7 +1959,7 @@
// CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD when either
// CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER or
// CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD is also generated.
- _errorReporter.reportErrorForName(
+ errorReporter.reportErrorForName(
CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
constructor);
}
@@ -2087,7 +1973,7 @@
void _checkForConstDeferredClass(InstanceCreationExpression expression,
ConstructorName constructorName, TypeName typeName) {
if (typeName.isDeferred) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_DEFERRED_CLASS,
constructorName,
[typeName.name.name]);
@@ -2100,7 +1986,7 @@
/// See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION].
void _checkForConstEvalThrowsException(ThrowExpression expression) {
if (_enclosingExecutable.isConstConstructor) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression);
}
}
@@ -2120,10 +2006,10 @@
bool isImplicit =
(expression as InstanceCreationExpressionImpl).isImplicit;
if (!isImplicit) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS, typeName);
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANTIATE_ABSTRACT_CLASS, typeName);
}
}
@@ -2140,7 +2026,7 @@
void _checkForConstOrNewWithEnum(InstanceCreationExpression expression,
TypeName typeName, InterfaceType type) {
if (type.element.isEnum) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANTIATE_ENUM, typeName);
}
}
@@ -2149,7 +2035,7 @@
void _checkForConstOrNewWithMixin(InstanceCreationExpression expression,
TypeName typeName, InterfaceType type) {
if (type.element.isMixin) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MIXIN_INSTANTIATE, typeName);
}
}
@@ -2165,10 +2051,10 @@
var constructorElement = expression.constructorName.staticElement;
if (constructorElement != null && !constructorElement.isConst) {
if (expression.keyword != null) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.CONST_WITH_NON_CONST, expression.keyword!);
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_WITH_NON_CONST, expression);
}
}
@@ -2204,12 +2090,12 @@
// report as named or default constructor absence
var name = constructorName.name;
if (name != null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR,
name,
[className, name]);
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
constructorName,
[className]);
@@ -2219,8 +2105,8 @@
void _checkForDeadNullCoalesce(TypeImpl lhsType, Expression rhs) {
if (!_isNonNullableByDefault) return;
- if (_typeSystem.isStrictlyNonNullable(lhsType)) {
- _errorReporter.reportErrorForNode(
+ if (typeSystem.isStrictlyNonNullable(lhsType)) {
+ errorReporter.reportErrorForNode(
StaticWarningCode.DEAD_NULL_AWARE_EXPRESSION,
rhs,
);
@@ -2233,7 +2119,7 @@
ImportDirective directive, ImportElement importElement) {
for (var element in importElement.namespace.definedNames.values) {
if (element is ExtensionElement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.DEFERRED_IMPORT_OF_EXTENSION,
directive.uri,
);
@@ -2278,7 +2164,7 @@
/// Return `true` if the caller should continue checking the rest of the
/// information in the for-each part.
bool _checkForEachParts(ForEachParts node, SimpleIdentifier variable) {
- if (_checkForUseOfVoidResult(node.iterable)) {
+ if (checkForUseOfVoidResult(node.iterable)) {
return false;
}
@@ -2286,7 +2172,7 @@
// TODO(scheglov) use NullableDereferenceVerifier
if (_isNonNullableByDefault) {
- if (_typeSystem.isNullable(iterableType)) {
+ if (typeSystem.isNullable(iterableType)) {
return false;
}
}
@@ -2320,12 +2206,12 @@
? _typeProvider.streamDynamicType
: _typeProvider.iterableDynamicType;
- if (_typeSystem.isTop(iterableType)) {
+ if (typeSystem.isTop(iterableType)) {
iterableType = requiredSequenceType;
}
- if (!_typeSystem.isAssignableTo(iterableType, requiredSequenceType)) {
- _errorReporter.reportErrorForNode(
+ if (!typeSystem.isAssignableTo(iterableType, requiredSequenceType)) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FOR_IN_OF_INVALID_TYPE,
node.iterable,
[iterableType, loopTypeName],
@@ -2348,8 +2234,8 @@
return true;
}
- if (!_typeSystem.isAssignableTo(sequenceElementType, variableType)) {
- _errorReporter.reportErrorForNode(
+ if (!typeSystem.isAssignableTo(sequenceElementType, variableType)) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
node.iterable,
[iterableType, loopTypeName, variableType],
@@ -2387,7 +2273,7 @@
return;
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY,
directive,
[directive.uri]);
@@ -2410,7 +2296,7 @@
continue;
}
if (!element.library!.isNonNullableByDefault) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXPORT_LEGACY_SYMBOL,
node.uri,
[element.displayName],
@@ -2461,7 +2347,7 @@
return false;
}
if (typeName.isDeferred) {
- _errorReporter.reportErrorForNode(errorCode, typeName);
+ errorReporter.reportErrorForNode(errorCode, typeName);
return true;
}
return false;
@@ -2498,7 +2384,7 @@
name == 'toString' ||
name == 'runtimeType' ||
name == 'noSuchMethod') {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXTENSION_DECLARES_MEMBER_OF_OBJECT,
node.name,
);
@@ -2519,9 +2405,9 @@
Expression expression = initializer.expression;
// test the static type of the expression
DartType staticType = expression.typeOrThrow;
- if (_typeSystem.isAssignableTo(staticType, fieldType)) {
+ if (typeSystem.isAssignableTo(staticType, fieldType)) {
if (!fieldType.isVoid) {
- _checkForUseOfVoidResult(expression);
+ checkForUseOfVoidResult(expression);
}
return;
}
@@ -2529,12 +2415,12 @@
if (_enclosingExecutable.isConstConstructor) {
// TODO(paulberry): this error should be based on the actual type of the
// constant, not the static type. See dartbug.com/21119.
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
expression,
[staticType, fieldType]);
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
expression,
[staticType, fieldType]);
@@ -2578,7 +2464,7 @@
if (constructor is ConstructorDeclaration) {
// constructor cannot be a factory
if (constructor.factoryKeyword != null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
parameter);
return;
@@ -2586,14 +2472,14 @@
// constructor cannot have a redirection
for (ConstructorInitializer initializer in constructor.initializers) {
if (initializer is RedirectingConstructorInvocation) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
parameter);
return;
}
}
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
parameter);
}
@@ -2624,7 +2510,7 @@
for (VariableDeclaration variable in variables) {
if (variable.initializer == null) {
if (isConst) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
variable.name,
[variable.name.name]);
@@ -2637,7 +2523,7 @@
variableElement.isExternal) {
// External top level variables can't be initialized, so no error.
} else if (!_isNonNullableByDefault || !variable.isLate) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FINAL_NOT_INITIALIZED,
variable.name,
[variable.name.name]);
@@ -2683,7 +2569,7 @@
}
DartType type = node.typeOrThrow;
if (type is FunctionType && type.typeFormals.isNotEmpty) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND,
node,
[type]);
@@ -2728,7 +2614,7 @@
} else {
errorCode = LanguageCode.IMPLICIT_DYNAMIC_VARIABLE;
}
- _errorReporter.reportErrorForNode(errorCode, node, [id]);
+ errorReporter.reportErrorForNode(errorCode, node, [id]);
}
}
@@ -2741,7 +2627,7 @@
return;
}
if (element.hasImplicitReturnType && element.returnType.isDynamic) {
- _errorReporter.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_RETURN,
+ errorReporter.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_RETURN,
functionName, [element.displayName]);
}
}
@@ -2756,7 +2642,7 @@
if (type is ParameterizedType &&
type.typeArguments.isNotEmpty &&
type.typeArguments.any((t) => t.isDynamic)) {
- _errorReporter
+ errorReporter
.reportErrorForNode(LanguageCode.IMPLICIT_DYNAMIC_TYPE, node, [type]);
}
}
@@ -2786,7 +2672,7 @@
return;
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY,
directive.uri,
[directive.uri.stringValue]);
@@ -2831,7 +2717,7 @@
return;
}
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
name,
[name.name, _getKind(element), element.enclosingElement.name]);
@@ -2846,7 +2732,7 @@
void _checkForIntNotAssignable(Expression argument) {
var staticParameterElement = argument.staticParameterElement;
var staticParameterType = staticParameterElement?.type;
- _checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType,
+ checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType,
CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
}
@@ -2856,7 +2742,7 @@
void _checkForInvalidAnnotationFromDeferredLibrary(Annotation annotation) {
Identifier nameIdentifier = annotation.name;
if (nameIdentifier is PrefixedIdentifier && nameIdentifier.isDeferred) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
annotation.name);
}
@@ -2891,7 +2777,7 @@
: leftVariableElement.type;
}
- if (!leftType.isVoid && _checkForUseOfVoidResult(rhs)) {
+ if (!leftType.isVoid && checkForUseOfVoidResult(rhs)) {
return;
}
@@ -2907,18 +2793,18 @@
SimpleIdentifier fieldName, Element? staticElement) {
if (staticElement is FieldElement) {
if (staticElement.isSynthetic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
initializer,
[fieldName]);
} else if (staticElement.isStatic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD,
initializer,
[fieldName]);
}
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
initializer,
[fieldName]);
@@ -2980,13 +2866,13 @@
}
if (_enclosingExecutable.inStaticMethod) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
} else if (_enclosingExecutable.inFactoryConstructor) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
identifier,
[identifier.name]);
@@ -2999,7 +2885,7 @@
FunctionBody body, CompileTimeErrorCode errorCode) {
var keyword = body.keyword;
if (keyword != null) {
- _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]);
+ errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]);
}
}
@@ -3008,7 +2894,7 @@
/// See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS].
void _checkForInvalidReferenceToThis(ThisExpression expression) {
if (!_thisAccessTracker.hasAccess) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, expression);
}
}
@@ -3026,7 +2912,7 @@
_enclosingClass!.constructors.any((c) => c.isConst);
if (!hasConstConstructor) return;
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.LATE_FINAL_FIELD_WITH_CONST_CONSTRUCTOR,
lateKeyword,
);
@@ -3037,7 +2923,7 @@
if (!_isNonNullableByDefault) return;
if (node.constructorName.name == null && type.isDartCoreList) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR,
node.constructorName,
);
@@ -3065,9 +2951,9 @@
// Check every list element.
var verifier = LiteralElementVerifier(
_typeProvider,
- _typeSystem,
- _errorReporter,
- _checkForUseOfVoidResult,
+ typeSystem,
+ errorReporter,
+ checkForUseOfVoidResult,
forList: true,
elementType: listElementType,
featureSet: _featureSet!,
@@ -3094,7 +2980,7 @@
}
if (element is! FunctionElement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MAIN_IS_NOT_FUNCTION,
nameNode,
);
@@ -3109,14 +2995,14 @@
parameters.where((e) => e.isRequiredPositional).toList();
if (requiredPositional.length > 2) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MAIN_HAS_TOO_MANY_REQUIRED_POSITIONAL_PARAMETERS,
nameNode,
);
}
if (parameters.any((e) => e.isRequiredNamed)) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MAIN_HAS_REQUIRED_NAMED_PARAMETERS,
nameNode,
);
@@ -3126,8 +3012,8 @@
var first = positional.first;
var type = first.declaredElement!.type;
var listOfString = _typeProvider.listType(_typeProvider.stringType);
- if (!_typeSystem.isSubtypeOf(listOfString, type)) {
- _errorReporter.reportErrorForNode(
+ if (!typeSystem.isSubtypeOf(listOfString, type)) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MAIN_FIRST_POSITIONAL_PARAMETER_TYPE,
first.notDefault.typeOrSelf,
);
@@ -3153,9 +3039,9 @@
var verifier = LiteralElementVerifier(
_typeProvider,
- _typeSystem,
- _errorReporter,
- _checkForUseOfVoidResult,
+ typeSystem,
+ errorReporter,
+ checkForUseOfVoidResult,
forMap: true,
mapKeyType: keyType,
mapValueType: valueType,
@@ -3202,7 +3088,7 @@
for (var constantName in constantNames) {
int offset = statement.offset;
int end = statement.rightParenthesis.end;
- _errorReporter.reportErrorForOffset(
+ errorReporter.reportErrorForOffset(
StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
offset,
end - offset,
@@ -3210,10 +3096,10 @@
);
}
- if (_typeSystem.isNullable(expressionType) && !hasCaseNull) {
+ if (typeSystem.isNullable(expressionType) && !hasCaseNull) {
int offset = statement.offset;
int end = statement.rightParenthesis.end;
- _errorReporter.reportErrorForOffset(
+ errorReporter.reportErrorForOffset(
StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
offset,
end - offset,
@@ -3227,7 +3113,7 @@
void _checkForMissingJSLibAnnotation(Annotation node) {
if (node.elementAnnotation?.isJS ?? false) {
if (_currentLibrary.hasJS != true) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
HintCode.MISSING_JS_LIB_ANNOTATION, node);
}
}
@@ -3242,7 +3128,7 @@
TypeName mixinName, ClassElement mixinElement) {
for (ConstructorElement constructor in mixinElement.constructors) {
if (!constructor.isSynthetic && !constructor.isFactory) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR,
mixinName,
[mixinElement.name]);
@@ -3269,7 +3155,7 @@
}
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT,
mixinName,
[mixinElement.name],
@@ -3288,15 +3174,15 @@
superType = superType.withNullability(NullabilitySuffix.none);
}
- bool isSatisfied = _typeSystem.isSubtypeOf(superType, constraint);
+ bool isSatisfied = typeSystem.isSubtypeOf(superType, constraint);
if (!isSatisfied) {
for (int i = 0; i < mixinIndex && !isSatisfied; i++) {
isSatisfied =
- _typeSystem.isSubtypeOf(_enclosingClass!.mixins[i], constraint);
+ typeSystem.isSubtypeOf(_enclosingClass!.mixins[i], constraint);
}
}
if (!isSatisfied) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
mixinName.name,
[
@@ -3330,7 +3216,7 @@
forMixinIndex: mixinIndex, concrete: true, forSuper: true);
if (superMember == null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode
.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
mixinName.name,
@@ -3349,7 +3235,7 @@
superMember: mixinMember,
);
if (!isCorrect) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode
.MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
mixinName.name,
@@ -3386,7 +3272,7 @@
Map<String, String> names =
mixedInNames.putIfAbsent(library, () => <String, String>{});
if (names.containsKey(name)) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION,
typeName,
[name, typeName.name.name, names[name]]);
@@ -3399,7 +3285,7 @@
concrete: true,
);
if (inheritedMember != null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION,
typeName, [
name,
@@ -3446,7 +3332,7 @@
for (ConstructorInitializer initializer in constructor.initializers) {
if (initializer is SuperConstructorInvocation) {
if (hasSuperInitializer) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer);
}
hasSuperInitializer = true;
@@ -3459,7 +3345,7 @@
/// See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
void _checkForNativeFunctionBodyInNonSdkCode(NativeFunctionBody body) {
if (!_isInSystemLibrary && !_hasExtUri) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body);
}
}
@@ -3493,12 +3379,12 @@
// report as named or default constructor absence
var name = constructorName.name;
if (name != null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR,
name,
[className, name]);
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT,
constructorName,
[className]);
@@ -3530,7 +3416,7 @@
: superUnnamedConstructor;
if (superUnnamedConstructor != null) {
if (superUnnamedConstructor.isFactory) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR,
declaration.name, [
superElement.name,
@@ -3547,7 +3433,7 @@
if (!_typeProvider.nonSubtypableClasses.contains(superType.element)) {
// Don't report this diagnostic for non-subtypable classes because the
// real problem was already reported.
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
declaration.name,
[superType, _enclosingClass!.displayName]);
@@ -3574,7 +3460,7 @@
.every((constructor) => constructor.isFactory)) {
// For `E extends Exception`, etc., this will never work, because it has
// no generative constructors. State this clearly to users.
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS,
superclass!,
[_enclosingClass!.name, superElement.name]);
@@ -3609,7 +3495,7 @@
}
/// TODO(srawlins): Add any tests showing this is reported.
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, literal);
}
@@ -3628,7 +3514,7 @@
if (annotation != null) {
DartType type = annotation.typeOrThrow;
if (!type.isVoid) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NON_VOID_RETURN_FOR_OPERATOR, annotation);
}
}
@@ -3642,7 +3528,7 @@
if (typeName != null) {
DartType type = typeName.typeOrThrow;
if (!type.isVoid) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NON_VOID_RETURN_FOR_SETTER, typeName);
}
}
@@ -3667,9 +3553,9 @@
if (field.initializer != null) continue;
var type = fieldElement.type;
- if (!_typeSystem.isPotentiallyNonNullable(type)) continue;
+ if (!typeSystem.isPotentiallyNonNullable(type)) continue;
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_INSTANCE_FIELD,
field,
[field.name.name],
@@ -3716,13 +3602,13 @@
}
var type = node.type!.typeOrThrow;
- if (!_typeSystem.isPotentiallyNonNullable(type)) {
+ if (!typeSystem.isPotentiallyNonNullable(type)) {
return;
}
for (var variable in node.variables) {
if (variable.initializer == null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NOT_INITIALIZED_NON_NULLABLE_VARIABLE,
variable.name,
[variable.name.name],
@@ -3777,7 +3663,7 @@
NodeList<FormalParameter> formalParameters = parameterList.parameters;
for (FormalParameter formalParameter in formalParameters) {
if (formalParameter.isOptional) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR,
formalParameter);
}
@@ -3822,7 +3708,7 @@
.add(BigInt.from(IntegerLiteralImpl.nearestValidDouble(lexeme)));
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
treatedAsDouble
? CompileTimeErrorCode.INTEGER_LITERAL_IMPRECISE_AS_DOUBLE
: CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE,
@@ -3843,7 +3729,7 @@
return;
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, name);
}
@@ -3863,7 +3749,7 @@
for (ConstructorInitializer initializer in declaration.initializers) {
if (initializer is RedirectingConstructorInvocation) {
if (_hasRedirectingFactoryConstructorCycle(constructorElement)) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer);
}
return;
@@ -3888,7 +3774,7 @@
return false;
}
// report error
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT,
redirectedConstructorNode);
return true;
@@ -3912,7 +3798,7 @@
for (FormalParameter parameter in declaration.parameters.parameters) {
if (parameter is DefaultFormalParameter &&
parameter.defaultValue != null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode
.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
parameter.identifier!);
@@ -3934,7 +3820,7 @@
if (declaration.name != null) {
constructorStrName += ".${declaration.name!.name}";
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.REDIRECT_TO_ABSTRACT_CLASS_CONSTRUCTOR,
redirectedConstructor,
[constructorStrName, redirectedClass.name]);
@@ -3945,7 +3831,7 @@
for (ConstructorInitializer initializer in declaration.initializers) {
if (initializer is RedirectingConstructorInvocation) {
if (numRedirections > 0) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS,
initializer);
}
@@ -3958,13 +3844,13 @@
if (invocation.constructorName != null) {
constructorStrName += ".${invocation.constructorName!.name}";
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR,
invocation,
[constructorStrName, enclosingTypeName]);
} else {
if (redirectingElement.isFactory) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode
.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
initializer);
@@ -3985,17 +3871,17 @@
if (numRedirections > 0) {
for (ConstructorInitializer initializer in declaration.initializers) {
if (initializer is SuperConstructorInvocation) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
initializer);
}
if (initializer is ConstructorFieldInitializer) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
initializer);
}
if (initializer is AssertInitializer) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSERT_IN_REDIRECTING_CONSTRUCTOR,
initializer);
}
@@ -4016,7 +3902,7 @@
if (redirectedElement != null &&
element.isConst &&
!redirectedElement.isConst) {
- _errorReporter.reportErrorForOffset(
+ errorReporter.reportErrorForOffset(
CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR,
errorEntity.offset,
errorEntity.end - errorEntity.offset,
@@ -4031,8 +3917,8 @@
_hiddenElements != null &&
_hiddenElements!.contains(element) &&
node.parent is! CommentReference) {
- _errorReporter.reportError(DiagnosticFactory()
- .referencedBeforeDeclaration(_errorReporter.source, node));
+ errorReporter.reportError(DiagnosticFactory()
+ .referencedBeforeDeclaration(errorReporter.source, node));
}
}
@@ -4053,7 +3939,7 @@
TypeName typeName = typeNames[j];
if (typeName.name.staticElement == element) {
detectedRepeatOnIndex[j] = true;
- _errorReporter
+ errorReporter
.reportErrorForNode(errorCode, typeName, [typeName.name.name]);
}
}
@@ -4066,7 +3952,7 @@
/// See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH].
void _checkForRethrowOutsideCatch(RethrowExpression expression) {
if (!_isInCatchClause) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression);
}
}
@@ -4087,7 +3973,7 @@
return;
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body);
}
@@ -4114,9 +4000,9 @@
// Check every set element.
var verifier = LiteralElementVerifier(
_typeProvider,
- _typeSystem,
- _errorReporter,
- _checkForUseOfVoidResult,
+ typeSystem,
+ errorReporter,
+ checkForUseOfVoidResult,
forSet: true,
elementType: setElementType,
featureSet: _featureSet!,
@@ -4148,7 +4034,7 @@
if (element.isStatic || element is ConstructorElement) {
return;
}
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
name,
[name.name]);
@@ -4166,7 +4052,7 @@
}
Expression expression = statement.expression;
- if (_checkForUseOfVoidResult(expression)) {
+ if (checkForUseOfVoidResult(expression)) {
return;
}
@@ -4183,8 +4069,8 @@
DartType caseType = caseExpression.typeOrThrow;
// check types
- if (!_typeSystem.isAssignableTo(expressionType, caseType)) {
- _errorReporter.reportErrorForNode(
+ if (!typeSystem.isAssignableTo(expressionType, caseType)) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
expression,
[expressionType, caseType]);
@@ -4197,8 +4083,8 @@
var expression = node.expression;
var type = node.expression.typeOrThrow;
- if (!_typeSystem.isAssignableTo(type, _typeSystem.objectNone)) {
- _errorReporter.reportErrorForNode(
+ if (!typeSystem.isAssignableTo(type, typeSystem.objectNone)) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.THROW_OF_INVALID_TYPE,
expression,
[type],
@@ -4215,7 +4101,7 @@
TypeAliasElementImpl element,
) {
if (element.hasSelfReference) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
node,
);
@@ -4227,7 +4113,7 @@
/// See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS].
void _checkForTypeAnnotationDeferredClass(TypeAnnotation? type) {
if (type is TypeName && type.isDeferred) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.TYPE_ANNOTATION_DEFERRED_CLASS,
type,
[type.name]);
@@ -4258,7 +4144,7 @@
}
if (step == parameters.length) {
var element = parameter.declaredElement!;
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND,
parameter,
[element.displayName, element.bound],
@@ -4278,7 +4164,7 @@
// The class's type parameters are not in scope for static methods.
// However all other type parameters are legal (e.g. the static method's
// type parameters, or a local function's type parameters).
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.TYPE_PARAMETER_REFERENCED_BY_STATIC,
identifier);
}
@@ -4337,7 +4223,7 @@
: superUnnamedConstructor;
if (superUnnamedConstructor != null) {
if (superUnnamedConstructor.isFactory) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
constructor.returnType,
[superUnnamedConstructor]);
@@ -4346,14 +4232,14 @@
var name = constructor.name;
int offset = returnType.offset;
int length = (name != null ? name.end : returnType.end) - offset;
- _errorReporter.reportErrorForOffset(
+ errorReporter.reportErrorForOffset(
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
offset,
length,
[superType]);
}
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
constructor.returnType,
[superElement.name]);
@@ -4429,13 +4315,13 @@
return;
}
- if (_typeSystem.isStrictlyNonNullable(targetType)) {
+ if (typeSystem.isStrictlyNonNullable(targetType)) {
if (errorCode == StaticWarningCode.INVALID_NULL_AWARE_OPERATOR) {
var previousOperator = previousShortCircuitingOperator(target);
if (previousOperator != null) {
- _errorReporter.reportError(DiagnosticFactory()
+ errorReporter.reportError(DiagnosticFactory()
.invalidNullAwareAfterShortCircuit(
- _errorReporter.source,
+ errorReporter.source,
operator.offset,
endToken.end - operator.offset,
arguments,
@@ -4443,7 +4329,7 @@
return;
}
}
- _errorReporter.reportErrorForOffset(
+ errorReporter.reportErrorForOffset(
errorCode,
operator.offset,
endToken.end - operator.offset,
@@ -4482,41 +4368,19 @@
return;
}
if (_enclosingExtension != null) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode
.UNQUALIFIED_REFERENCE_TO_STATIC_MEMBER_OF_EXTENDED_TYPE,
name,
[enclosingElement.displayName]);
} else {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
name,
[enclosingElement.displayName]);
}
}
- /// Check for situations where the result of a method or function is used,
- /// when it returns 'void'. Or, in rare cases, when other types of expressions
- /// are void, such as identifiers.
- ///
- /// See [StaticWarningCode.USE_OF_VOID_RESULT].
- bool _checkForUseOfVoidResult(Expression expression) {
- if (!identical(expression.staticType, VoidTypeImpl.instance)) {
- return false;
- }
-
- if (expression is MethodInvocation) {
- SimpleIdentifier methodName = expression.methodName;
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.USE_OF_VOID_RESULT, methodName, []);
- } else {
- _errorReporter.reportErrorForNode(
- CompileTimeErrorCode.USE_OF_VOID_RESULT, expression, []);
- }
-
- return true;
- }
-
void _checkForValidField(FieldFormalParameter parameter) {
var parent2 = parameter.parent?.parent;
if (parent2 is! ConstructorDeclaration &&
@@ -4527,7 +4391,7 @@
if (element is FieldFormalParameterElement) {
var fieldElement = element.field;
if (fieldElement == null || fieldElement.isSynthetic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
parameter,
[parameter.identifier.name]);
@@ -4537,29 +4401,29 @@
DartType declaredType = parameterElement.type;
DartType fieldType = fieldElement.type;
if (fieldElement.isSynthetic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
parameter,
[parameter.identifier.name]);
} else if (fieldElement.isStatic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
parameter,
[parameter.identifier.name]);
- } else if (!_typeSystem.isSubtypeOf(declaredType, fieldType)) {
- _errorReporter.reportErrorForNode(
+ } else if (!typeSystem.isSubtypeOf(declaredType, fieldType)) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
parameter,
[declaredType, fieldType]);
}
} else {
if (fieldElement.isSynthetic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
parameter,
[parameter.identifier.name]);
} else if (fieldElement.isStatic) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
parameter,
[parameter.identifier.name]);
@@ -4617,13 +4481,13 @@
expected = 0;
}
if (expected != -1 && numParameters != expected) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR,
nameNode,
[name, expected, numParameters]);
return true;
} else if ("-" == name && numParameters > 1) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS,
nameNode,
[numParameters]);
@@ -4648,7 +4512,7 @@
NodeList<FormalParameter> parameters = parameterList.parameters;
if (parameters.length != 1 || !parameters[0].isRequiredPositional) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
setterName);
}
@@ -4752,7 +4616,7 @@
if (!superVariance
.greaterThanOrEqual(typeParameterElementImpl.variance)) {
if (!typeParameterElementImpl.isLegacyCovariant) {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode
.WRONG_EXPLICIT_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
typeParameter,
@@ -4764,7 +4628,7 @@
],
);
} else {
- _errorReporter.reportErrorForElement(
+ errorReporter.reportErrorForElement(
CompileTimeErrorCode
.WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
typeParameter,
@@ -4800,7 +4664,7 @@
TypeParameterElementImpl typeParameterImpl =
typeParameter as TypeParameterElementImpl;
if (!variance.greaterThanOrEqual(typeParameterImpl.variance)) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.WRONG_TYPE_PARAMETER_VARIANCE_POSITION,
node,
[
@@ -4829,7 +4693,7 @@
for (var interfaceNode in implementsClause.interfaces) {
var type = interfaceNode.type;
if (type is InterfaceType && type.element == superElement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS,
interfaceNode,
[superElement],
@@ -4846,7 +4710,7 @@
if (readElement is MethodElement) {
var parameters = readElement.parameters;
if (parameters.isNotEmpty) {
- _checkForArgumentTypeNotAssignableForArgument2(
+ checkForArgumentTypeNotAssignableForArgument2(
argument: index,
parameter: parameters[0],
promoteParameterToNullable: false,
@@ -4857,7 +4721,7 @@
if (writeElement is MethodElement) {
var parameters = writeElement.parameters;
if (parameters.isNotEmpty) {
- _checkForArgumentTypeNotAssignableForArgument2(
+ checkForArgumentTypeNotAssignableForArgument2(
argument: index,
parameter: parameters[0],
promoteParameterToNullable: false,
@@ -4874,7 +4738,7 @@
var classElement = node.declaredElement as ClassElement;
var supertype = classElement.supertype;
- var interfacesMerger = InterfacesMerger(_typeSystem);
+ var interfacesMerger = InterfacesMerger(typeSystem);
interfacesMerger.addWithSupertypes(supertype);
for (var typeName in withClause.mixinTypes) {
@@ -4882,7 +4746,7 @@
if (mixinType is InterfaceType) {
var mixinElement = mixinType.element;
if (typeName.typeArguments == null) {
- var mixinSupertypeConstraints = _typeSystem
+ var mixinSupertypeConstraints = typeSystem
.gatherMixinSupertypeConstraintsForInference(mixinElement);
if (mixinSupertypeConstraints.isNotEmpty) {
var matchingInterfaceTypes = _findInterfaceTypesForConstraints(
@@ -4894,7 +4758,7 @@
// Try to pattern match matchingInterfaceType against
// mixinSupertypeConstraint to find the correct set of type
// parameters to apply to the mixin.
- var inferredTypeArguments = _typeSystem.matchSupertypeConstraints(
+ var inferredTypeArguments = typeSystem.matchSupertypeConstraints(
mixinElement,
mixinSupertypeConstraints,
matchingInterfaceTypes,
@@ -4902,7 +4766,7 @@
.isEnabled(Feature.generic_metadata),
);
if (inferredTypeArguments == null) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode
.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
typeName.name.beginToken,
@@ -4954,7 +4818,7 @@
for (var mixinNode in withClause.mixinTypes) {
var type = mixinNode.type;
if (type is InterfaceType && type.element == superElement) {
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MIXINS_SUPER_CLASS,
mixinNode,
[superElement],
@@ -4983,7 +4847,7 @@
if (_enclosingExtension != null) {
// Reported by the parser.
} else {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
keyword,
);
@@ -5031,16 +4895,16 @@
if (parameter.isRequiredNamed) {
if (parameter.defaultValue != null) {
var parameterName = _parameterName(parameter);
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.DEFAULT_VALUE_ON_REQUIRED_PARAMETER,
parameterName ?? parameter,
);
}
} else if (defaultValuesAreExpected && parameter.defaultValue == null) {
var type = parameter.declaredElement!.type;
- if (_typeSystem.isPotentiallyNonNullable(type)) {
+ if (typeSystem.isPotentiallyNonNullable(type)) {
var parameterName = _parameterName(parameter);
- _errorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.MISSING_DEFAULT_VALUE_FOR_PARAMETER,
parameterName ?? parameter,
[parameterName?.name ?? '?'],
@@ -5061,7 +4925,7 @@
foundInterfaceType = interfaceType;
} else {
if (interfaceType != foundInterfaceType) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode
.MIXIN_INFERENCE_INCONSISTENT_MATCHING_CLASSES,
mixin.name.beginToken,
@@ -5070,7 +4934,7 @@
}
}
if (foundInterfaceType == null) {
- _errorReporter.reportErrorForToken(
+ errorReporter.reportErrorForToken(
CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS,
mixin.name.beginToken,
[mixin, supertypeConstraint]);
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 17573ee..7027e52 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -58,6 +58,7 @@
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error_detection_helpers.dart';
import 'package:analyzer/src/generated/migratable_ast_info_provider.dart';
import 'package:analyzer/src/generated/migration.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -154,7 +155,7 @@
/// Instances of the class `ResolverVisitor` are used to resolve the nodes
/// within a single compilation unit.
-class ResolverVisitor extends ScopedVisitor {
+class ResolverVisitor extends ScopedVisitor with ErrorDetectionHelpers {
/// The manager for the inheritance mappings.
final InheritanceManager3 inheritance;
@@ -203,6 +204,7 @@
late final StaticTypeAnalyzer typeAnalyzer;
/// The type system in use during resolution.
+ @override
final TypeSystemImpl typeSystem;
/// The class declaration representing the class containing the current node,
@@ -418,6 +420,19 @@
bool get _isNonNullableByDefault =>
_featureSet.isEnabled(Feature.non_nullable);
+ /// Verify that the arguments in the given [argumentList] can be assigned to
+ /// their corresponding parameters.
+ ///
+ /// This method corresponds to
+ /// [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList].
+ ///
+ /// See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
+ void checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) {
+ for (Expression argument in argumentList.arguments) {
+ checkForArgumentTypeNotAssignableForArgument(argument);
+ }
+ }
+
void checkForBodyMayCompleteNormally({
required DartType? returnType,
required FunctionBody body,
@@ -877,6 +892,10 @@
return;
}
AnnotationResolver(this).resolve(node);
+ var arguments = node.arguments;
+ if (arguments != null) {
+ checkForArgumentTypesNotAssignableInList(arguments);
+ }
}
@override
@@ -1533,6 +1552,7 @@
_functionExpressionInvocationResolver
.resolve(node as FunctionExpressionInvocationImpl);
nullShortingTermination(node);
+ checkForArgumentTypesNotAssignableInList(node.argumentList);
}
@override
@@ -1679,6 +1699,7 @@
node.argumentList.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
+ checkForArgumentTypesNotAssignableInList(node.argumentList);
}
@override
@@ -1770,6 +1791,7 @@
} else {
nullShortingTermination(node);
}
+ checkForArgumentTypesNotAssignableInList(node.argumentList);
}
@override
@@ -1886,6 +1908,7 @@
InferenceContext.setType(node.argumentList, node.staticElement?.type);
node.argumentList.accept(this);
node.accept(typeAnalyzer);
+ checkForArgumentTypesNotAssignableInList(node.argumentList);
}
@override
@@ -1943,6 +1966,7 @@
InferenceContext.setType(node.argumentList, node.staticElement?.type);
node.argumentList.accept(this);
node.accept(typeAnalyzer);
+ checkForArgumentTypesNotAssignableInList(node.argumentList);
}
@override
diff --git a/pkg/analyzer/lib/src/summary2/apply_resolution.dart b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
index 20308e2..e8fd2a7 100644
--- a/pkg/analyzer/lib/src/summary2/apply_resolution.dart
+++ b/pkg/analyzer/lib/src/summary2/apply_resolution.dart
@@ -84,6 +84,8 @@
void visitAnnotation(covariant AnnotationImpl node) {
_expectMarker(MarkerTag.Annotation_name);
node.name.accept(this);
+ _expectMarker(MarkerTag.Annotation_typeArguments);
+ node.typeArguments?.accept(this);
_expectMarker(MarkerTag.Annotation_constructorName);
node.constructorName?.accept(this);
_expectMarker(MarkerTag.Annotation_arguments);
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 5282bec..18733e8 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -258,11 +258,13 @@
Annotation _readAnnotation() {
var name = readNode() as Identifier;
+ var typeArguments = _readOptionalNode() as TypeArgumentList?;
var constructorName = _readOptionalNode() as SimpleIdentifier?;
var arguments = _readOptionalNode() as ArgumentList?;
return astFactory.annotation(
atSign: Tokens.AT,
name: name,
+ typeArguments: typeArguments,
period: Tokens.PERIOD,
constructorName: constructorName,
arguments: arguments,
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index 7fd7486..933b12b 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -11,6 +11,7 @@
AnnotatedNode_metadata,
AnnotatedNode_end,
Annotation_name,
+ Annotation_typeArguments,
Annotation_constructorName,
Annotation_arguments,
Annotation_element,
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index be8cfa6..74968d8 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -61,6 +61,8 @@
_writeMarker(MarkerTag.Annotation_name);
_writeNode(node.name);
+ _writeMarker(MarkerTag.Annotation_typeArguments);
+ _writeOptionalNode(node.typeArguments);
_writeMarker(MarkerTag.Annotation_constructorName);
_writeOptionalNode(node.constructorName);
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 61d2688..845aa80 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -574,6 +574,8 @@
//TODO(pq): consider an error if the node is not a Scalar.
});
}
+ // TODO(srawlins): Report non-Map with
+ // AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT.
}
}
@@ -658,11 +660,11 @@
void _applyExcludes(AnalysisOptionsImpl options, YamlNode? excludes) {
if (excludes is YamlList) {
- var excludeList = toStringList(excludes);
- if (excludeList != null) {
- options.excludePatterns = excludeList;
- }
+ // TODO(srawlins): Report non-String items
+ options.excludePatterns = excludes.whereType<String>().toList();
}
+ // TODO(srawlins): Report non-List with
+ // AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT.
}
void _applyLanguageOption(
diff --git a/pkg/analyzer/lib/src/util/yaml.dart b/pkg/analyzer/lib/src/util/yaml.dart
index 642dcc1..108ea8d 100644
--- a/pkg/analyzer/lib/src/util/yaml.dart
+++ b/pkg/analyzer/lib/src/util/yaml.dart
@@ -8,23 +8,6 @@
import 'package:yaml/src/event.dart';
import 'package:yaml/yaml.dart';
-/// If all of the elements of [list] are strings, return a list of strings
-/// containing the same elements. Otherwise, return `null`.
-List<String>? toStringList(List? list) {
- if (list == null) {
- return null;
- }
- List<String> stringList = <String>[];
- for (var element in list) {
- if (element is String) {
- stringList.add(element);
- } else {
- return null;
- }
- }
- return stringList;
-}
-
bool _contains(YamlList l1, YamlNode n2) {
for (YamlNode n1 in l1.nodes) {
if (n1.value == n2.value) {
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index fdf4b00..ee0c6d9 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -13,44 +13,11 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/util/uri.dart';
+import 'package:analyzer/src/workspace/bazel_watcher.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
-import 'package:watcher/watcher.dart';
-
-/// Notification that we issue in [BazelWorkspace.findFile] when searching for
-/// generated files.
-///
-/// This allows clients to watch for changes to the generated files.
-class BazelFileNotification {
- /// Candidate paths that we searched.
- ///
- /// If it's a singleton, then the file was found/resolved.
- final List<String> candidates;
-
- /// Absolute path that we tried searching for.
- ///
- /// This is not necessarily the path of the actual file that will be used. See
- /// [BazelWorkspace.findFile] for details.
- final String requested;
-
- final ResourceProvider _provider;
-
- BazelFileNotification(this.requested, this.candidates, this._provider);
-
- BazelFileWatcher watcher(
- {required Duration pollingDelayShort,
- required Duration pollingDelayLong,
- Timer Function(Duration, void Function(Timer)) timerFactory =
- _defaultTimerFactory}) =>
- BazelFileWatcher(candidates, _provider, pollingDelayShort,
- pollingDelayLong, timerFactory);
-
- static Timer _defaultTimerFactory(
- Duration duration, void Function(Timer) callback) =>
- Timer.periodic(duration, callback);
-}
/// Instances of the class `BazelFileUriResolver` resolve `file` URI's by first
/// resolving file uri's in the expected way, and then by looking in the
@@ -76,140 +43,6 @@
}
}
-/// Watches a list of files that should be generated by Bazel.
-///
-/// If we didn't find the file initially, we'll have more that one potential
-/// path. We'll poll them with a shorter delay waiting for at least one
-/// of the paths to become valid (we assume that users will generate the rather
-/// sooner than later since they will likely see errors due to unresolved
-/// files). Once a file appears, we switch to a different mode, where we only
-/// watch that particular file and poll it less frequently. If the file is
-/// deleted we go back to the initial mode of eager polling for all paths.
-class BazelFileWatcher {
- /// The paths of files that we watch for.
- ///
- /// If it's a singleton, then the file was found/resolved by the
- /// [BazelWorkspace].
- final List<String> _candidates;
-
- final _eventsController = StreamController<WatchEvent>.broadcast();
-
- /// The time of last modification of the file under [_validPath].
- int? _lastModified;
-
- /// How often do we poll a file that we have found.
- final Duration _pollingDelayLong;
-
- /// How often do we poll when none of potential files exist.
- final Duration _pollingDelayShort;
-
- final ResourceProvider _provider;
-
- /// One of the [_candidates] that is valid, i.e., we found a file with that
- /// path.
- String? _validPath;
-
- Timer? _timer;
-
- /// Used to contruct a [Timer] for polling.
- final Timer Function(Duration, void Function(Timer)) _timerFactory;
-
- BazelFileWatcher(this._candidates, this._provider, this._pollingDelayShort,
- this._pollingDelayLong, this._timerFactory);
-
- Stream<WatchEvent> get events => _eventsController.stream;
-
- /// Starts watching the files.
- ///
- /// To avoid missing events, the clients should first start listening on
- /// [events] and then call [start].
- void start() {
- assert(_timer == null);
- var info = _pollAll();
- if (info != null) {
- _validPath = info.path;
- _lastModified = info.modified;
- _setPollingDelayToLong();
- } else {
- _setPollingDelayToShort();
- }
- }
-
- void stop() {
- _timer?.cancel();
- _eventsController.close();
- }
-
- void _poll() {
- if (_eventsController.isClosed) return;
-
- int? modified;
- if (_validPath == null) {
- var info = _pollAll();
- if (info != null) {
- _validPath = info.path;
- modified = info.modified;
- }
- } else {
- modified = _pollOne(_validPath!);
- }
-
- // If there is no file, then we have nothing to do.
- if (_validPath == null) return;
-
- if (modified == null && _lastModified != null) {
- // The file is no longer there, so let's issue a REMOVE event, unset
- // `_validPath` and set the timer to poll more frequently.
- _eventsController.add(WatchEvent(ChangeType.REMOVE, _validPath!));
- _validPath = null;
- _setPollingDelayToShort();
- } else if (modified != null && _lastModified == null) {
- _eventsController.add(WatchEvent(ChangeType.ADD, _validPath!));
- _setPollingDelayToLong();
- } else if (_lastModified != null && modified != _lastModified) {
- _eventsController.add(WatchEvent(ChangeType.MODIFY, _validPath!));
- }
- _lastModified = modified;
- }
-
- /// Tries polling all the possible paths.
- ///
- /// Will set [_validPath] and return its modified time if a file is found.
- /// Returns [null] if nothing is found.
- FileInfo? _pollAll() {
- assert(_validPath == null);
- for (var path in _candidates) {
- var modified = _pollOne(path);
- if (modified != null) {
- return FileInfo(path, modified);
- }
- }
- return null;
- }
-
- /// Returns the modified time of the path or `null` if the file does not
- /// exist.
- int? _pollOne(String path) {
- try {
- var file = _provider.getFile(path);
- return file.modificationStamp;
- } on FileSystemException catch (_) {
- // File doesn't exist, so return null.
- return null;
- }
- }
-
- void _setPollingDelayToLong() {
- _timer?.cancel();
- _timer = _timerFactory(_pollingDelayLong, (_) => _poll());
- }
-
- void _setPollingDelayToShort() {
- _timer?.cancel();
- _timer = _timerFactory(_pollingDelayShort, (_) => _poll());
- }
-}
-
/// The [UriResolver] that can resolve `package` URIs in [BazelWorkspace].
class BazelPackageUriResolver extends UriResolver {
final BazelWorkspace _workspace;
@@ -377,8 +210,7 @@
/// the corresponding package.
final Map<String, BazelWorkspacePackage> _directoryToPackage = {};
- final _bazelCandidateFiles =
- StreamController<BazelFileNotification>.broadcast();
+ final _bazelCandidateFiles = StreamController<BazelSearchInfo>.broadcast();
BazelWorkspace._(
this.provider,
@@ -391,7 +223,7 @@
/// Stream of files that we tried to find along with their potential or actual
/// paths.
- Stream<BazelFileNotification> get bazelCandidateFiles =>
+ Stream<BazelSearchInfo> get bazelCandidateFiles =>
_bazelCandidateFiles.stream;
@override
@@ -435,8 +267,8 @@
for (var path in generatedCandidates) {
File file = provider.getFile(path);
if (file.exists) {
- _bazelCandidateFiles.add(BazelFileNotification(
- relative, generatedCandidates.toList(), provider));
+ _bazelCandidateFiles
+ .add(BazelSearchInfo(relative, generatedCandidates.toList()));
return file;
}
}
@@ -455,8 +287,8 @@
}
// If we couldn't find the file, assume that it has not yet been
// generated, so send an event with all the paths that we tried.
- _bazelCandidateFiles.add(BazelFileNotification(
- relative, generatedCandidates.toList(), provider));
+ _bazelCandidateFiles
+ .add(BazelSearchInfo(relative, generatedCandidates.toList()));
// Not generated, return the default one.
return writableFile;
} catch (_) {
@@ -833,9 +665,3 @@
}
}
}
-
-class FileInfo {
- String path;
- int modified;
- FileInfo(this.path, this.modified);
-}
diff --git a/pkg/analyzer/lib/src/workspace/bazel_watcher.dart b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
new file mode 100644
index 0000000..5d76920
--- /dev/null
+++ b/pkg/analyzer/lib/src/workspace/bazel_watcher.dart
@@ -0,0 +1,544 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:core';
+import 'dart:io' as io;
+import 'dart:isolate';
+import 'dart:math';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/instrumentation/service.dart';
+import 'package:pedantic/pedantic.dart';
+import 'package:watcher/watcher.dart';
+
+Future<void> _isolateMain(SendPort sendPort) async {
+ var fromMainIsolate = ReceivePort();
+ var bazelIsolate = BazelFileWatcherIsolate(
+ fromMainIsolate, sendPort, PhysicalResourceProvider.INSTANCE)
+ ..start();
+ await bazelIsolate.hasFinished;
+}
+
+/// Exposes the ability to poll for changes in generated files.
+///
+/// The only logic here is that we may have multiple "candidate" paths where the
+/// file might be located, but after the first time we actually find the file,
+/// we can only focus on that particular path, since the files should be
+/// consistently in the same place after rebuilds.
+class BazelFilePoller {
+ /// The possible "candidate" paths that we watch.
+ final List<String> _candidates;
+
+ /// The time of last modification of the file under [_validPath].
+ int? _lastModified;
+
+ /// The resource provider used for polling the files.
+ final ResourceProvider _provider;
+
+ /// One of the [_candidates] that is valid, i.e. we found a file with that
+ /// path.
+ String? _validPath;
+
+ BazelFilePoller(this._provider, this._candidates);
+
+ /// Checks if the file corresponding to the watched path has changed and
+ /// returns the event or `null` if nothing changed.
+ WatchEvent? poll() {
+ int? modified;
+ if (_validPath == null) {
+ var info = _pollAll();
+ if (info != null) {
+ _validPath = info.path;
+ modified = info.modified;
+ }
+ } else {
+ modified = _pollOne(_validPath!);
+ }
+
+ // If there is no file, then we have nothing to do.
+ if (_validPath == null) return null;
+
+ WatchEvent? result;
+ if (modified == null && _lastModified != null) {
+ // The file is no longer there, so let's issue a REMOVE event, unset
+ // `_validPath` and set the timer to poll more frequently.
+ result = WatchEvent(ChangeType.REMOVE, _validPath!);
+ _validPath = null;
+ } else if (modified != null && _lastModified == null) {
+ result = WatchEvent(ChangeType.ADD, _validPath!);
+ } else if (_lastModified != null && modified != _lastModified) {
+ result = WatchEvent(ChangeType.MODIFY, _validPath!);
+ }
+ _lastModified = modified;
+ return result;
+ }
+
+ /// Starts watching the files.
+ ///
+ /// This should be called when creating an instance of this class to correctly
+ /// categorize events (e.g. whether a file already existed or was added).
+ void start() {
+ assert(_validPath == null);
+ assert(_lastModified == null);
+ var info = _pollAll();
+ if (info != null) {
+ _validPath = info.path;
+ _lastModified = info.modified;
+ }
+ }
+
+ /// Tries polling all the possible paths.
+ ///
+ /// Will set [_validPath] and return its modified time if a file is found.
+ /// Returns [null] if nothing is found.
+ FileInfo? _pollAll() {
+ assert(_validPath == null);
+ for (var path in _candidates) {
+ var modified = _pollOne(path);
+ if (modified != null) {
+ return FileInfo(path, modified);
+ }
+ }
+ return null;
+ }
+
+ /// Returns the modified time of the path or `null` if the file does not
+ /// exist.
+ int? _pollOne(String path) {
+ try {
+ var file = _provider.getFile(path);
+ return file.modificationStamp;
+ } on FileSystemException catch (_) {
+ // File doesn't exist, so return null.
+ return null;
+ }
+ }
+}
+
+/// The watcher implementation that runs in a separate isolate.
+///
+/// It'll try to detect when Bazel finished running (through [PollTrigger] which
+/// usually will be [_BazelInvocationWatcher]) and then poll all the files to
+/// find any changes, which will be sent to the main isolate as
+/// [BazelWatcherEvents].
+class BazelFileWatcherIsolate {
+ final ReceivePort _fromMainIsolate;
+ final SendPort _toMainIsolate;
+ late final StreamSubscription _fromMainIsolateSubscription;
+
+ /// For each workspace tracks all the data associated with it.
+ final _perWorkspaceData = <String, _PerWorkspaceData>{};
+
+ /// A factory for [PollTrigger].
+ ///
+ /// Used mostly for testing to allow using a different trigger.
+ late final PollTrigger Function(String) _pollTriggerFactory;
+
+ /// Resource provider used for polling.
+ ///
+ /// NB: The default [PollTrigger] (i.e., [_BazelInvocationWatcher]) uses
+ /// `dart:io` directly. So for testing both [_provider] and
+ /// [_pollTriggerFactory] should be provided.
+ final ResourceProvider _provider;
+
+ final _hasFinished = Completer<void>();
+
+ BazelFileWatcherIsolate(
+ this._fromMainIsolate, this._toMainIsolate, this._provider,
+ {PollTrigger Function(String)? pollTriggerFactory}) {
+ _pollTriggerFactory = pollTriggerFactory ?? _defaultPollTrigger;
+ }
+
+ Future<void> get hasFinished => _hasFinished.future;
+
+ void handleRequest(dynamic request) async {
+ if (request is BazelWatcherStartWatching) {
+ var workspaceData = _perWorkspaceData[request.workspace];
+ if (workspaceData == null) {
+ var trigger = _pollTriggerFactory(request.workspace);
+ var subscription =
+ trigger.stream.listen((_) => _pollAllWatchers(request.workspace));
+ workspaceData = _PerWorkspaceData(trigger, subscription);
+ _perWorkspaceData[request.workspace] = workspaceData;
+ }
+ var requestedPath = request.info.requestedPath;
+ var count = workspaceData.watched.add(requestedPath);
+ if (count > 1) {
+ assert(workspaceData.pollers.containsKey(requestedPath));
+ return;
+ }
+ workspaceData.pollers[requestedPath] =
+ BazelFilePoller(_provider, request.info.candidatePaths)..start();
+ } else if (request is BazelWatcherStopWatching) {
+ var workspaceData = _perWorkspaceData[request.workspace];
+ if (workspaceData == null) return;
+ var count = workspaceData.watched.remove(request.requestedPath);
+ if (count == 0) {
+ workspaceData.pollers.remove(request.requestedPath);
+ if (workspaceData.watched.isEmpty) {
+ workspaceData.trigger.cancel();
+ unawaited(workspaceData.pollSubscription.cancel());
+ _perWorkspaceData.remove(request.workspace);
+ }
+ }
+ } else if (request is BazelWatcherShutdownIsolate) {
+ unawaited(_fromMainIsolateSubscription.cancel());
+ _fromMainIsolate.close();
+ for (var data in _perWorkspaceData.values) {
+ data.trigger.cancel();
+ unawaited(data.pollSubscription.cancel());
+ }
+ _hasFinished.complete();
+ _perWorkspaceData.clear();
+ } else {
+ // We don't have access to the `InstrumentationService` so we send the
+ // message to the main isolate to log it.
+ _toMainIsolate.send(BazelWatcherError(
+ 'BazelFileWatcherIsolate got unexpected request: $request'));
+ }
+ }
+
+ /// Returns the total number of requested file paths that are being watched.
+ ///
+ /// This is for testing *only*.
+ int numWatchedFiles() {
+ var total = 0;
+ for (var data in _perWorkspaceData.values) {
+ total += data.watched.length;
+ }
+ return total;
+ }
+
+ /// Starts listening for messages from the main isolate and sends it
+ /// [BazelWatcherIsolateStarted].
+ void start() {
+ _fromMainIsolateSubscription = _fromMainIsolate.listen(handleRequest);
+ _toMainIsolate.send(BazelWatcherIsolateStarted(_fromMainIsolate.sendPort));
+ }
+
+ PollTrigger _defaultPollTrigger(String workspacePath) =>
+ _BazelInvocationWatcher(_provider, workspacePath);
+
+ void _pollAllWatchers(String workspace) {
+ try {
+ var events = <WatchEvent>[];
+ for (var watcher in _perWorkspaceData[workspace]!.pollers.values) {
+ var event = watcher.poll();
+ if (event != null) events.add(event);
+ }
+ if (events.isNotEmpty) {
+ _toMainIsolate.send(BazelWatcherEvents(events));
+ }
+ } on Exception catch (_) {
+ // This shouldn't really happen, but we shouldn't crash when polling
+ // either, so just ignore the error and rely on the next try.
+ return;
+ }
+ }
+}
+
+/// A watcher service that exposes batch-oriented notification interface for
+/// changes to watched files.
+///
+/// The actual `stat`ing of file takes place in a separate isolate to avoid
+/// blocking the main one. Since much of the analysis server is synchronous, we
+/// can't use async functions and resort to launching the isolate and buffering
+/// the requests until the isolate has started.
+///
+/// The isolate is started lazily on the first request to watch a path, so
+/// instantiating [BazelFileWatcherService] is very cheap.
+///
+/// The protocol when communicating with the isolate:
+/// 1. The watcher isolate sends to the main one a [BazelWatcherIsolateStarted]
+/// and expects a [BazelWatcherInitializeIsolate] to be sent from the main
+/// isolate as a reply.
+/// 2. The main isolate can request to start watching a file by sending
+/// [BazelWatcherStartWatching] request. There is no response expected.
+/// 3. The watcher isolate will send a [BazelWatcherEvents] notification when
+/// changes are detected. Again, no response from the main isolate is
+/// expected.
+/// 4. The main isolate will send a [BazelWatcherShutdownIsolate] when the
+/// isolate is supposed to shut down. No more messages should be exchanged
+/// afterwards.
+class BazelFileWatcherService {
+ final InstrumentationService _instrumetation;
+
+ final _events = StreamController<List<WatchEvent>>.broadcast();
+
+ /// Buffers files to watch until the isolate is ready.
+ final _buffer = <BazelWatcherMessage>[];
+
+ late final ReceivePort _fromIsolatePort;
+ late final SendPort _toIsolatePort;
+ late final StreamSubscription _fromIsolateSubscription;
+
+ /// True if we have launched the isolate.
+ bool _isolateIsStarting = false;
+
+ /// True if the isolate is ready to watch files.
+ final _isolateHasStarted = Completer<void>();
+
+ BazelFileWatcherService(this._instrumetation);
+
+ Stream<List<WatchEvent>> get events => _events.stream;
+
+ /// Shuts everything down including the watcher isolate.
+ /// FIXME(michalt): Remove this if we really never need to shut down the
+ /// isolate.
+ void shutdown() {
+ if (_isolateHasStarted.isCompleted) {
+ _toIsolatePort.send(BazelWatcherShutdownIsolate());
+ }
+ if (_isolateIsStarting) {
+ _fromIsolateSubscription.cancel();
+ _fromIsolatePort.close();
+ }
+ _events.close();
+ }
+
+ void startWatching(String workspace, BazelSearchInfo info) {
+ assert(!_events.isClosed);
+ _startIsolateIfNeeded();
+ var request = BazelWatcherStartWatching(workspace, info);
+ if (!_isolateHasStarted.isCompleted) {
+ _buffer.add(request);
+ } else {
+ _toIsolatePort.send(request);
+ }
+ }
+
+ void stopWatching(String workspace, String requestedPath) {
+ assert(!_events.isClosed);
+ var request = BazelWatcherStopWatching(workspace, requestedPath);
+ if (!_isolateHasStarted.isCompleted) {
+ _buffer.add(request);
+ } else {
+ _toIsolatePort.send(request);
+ }
+ }
+
+ void _handleIsolateMessage(dynamic message) {
+ if (message is BazelWatcherIsolateStarted) {
+ _toIsolatePort = message.sendPort;
+ _isolateHasStarted.complete();
+ } else if (message is BazelWatcherEvents) {
+ _events.add(message.events);
+ } else if (message is BazelWatcherError) {
+ _instrumetation.logError(message.message);
+ } else {
+ _instrumetation.logError(
+ 'Received unexpected message from BazelFileWatcherIsolate: $message');
+ }
+ }
+
+ /// Starts the isolate if it has not yet been started.
+ void _startIsolateIfNeeded() {
+ if (_isolateIsStarting) return;
+ _isolateIsStarting = true;
+ _startIsolateImpl();
+ _isolateHasStarted.future.then((_) {
+ _buffer.forEach(_toIsolatePort.send);
+ _buffer.clear();
+ });
+ }
+
+ Future<void> _startIsolateImpl() async {
+ _fromIsolatePort = ReceivePort();
+ _fromIsolateSubscription = _fromIsolatePort.listen(_handleIsolateMessage);
+ await Isolate.spawn(_isolateMain, _fromIsolatePort.sendPort);
+ }
+}
+
+/// Notification that we issue when searching for generated files in a Bazel
+/// workspace.
+///
+/// This allows clients to watch for changes to the generated files.
+class BazelSearchInfo {
+ /// Candidate paths that we searched.
+ final List<String> candidatePaths;
+
+ /// Absolute path that we tried searching for.
+ ///
+ /// This is not necessarily the path of the actual file that will be used. See
+ /// `BazelWorkspace.findFile` for details.
+ final String requestedPath;
+
+ BazelSearchInfo(this.requestedPath, this.candidatePaths);
+}
+
+class BazelWatcherError implements BazelWatcherMessage {
+ final String message;
+ BazelWatcherError(this.message);
+}
+
+class BazelWatcherEvents implements BazelWatcherMessage {
+ final List<WatchEvent> events;
+ BazelWatcherEvents(this.events);
+}
+
+/// Sent by the watcher isolate to transfer the [SendPort] to the main isolate.
+class BazelWatcherIsolateStarted implements BazelWatcherMessage {
+ final SendPort sendPort;
+ BazelWatcherIsolateStarted(this.sendPort);
+}
+
+abstract class BazelWatcherMessage {}
+
+class BazelWatcherShutdownIsolate implements BazelWatcherMessage {}
+
+class BazelWatcherStartWatching implements BazelWatcherMessage {
+ final String workspace;
+ final BazelSearchInfo info;
+ BazelWatcherStartWatching(this.workspace, this.info);
+}
+
+class BazelWatcherStopWatching implements BazelWatcherMessage {
+ final String workspace;
+ final String requestedPath;
+ BazelWatcherStopWatching(this.workspace, this.requestedPath);
+}
+
+class FileInfo {
+ String path;
+ int modified;
+ FileInfo(this.path, this.modified);
+}
+
+/// Triggers polling every time something appears in the [stream].
+abstract class PollTrigger {
+ Stream<Object> get stream;
+ void cancel();
+}
+
+/// Watches for finished Bazel invocations.
+///
+/// The idea here is to detect when Bazel finished running and use that to
+/// trigger polling. To detect that we use the `command.log` file that bazel
+/// contiuously updates as the build progresses. We find that file based on [1]:
+///
+/// - In the workspace directory there should be a `bazel-out` symlink whose
+/// target should be of the form:
+/// `[...]/<hash of workspace>/execroot/<workspace name>/bazel-out`
+/// - The file should be in `[...]/<hash of workspace>/command.log`.
+///
+/// In other words, we need to get the target of the symlink and then trim three
+/// last parts of the path.
+///
+/// [1] https://docs.bazel.build/versions/master/output_directories.html
+///
+/// NB: We're not using a [ResourceProvider] because it doesn't support finding a
+/// target of a symlink.
+class _BazelInvocationWatcher implements PollTrigger {
+ /// Determines how often do we check for `command.log` changes.
+ static const _pollInterval = Duration(seconds: 1);
+
+ /// To confirm that a build finished, we check for this message in the
+ /// `command.log`.
+ static const _buildCompletedMsg = 'Build completed successfully';
+
+ final _controller = StreamController<WatchEvent>.broadcast();
+ final ResourceProvider _provider;
+ final String _workspacePath;
+ late final Timer _timer;
+ BazelFilePoller? _poller;
+ String? _commandLogPath;
+
+ _BazelInvocationWatcher(this._provider, this._workspacePath) {
+ _timer = Timer.periodic(_pollInterval, _poll);
+ }
+
+ @override
+ Stream<WatchEvent> get stream => _controller.stream;
+
+ @override
+ void cancel() => _timer.cancel();
+
+ bool _buildFinished(String contents) {
+ // Only look at the last 100 characters.
+ var offset = max(0, contents.length - 100);
+ return contents.contains(_buildCompletedMsg, offset);
+ }
+
+ Future<String?> _getCommandLogPath() async {
+ String? resolvedLink;
+ var bazelOut = _inWorkspace('bazel-out');
+ var blazeOut = _inWorkspace('blaze-out');
+ if (await io.Link(bazelOut).exists()) {
+ resolvedLink = await io.Link(bazelOut).target();
+ } else if (await io.Link(blazeOut).exists()) {
+ resolvedLink = await io.Link(blazeOut).target();
+ }
+ if (resolvedLink == null) return null;
+ var pathContext = _provider.pathContext;
+ return pathContext.join(
+ pathContext
+ .dirname(pathContext.dirname(pathContext.dirname(resolvedLink))),
+ 'command.log');
+ }
+
+ String _inWorkspace(String p) =>
+ _provider.pathContext.join(_workspacePath, p);
+
+ Future<void> _poll(Timer _) async {
+ try {
+ _commandLogPath ??= await _getCommandLogPath();
+ if (_commandLogPath == null) return;
+
+ _poller ??= BazelFilePoller(_provider, [_commandLogPath!]);
+ var event = _poller!.poll();
+ if (event == null) return;
+
+ var file = io.File(_commandLogPath!);
+ var contents = file.readAsStringSync();
+ if (_buildFinished(contents)) {
+ _controller.add(WatchEvent(ChangeType.MODIFY, _commandLogPath!));
+ }
+ } on Exception catch (_) {
+ // Ignore failures, it's possible that the file was deleted between when
+ // we checked and tried to read it, etc.
+ return;
+ }
+ }
+}
+
+class _Multiset<T> {
+ final _counts = <T, int>{};
+
+ bool get isEmpty => _counts.isEmpty;
+
+ int get length =>
+ _counts.values.fold(0, (accumulator, count) => accumulator + count);
+
+ /// Returns the number of [elem] objects after the addition.
+ int add(T elem) =>
+ _counts.update(elem, (count) => count + 1, ifAbsent: () => 1);
+
+ /// Returns the number of [elem] objects after the removal.
+ int remove(T elem) {
+ var newCount = _counts.update(elem, (count) => count - 1);
+ if (newCount == 0) {
+ _counts.remove(elem);
+ }
+ return newCount;
+ }
+}
+
+class _PerWorkspaceData {
+ /// For each requested file stores the corresponding [BazelFilePoller].
+ final pollers = <String, BazelFilePoller>{};
+
+ /// Keeps count of the number of requests to watch a file, so that we can stop
+ /// watching when we reach 0 clients.
+ final watched = _Multiset();
+
+ /// The [PollTrigger] that detects when we should poll files.
+ final PollTrigger trigger;
+
+ /// Subscription of [trigger].
+ final StreamSubscription<Object> pollSubscription;
+
+ _PerWorkspaceData(this.trigger, this.pollSubscription);
+}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 325dd01..8c45917 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -20,6 +20,7 @@
source_span: ^1.8.0
watcher: ^1.0.0
yaml: ^3.0.0
+ pedantic: ^1.10.0
dev_dependencies:
analyzer_utilities:
path: ../analyzer_utilities
@@ -27,7 +28,6 @@
async: ^2.5.0
linter: any
matcher: ^0.12.10
- pedantic: ^1.10.0
test: ^1.16.0
test_api: ^0.2.19
test_reflective_loader: ^0.2.0
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index f3bb485..5a0883d 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -427,7 +427,7 @@
expect(prefixed.prefix.staticType, isNull);
expect(annotation.constructorName!.staticElement, aGetter);
- expect(annotation.constructorName!.staticType, typeProvider.intType);
+ assertTypeNull(annotation.constructorName!);
expect(annotation.arguments, isNull);
}
@@ -508,7 +508,7 @@
var constructorName = annotation.constructorName as SimpleIdentifier;
expect(constructorName.staticElement, same(constructor));
- assertType(constructorName.staticType, 'A Function(int, {int b})');
+ assertTypeNull(constructorName);
var arguments = annotation.arguments!.arguments;
var parameters = constructor.parameters;
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index 796316c..d96b3dc 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/constant/value.dart';
import 'package:analyzer/src/test_utilities/find_element.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -15,139 +16,29 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(MetadataResolutionTest);
- defineReflectiveTests(MetadataResolutionWithNullSafetyTest);
});
}
@reflectiveTest
-class MetadataResolutionTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
- test_genericClass_instanceGetter() async {
- await resolveTestCode(r'''
-class A<T> {
- T get foo {}
-}
-
-@A.foo
-void f() {}
-''');
-
- _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
- element: self::@class::A::@getter::foo
- name: PrefixedIdentifier
- identifier: SimpleIdentifier
- staticElement: self::@class::A::@getter::foo
- staticType: null
- token: foo
- period: .
- prefix: SimpleIdentifier
- staticElement: self::@class::A
- staticType: null
- token: A
- staticElement: self::@class::A::@getter::foo
- staticType: null
-''');
- }
-
- test_genericClass_namedConstructor() async {
- await assertNoErrorsInCode(r'''
-class A<T> {
- const A.named();
-}
-
-@A.named()
-void f() {}
-''');
-
- _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
- arguments: ArgumentList
- element: ConstructorMember
- base: self::@class::A::@constructor::named
- substitution: {T: dynamic}
- name: PrefixedIdentifier
- identifier: SimpleIdentifier
- staticElement: ConstructorMember
- base: self::@class::A::@constructor::named
- substitution: {T: dynamic}
- staticType: null
- token: named
- period: .
- prefix: SimpleIdentifier
- staticElement: self::@class::A
- staticType: null
- token: A
- staticElement: ConstructorMember
- base: self::@class::A::@constructor::named
- substitution: {T: dynamic}
- staticType: null
-''');
- }
-
- test_genericClass_staticGetter() async {
- await resolveTestCode(r'''
-class A<T> {
- static T get foo {}
-}
-
-@A.foo
-void f() {}
-''');
-
- _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
- element: self::@class::A::@getter::foo
- name: PrefixedIdentifier
- identifier: SimpleIdentifier
- staticElement: self::@class::A::@getter::foo
- staticType: null
- token: foo
- period: .
- prefix: SimpleIdentifier
- staticElement: self::@class::A
- staticType: null
- token: A
- staticElement: self::@class::A::@getter::foo
- staticType: null
-''');
- }
-
- test_genericClass_unnamedConstructor() async {
- await assertNoErrorsInCode(r'''
-class A<T> {
- const A();
-}
-
-@A()
-void f() {}
-''');
-
- _assertResolvedNodeText(findNode.annotation('@A'), r'''
-Annotation
- arguments: ArgumentList
- element: ConstructorMember
- base: self::@class::A::@constructor::•
- substitution: {T: dynamic}
- name: SimpleIdentifier
- staticElement: self::@class::A
- staticType: null
- token: A
-''');
+class MetadataResolutionTest extends PubPackageResolutionTest {
+ ImportFindElement get import_a {
+ return findElement.importFind('package:test/a.dart');
}
test_onFieldFormal() async {
await assertNoErrorsInCode(r'''
class A {
- const A(_);
+ final Object f;
+ const A(this.f);
}
class B {
final int f;
- B({@A( A(0) ) this.f});
+ B({@A( A(0) ) required this.f});
}
''');
- _assertResolvedNodeText(findNode.annotation('@A'), r'''
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
Annotation
arguments: ArgumentList
arguments
@@ -172,132 +63,11 @@
staticType: null
token: A
''');
- }
-
- test_otherLibrary_constructor_named() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-class A {
- final int f;
- const A.named(this.f);
-}
+ _assertAnnotationValueText(annotation, r'''
+A
+ f: A
+ f: int 0
''');
-
- newFile('$testPackageLibPath/b.dart', content: r'''
-import 'a.dart';
-
-@A.named(42)
-class B {}
-''');
-
- await assertNoErrorsInCode(r'''
-import 'b.dart';
-
-B b;
-''');
-
- var classB = findNode.typeName('B b;').name.staticElement!;
- var annotation = classB.metadata.single;
- var value = annotation.computeConstantValue()!;
- assertType(value.type, 'A');
- expect(value.getField('f')!.toIntValue(), 42);
- }
-
- test_otherLibrary_constructor_unnamed() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-class A {
- final int f;
- const A(this.f);
-}
-''');
-
- newFile('$testPackageLibPath/b.dart', content: r'''
-import 'a.dart';
-
-@A(42)
-class B {}
-''');
-
- await assertNoErrorsInCode(r'''
-import 'b.dart';
-
-B b;
-''');
-
- var classB = findNode.typeName('B b;').name.staticElement!;
- var annotation = classB.metadata.single;
- var value = annotation.computeConstantValue()!;
- assertType(value.type, 'A');
- expect(value.getField('f')!.toIntValue(), 42);
- }
-
- test_otherLibrary_implicitConst() async {
- newFile('$testPackageLibPath/a.dart', content: r'''
-class A {
- final int f;
- const A(this.f);
-}
-
-class B {
- final A a;
- const B(this.a);
-}
-
-@B( A(42) )
-class C {}
-''');
-
- await assertNoErrorsInCode(r'''
-import 'a.dart';
-
-C c;
-''');
-
- var classC = findNode.typeName('C c;').name.staticElement!;
- var annotation = classC.metadata.single;
- var value = annotation.computeConstantValue()!;
- assertType(value.type, 'B');
- expect(value.getField('a')!.getField('f')!.toIntValue(), 42);
- }
-
- @FailingTest(reason: 'Reverted because of dartbug.com/38565')
- test_sameLibrary_genericClass_constructor_unnamed() async {
- await assertNoErrorsInCode(r'''
-class A<T> {
- final T f;
- const A(this.f);
-}
-
-@A(42)
-class B {}
-''');
- var annotation = findElement.class_('B').metadata.single;
- var value = annotation.computeConstantValue()!;
- assertType(value.type, 'A<int>');
- expect(value.getField('f')!.toIntValue(), 42);
- }
-
- void _assertResolvedNodeText(AstNode node, String expected) {
- var actual = _resolvedNodeText(node);
- expect(actual, expected);
- }
-
- String _resolvedNodeText(AstNode node) {
- var buffer = StringBuffer();
- node.accept(
- ResolvedAstPrinter(
- selfUriStr: result.uri.toString(),
- sink: buffer,
- indent: '',
- ),
- );
- return buffer.toString();
- }
-}
-
-@reflectiveTest
-class MetadataResolutionWithNullSafetyTest extends PubPackageResolutionTest {
- ImportFindElement get import_a {
- return findElement.importFind('package:test/a.dart');
}
test_optIn_fromOptOut_class() async {
@@ -354,11 +124,11 @@
isLegacy: true,
);
- _assertConstantValue(
- findElement.function('f').metadata[0].computeConstantValue()!,
- type: 'A*',
- fieldMap: {'a': 42},
- );
+ _assertElementAnnotationValueText(
+ findElement.function('f').metadata[0], r'''
+A*
+ a: int 42
+''');
}
test_optIn_fromOptOut_class_constructor_withDefault() async {
@@ -388,11 +158,11 @@
isLegacy: true,
);
- _assertConstantValue(
- findElement.function('f').metadata[0].computeConstantValue()!,
- type: 'A*',
- fieldMap: {'a': 42},
- );
+ _assertElementAnnotationValueText(
+ findElement.function('f').metadata[0], r'''
+A*
+ a: int 42
+''');
}
test_optIn_fromOptOut_class_getter() async {
@@ -421,7 +191,10 @@
isLegacy: true,
);
- _assertIntValue(findElement.function('f').metadata[0], 42);
+ _assertElementAnnotationValueText(
+ findElement.function('f').metadata[0], r'''
+int 42
+''');
}
test_optIn_fromOptOut_getter() async {
@@ -443,7 +216,10 @@
isLegacy: true,
);
- _assertIntValue(findElement.function('f').metadata[0], 42);
+ _assertElementAnnotationValueText(
+ findElement.function('f').metadata[0], r'''
+int 42
+''');
}
test_optIn_fromOptOut_prefix_class() async {
@@ -547,35 +323,577 @@
);
}
- void _assertConstantValue(
- DartObject object, {
- required String type,
- Map<String, Object>? fieldMap,
- int? intValue,
- }) {
- assertType(object.type, type);
- if (fieldMap != null) {
- for (var entry in fieldMap.entries) {
- var actual = object.getField(entry.key);
- var expected = entry.value;
- if (expected is int) {
- expect(actual!.toIntValue(), expected);
- } else {
- fail('Unsupported expected type: ${expected.runtimeType} $expected');
- }
- }
- } else if (intValue != null) {
- expect(object.toIntValue(), intValue);
- } else {
- fail('No expectations.');
- }
+ test_value_class_inference_namedConstructor() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ final int f;
+ const A.named(this.f);
+}
+
+@A.named(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ element: self::@class::A::@constructor::named
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: self::@class::A::@constructor::named
+ staticType: null
+ token: named
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: self::@class::A::@constructor::named
+ staticType: null
+''');
+ _assertAnnotationValueText(annotation, '''
+A
+ f: int 42
+''');
+
+ assertElement2(
+ findNode.integerLiteral('42').staticParameterElement,
+ declaration: findElement.fieldFormalParameter('f'),
+ );
}
- void _assertIntValue(ElementAnnotation annotation, int intValue) {
- _assertConstantValue(
- annotation.computeConstantValue()!,
- type: 'int',
- intValue: intValue,
+ test_value_class_unnamedConstructor() async {
+ await assertNoErrorsInCode(r'''
+ class A {
+ final int f;
+ const A(this.f);
+}
+
+@A(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ element: self::@class::A::@constructor::•
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+''');
+ _assertAnnotationValueText(annotation, r'''
+A
+ f: int 42
+''');
+
+ assertElement2(
+ findNode.integerLiteral('42').staticParameterElement,
+ declaration: findElement.fieldFormalParameter('f'),
);
}
+
+ test_value_genericClass_inference_namedConstructor() async {
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ final T f;
+ const A.named(this.f);
+}
+
+@A.named(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ element: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+ token: named
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+''');
+ _assertAnnotationValueText(annotation, '''
+A<int>
+ f: int 42
+''');
+ assertElement2(
+ findNode.integerLiteral('42').staticParameterElement,
+ declaration: findElement.fieldFormalParameter('f'),
+ substitution: {'T': 'int'},
+ );
+ }
+
+ test_value_genericClass_inference_unnamedConstructor() async {
+ await assertNoErrorsInCode(r'''
+ class A<T> {
+ final T f;
+ const A(this.f);
+}
+
+@A(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ element: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: int}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+''');
+ _assertAnnotationValueText(annotation, r'''
+A<int>
+ f: int 42
+''');
+ assertElement2(
+ findNode.integerLiteral('42').staticParameterElement,
+ declaration: findElement.fieldFormalParameter('f'),
+ substitution: {'T': 'int'},
+ );
+ }
+
+ test_value_genericClass_instanceGetter() async {
+ await resolveTestCode(r'''
+class A<T> {
+ T get foo {}
+}
+
+@A.foo
+void f() {}
+''');
+
+ _assertResolvedNodeText(findNode.annotation('@A'), r'''
+Annotation
+ element: self::@class::A::@getter::foo
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: self::@class::A::@getter::foo
+ staticType: null
+ token: foo
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: self::@class::A::@getter::foo
+ staticType: null
+''');
+ }
+
+ test_value_genericClass_namedConstructor() async {
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ final int f;
+ const A.named(this.f);
+}
+
+@A.named(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ element: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: dynamic}
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: dynamic}
+ staticType: null
+ token: named
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: dynamic}
+ staticType: null
+''');
+ _assertAnnotationValueText(annotation, '''
+A<dynamic>
+ f: int 42
+''');
+ }
+
+ test_value_genericClass_staticGetter() async {
+ await resolveTestCode(r'''
+class A<T> {
+ static T get foo {}
+}
+
+@A.foo
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ element: self::@class::A::@getter::foo
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: self::@class::A::@getter::foo
+ staticType: null
+ token: foo
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: self::@class::A::@getter::foo
+ staticType: null
+''');
+ _assertAnnotationValueText(annotation, '''
+<null>
+''');
+ }
+
+ test_value_genericClass_typeArguments_namedConstructor() async {
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ final T f;
+ const A.named(this.f);
+}
+
+@A<int>.named(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ constructorName: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+ token: named
+ element: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+''');
+ _assertAnnotationValueText(annotation, '''
+A<int>
+ f: int 42
+''');
+ assertElement2(
+ findNode.integerLiteral('42').staticParameterElement,
+ declaration: findElement.fieldFormalParameter('f'),
+ substitution: {'T': 'int'},
+ );
+ }
+
+ test_value_genericClass_typeArguments_unnamedConstructor() async {
+ await assertNoErrorsInCode(r'''
+ class A<T> {
+ final T f;
+ const A(this.f);
+}
+
+@A<int>(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ element: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: int}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+''');
+ _assertAnnotationValueText(annotation, r'''
+A<int>
+ f: int 42
+''');
+ assertElement2(
+ findNode.integerLiteral('42').staticParameterElement,
+ declaration: findElement.fieldFormalParameter('f'),
+ substitution: {'T': 'int'},
+ );
+ }
+
+ test_value_genericClass_unnamedConstructor_noGenericMetadata() async {
+ writeTestPackageConfig(PackageConfigFileBuilder(), languageVersion: '2.12');
+ await assertNoErrorsInCode(r'''
+class A<T> {
+ final T f;
+ const A(this.f);
+}
+
+@A(42)
+void f() {}
+''');
+
+ var annotation = findNode.annotation('@A');
+ _assertResolvedNodeText(annotation, r'''
+Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 42
+ staticType: int
+ element: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: dynamic}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+''');
+ _assertAnnotationValueText(annotation, r'''
+A<dynamic>
+ f: int 42
+''');
+ assertElement2(
+ findNode.integerLiteral('42').staticParameterElement,
+ declaration: findElement.fieldFormalParameter('f'),
+ substitution: {'T': 'dynamic'},
+ );
+ }
+
+ test_value_otherLibrary_implicitConst() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+ final int f;
+ const A(this.f);
+}
+
+class B {
+ final A a;
+ const B(this.a);
+}
+
+@B( A(42) )
+class C {}
+''');
+
+ await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+void f(C c) {}
+''');
+
+ var classC = findNode.typeName('C c').name.staticElement!;
+ var annotation = classC.metadata.single;
+ _assertElementAnnotationValueText(annotation, r'''
+B
+ a: A
+ f: int 42
+''');
+ }
+
+ test_value_otherLibrary_namedConstructor() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+ final int f;
+ const A.named(this.f);
+}
+''');
+
+ newFile('$testPackageLibPath/b.dart', content: r'''
+import 'a.dart';
+
+@A.named(42)
+class B {}
+''');
+
+ await assertNoErrorsInCode(r'''
+import 'b.dart';
+
+void f(B b) {}
+''');
+
+ var classB = findNode.typeName('B b').name.staticElement!;
+ var annotation = classB.metadata.single;
+ _assertElementAnnotationValueText(annotation, r'''
+A
+ f: int 42
+''');
+ }
+
+ test_value_otherLibrary_unnamedConstructor() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+class A {
+ final int f;
+ const A(this.f);
+}
+''');
+
+ newFile('$testPackageLibPath/b.dart', content: r'''
+import 'a.dart';
+
+@A(42)
+class B {}
+''');
+
+ await assertNoErrorsInCode(r'''
+import 'b.dart';
+
+void f(B b) {}
+''');
+
+ var classB = findNode.typeName('B b').name.staticElement!;
+ var annotation = classB.metadata.single;
+ _assertElementAnnotationValueText(annotation, r'''
+A
+ f: int 42
+''');
+ }
+
+ void _assertAnnotationValueText(Annotation annotation, String expected) {
+ var elementAnnotation = annotation.elementAnnotation!;
+ _assertElementAnnotationValueText(elementAnnotation, expected);
+ }
+
+ void _assertDartObjectText(DartObject? object, String expected) {
+ var buffer = StringBuffer();
+ _DartObjectPrinter(buffer).write(object as DartObjectImpl?, '');
+ var actual = buffer.toString();
+ if (actual != expected) {
+ print(buffer);
+ }
+ expect(actual, expected);
+ }
+
+ void _assertElementAnnotationValueText(
+ ElementAnnotation annotation,
+ String expected,
+ ) {
+ var value = annotation.computeConstantValue();
+ _assertDartObjectText(value, expected);
+ }
+
+ void _assertResolvedNodeText(AstNode node, String expected) {
+ var actual = _resolvedNodeText(node);
+ if (actual != expected) {
+ print(actual);
+ }
+ expect(actual, expected);
+ }
+
+ String _resolvedNodeText(AstNode node) {
+ var buffer = StringBuffer();
+ node.accept(
+ ResolvedAstPrinter(
+ selfUriStr: result.uri.toString(),
+ sink: buffer,
+ indent: '',
+ ),
+ );
+ return buffer.toString();
+ }
+}
+
+class _DartObjectPrinter {
+ final StringBuffer sink;
+
+ _DartObjectPrinter(this.sink);
+
+ void write(DartObjectImpl? object, String indent) {
+ if (object != null) {
+ var type = object.type;
+ if (type.isDartCoreInt) {
+ sink.write('int ');
+ sink.writeln(object.toIntValue());
+ } else if (object.isUserDefinedObject) {
+ var newIndent = '$indent ';
+ var typeStr = type.getDisplayString(withNullability: true);
+ sink.writeln(typeStr);
+ var fields = object.fields;
+ if (fields != null) {
+ for (var entry in fields.entries) {
+ sink.write(newIndent);
+ sink.write('${entry.key}: ');
+ write(entry.value, newIndent);
+ }
+ }
+ } else {
+ throw UnimplementedError();
+ }
+ } else {
+ sink.writeln('<null>');
+ }
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
index 1795ae3..a72d21b 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_annotation_test.dart
@@ -15,6 +15,45 @@
@reflectiveTest
class InvalidAnnotationTest extends PubPackageResolutionTest {
+ test_class_noUnnamedConstructor() async {
+ await assertErrorsInCode(r'''
+class A {
+ const A.named();
+}
+
+@A
+void f() {}
+''', [
+ error(CompileTimeErrorCode.INVALID_ANNOTATION, 32, 2),
+ ]);
+ }
+
+ test_class_staticMethod() async {
+ await assertErrorsInCode(r'''
+class A {
+ static int foo() => 0;
+}
+
+@A.foo
+void f() {}
+''', [
+ error(CompileTimeErrorCode.INVALID_ANNOTATION, 38, 6),
+ ]);
+ }
+
+ test_class_staticMethod_arguments() async {
+ await assertErrorsInCode(r'''
+class A {
+ static int foo() => 0;
+}
+
+@A.foo()
+void f() {}
+''', [
+ error(CompileTimeErrorCode.INVALID_ANNOTATION, 38, 8),
+ ]);
+ }
+
test_getter() async {
await assertErrorsInCode(r'''
get V => 0;
@@ -129,6 +168,28 @@
]);
}
+ test_prefix_function() async {
+ await assertErrorsInCode(r'''
+import 'dart:math' as p;
+
+@p.sin(0)
+class B {}
+''', [
+ error(CompileTimeErrorCode.INVALID_ANNOTATION, 26, 9),
+ ]);
+ }
+
+ test_prefix_function_unresolved() async {
+ await assertErrorsInCode(r'''
+import 'dart:math' as p;
+
+@p.sin.cos(0)
+class B {}
+''', [
+ error(CompileTimeErrorCode.INVALID_ANNOTATION, 26, 13),
+ ]);
+ }
+
test_staticMethodReference() async {
await assertErrorsInCode(r'''
class A {
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
index 711ac51..b8c6202 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_annotation_test.dart
@@ -45,6 +45,26 @@
]);
}
+ test_unresolved_prefix() async {
+ await assertErrorsInCode(r'''
+@p.A(0)
+class B {}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 0, 7),
+ ]);
+ }
+
+ test_unresolved_prefixed() async {
+ await assertErrorsInCode(r'''
+import 'dart:math' as p;
+
+@p.A(0)
+class B {}
+''', [
+ error(CompileTimeErrorCode.UNDEFINED_ANNOTATION, 26, 7),
+ ]);
+ }
+
test_unresolved_prefixedIdentifier() async {
await assertErrorsInCode(r'''
import 'dart:math' as p;
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 3b4f286..b90d591 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -71,6 +71,7 @@
_writeNode('constructorName', node.constructorName);
_writeElement('element', node.element);
_writeNode('name', node.name);
+ _writeNode('typeArguments', node.typeArguments);
});
}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index ece3d72..470764b 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:pub_semver/pub_semver.dart';
@@ -40,6 +41,11 @@
sourceFactory = SourceFactory(
[
DartUriResolver(sdk),
+ PackageMapUriResolver(resourceProvider, {
+ 'test': [
+ resourceProvider.getFolder('/home/test/lib'),
+ ],
+ }),
ResourceUriResolver(resourceProvider),
],
);
@@ -60,8 +66,9 @@
Source addSource(String path, String contents) {
var file = newFile(path, content: contents);
- var source = file.createSource();
- return source;
+ var fileSource = file.createSource();
+ var uri = sourceFactory.restoreUri(fileSource)!;
+ return sourceFactory.forUri2(uri)!;
}
Source addTestSource(String code, [Uri? uri]) {
@@ -88,6 +95,11 @@
sdkLanguageVersion: Version.parse('2.12.0'),
flags: [EnableString.nonfunction_type_aliases],
);
+
+ static final FeatureSet genericMetadata = FeatureSet.fromEnableFlags2(
+ sdkLanguageVersion: Version.parse('2.13.0'),
+ flags: [EnableString.generic_metadata],
+ );
}
/// Mixin containing test cases exercising summary resynthesis. Intended to be
@@ -9068,46 +9080,81 @@
}
test_invalid_annotation_prefixed_constructor() async {
- addLibrarySource('/a.dart', r'''
-class C {
- const C.named();
+ testFile = convertPath('/home/test/lib/test.dart');
+ addLibrarySource('/home/test/lib/a.dart', r'''
+class A {
+ const A.named();
}
''');
var library = await checkLibrary('''
import "a.dart" as a;
-@a.C.named
-class D {}
+@a.A.named
+class C {}
''');
- checkElementText(library, r'''
-import 'a.dart' as a;
-@
- a/*location: test.dart;a*/.
- C/*location: a.dart;C*/.
- named/*location: a.dart;C;named*/
-class D {
+ checkElementText(
+ library,
+ r'''
+import 'package:test/a.dart' as a;
+class C {
}
-''');
+ metadata
+ Annotation
+ constructorName: SimpleIdentifier
+ staticElement: package:test/a.dart::@class::A::@constructor::named
+ staticType: null
+ token: named
+ element: package:test/a.dart::@class::A::@constructor::named
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+ token: A
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::a
+ staticType: null
+ token: a
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+''',
+ withFullyResolvedAst: true);
}
test_invalid_annotation_unprefixed_constructor() async {
- addLibrarySource('/a.dart', r'''
-class C {
- const C.named();
+ testFile = convertPath('/home/test/lib/test.dart');
+ addLibrarySource('/home/test/lib/a.dart', r'''
+class A {
+ const A.named();
}
''');
var library = await checkLibrary('''
import "a.dart";
-@C.named
-class D {}
+@A.named
+class C {}
''');
- checkElementText(library, r'''
-import 'a.dart';
-@
- C/*location: a.dart;C*/.
- named/*location: a.dart;C;named*/
-class D {
+ checkElementText(
+ library,
+ r'''
+import 'package:test/a.dart';
+class C {
}
-''');
+ metadata
+ Annotation
+ element: package:test/a.dart::@class::A::@constructor::named
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/a.dart::@class::A::@constructor::named
+ staticType: null
+ token: named
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+ token: A
+ staticElement: package:test/a.dart::@class::A::@constructor::named
+ staticType: null
+''',
+ withFullyResolvedAst: true);
}
test_invalid_importPrefix_asTypeArgument() async {
@@ -9615,41 +9662,347 @@
}
test_metadata_constructor_call_named() async {
+ testFile = convertPath('/home/test/lib/test.dart');
var library = await checkLibrary('''
class A {
- const A.named();
+ const A.named(int _);
}
-@A.named()
+@A.named(0)
class C {}
''');
- checkElementText(library, r'''
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A.named(int _);
+}
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ element: self::@class::A::@constructor::named
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: self::@class::A::@constructor::named
+ staticType: null
+ token: named
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: self::@class::A::@constructor::named
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_named_generic_inference() async {
+ featureSet = FeatureSets.genericMetadata;
+ var library = await checkLibrary('''
+class A<T> {
+ const A.named(T _);
+}
+
+@A.named(0)
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A.named(T _);
+}
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ element: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+ token: named
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_named_generic_typeArguments() async {
+ featureSet = FeatureSets.genericMetadata;
+ var library = await checkLibrary('''
+class A<T> {
+ const A.named();
+}
+
+@A<int>.named()
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
class A {
const A.named();
}
-@
- A/*location: test.dart;A*/.
- named/*location: test.dart;A;named*/()
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
class C {
}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ constructorName: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+ token: named
+ element: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: int}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_named_generic_typeArguments_disabledGenericMetadata() async {
+ var library = await checkLibrary('''
+class A<T> {
+ const A.named();
+}
+
+@A<int>.named()
+class C {}
''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A.named();
+}
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ constructorName: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: dynamic}
+ staticType: null
+ token: named
+ element: ConstructorMember
+ base: self::@class::A::@constructor::named
+ substitution: {T: dynamic}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+''',
+ withFullyResolvedAst: true);
}
test_metadata_constructor_call_named_prefixed() async {
- addLibrarySource('/foo.dart', 'class A { const A.named(); }');
- var library = await checkLibrary('''
-import 'foo.dart' as foo;
-@foo.A.named()
-class C {}
-''');
- checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
- foo/*location: test.dart;foo*/.
- A/*location: foo.dart;A*/.
- named/*location: foo.dart;A;named*/()
-class C {
+ testFile = convertPath('/home/test/lib/test.dart');
+ addLibrarySource('/home/test/lib/foo.dart', '''
+class A {
+ const A.named(int _);
}
''');
+ var library = await checkLibrary('''
+import 'foo.dart' as foo;
+@foo.A.named(0)
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ constructorName: SimpleIdentifier
+ staticElement: package:test/foo.dart::@class::A::@constructor::named
+ staticType: null
+ token: named
+ element: package:test/foo.dart::@class::A::@constructor::named
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ token: A
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::foo
+ staticType: null
+ token: foo
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_named_prefixed_generic_inference() async {
+ featureSet = FeatureSets.genericMetadata;
+ addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+ const A.named(T _);
+}
+''');
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A.named(0)
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ constructorName: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: package:test/foo.dart::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+ token: named
+ element: ConstructorMember
+ base: package:test/foo.dart::@class::A::@constructor::named
+ substitution: {T: int}
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ token: A
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::foo
+ staticType: null
+ token: foo
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_named_prefixed_generic_typeArguments() async {
+ featureSet = FeatureSets.genericMetadata;
+ addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+ const A.named();
+}
+''');
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A<int>.named()
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ constructorName: SimpleIdentifier
+ staticElement: ConstructorMember
+ base: package:test/foo.dart::@class::A::@constructor::named
+ substitution: {T: int}
+ staticType: null
+ token: named
+ element: ConstructorMember
+ base: package:test/foo.dart::@class::A::@constructor::named
+ substitution: {T: int}
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ token: A
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::foo
+ staticType: null
+ token: foo
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+''',
+ withFullyResolvedAst: true);
}
test_metadata_constructor_call_named_synthetic_ofClassAlias_generic() async {
@@ -9660,7 +10013,7 @@
mixin B {}
-class C<T> = A with B;
+class C<T> = A with B;
@C.named()
class D {}
@@ -9709,30 +10062,249 @@
}
test_metadata_constructor_call_unnamed() async {
- var library = await checkLibrary('class A { const A(); } @A() class C {}');
- checkElementText(library, r'''
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+class A {
+ const A(int _);
+}
+@A(0)
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A(int _);
+}
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ element: self::@class::A::@constructor::•
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_unnamed_generic_inference() async {
+ featureSet = FeatureSets.genericMetadata;
+ var library = await checkLibrary('''
+class A<T> {
+ const A(T _);
+}
+
+@A(0)
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ const A(T _);
+}
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ element: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: int}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_unnamed_generic_typeArguments() async {
+ featureSet = FeatureSets.genericMetadata;
+ var library = await checkLibrary('''
+class A<T> {
+ const A();
+}
+
+@A<int>()
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
class A {
const A();
}
-@
- A/*location: test.dart;A*/()
+ typeParameters
+ T
+ bound: null
+ defaultType: dynamic
class C {
}
-''');
+ metadata
+ Annotation
+ arguments: ArgumentList
+ element: ConstructorMember
+ base: self::@class::A::@constructor::•
+ substitution: {T: int}
+ name: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+''',
+ withFullyResolvedAst: true);
}
test_metadata_constructor_call_unnamed_prefixed() async {
- addLibrarySource('/foo.dart', 'class A { const A(); }');
+ testFile = convertPath('/home/test/lib/test.dart');
+ addLibrarySource('/home/test/lib/foo.dart', 'class A { const A(_); }');
var library =
- await checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
- checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
- foo/*location: test.dart;foo*/.
- A/*location: foo.dart;A*/()
+ await checkLibrary('import "foo.dart" as foo; @foo.A(0) class C {}');
+ checkElementText(
+ library,
+ r'''
+import 'package:test/foo.dart' as foo;
class C {
}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ element: package:test/foo.dart::@class::A::@constructor::•
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ token: A
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::foo
+ staticType: null
+ token: foo
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_unnamed_prefixed_generic_inference() async {
+ featureSet = FeatureSets.genericMetadata;
+ addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+ const A(T _);
+}
''');
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A(0)
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ arguments
+ IntegerLiteral
+ literal: 0
+ staticType: int
+ element: ConstructorMember
+ base: package:test/foo.dart::@class::A::@constructor::•
+ substitution: {T: int}
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ token: A
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::foo
+ staticType: null
+ token: foo
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_constructor_call_unnamed_prefixed_generic_typeArguments() async {
+ featureSet = FeatureSets.genericMetadata;
+ addLibrarySource('/home/test/lib/foo.dart', '''
+class A<T> {
+ const A();
+}
+''');
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+import "foo.dart" as foo;
+@foo.A<int>()
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+ metadata
+ Annotation
+ arguments: ArgumentList
+ element: ConstructorMember
+ base: package:test/foo.dart::@class::A::@constructor::•
+ substitution: {T: int}
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ token: A
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::foo
+ staticType: null
+ token: foo
+ staticElement: package:test/foo.dart::@class::A
+ staticType: null
+ typeArguments: TypeArgumentList
+ arguments
+ TypeName
+ name: SimpleIdentifier
+ staticElement: dart:core::@class::int
+ staticType: null
+ token: int
+ type: int
+''',
+ withFullyResolvedAst: true);
}
test_metadata_constructor_call_unnamed_synthetic_ofClassAlias_generic() async {
@@ -9743,7 +10315,7 @@
mixin B {}
-class C<T> = A with B;
+class C<T> = A with B;
@C()
class D {}
@@ -10427,6 +10999,166 @@
''');
}
+ test_metadata_value_class_staticField() async {
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+class A {
+ static const x = 0;
+}
+@A.x
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+class A {
+ static const int x;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+}
+class C {
+}
+ metadata
+ Annotation
+ element: self::@class::A::@getter::x
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: self::@class::A::@getter::x
+ staticType: null
+ token: x
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@class::A
+ staticType: null
+ token: A
+ staticElement: self::@class::A::@getter::x
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_value_enum_constant() async {
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+enum E {a, b, c}
+@E.b
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+enum E {
+ synthetic final int index;
+ synthetic static const List<E> values;
+ static const E a;
+ static const E b;
+ static const E c;
+ String toString() {}
+}
+class C {
+}
+ metadata
+ Annotation
+ element: self::@enum::E::@getter::b
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: self::@enum::E::@getter::b
+ staticType: null
+ token: b
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@enum::E
+ staticType: null
+ token: E
+ staticElement: self::@enum::E::@getter::b
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_value_extension_staticField() async {
+ testFile = convertPath('/home/test/lib/test.dart');
+ var library = await checkLibrary('''
+extension E on int {
+ static const x = 0;
+}
+@E.x
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+class C {
+}
+ metadata
+ Annotation
+ element: self::@extension::E::@getter::x
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: self::@extension::E::@getter::x
+ staticType: null
+ token: x
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@extension::E
+ staticType: null
+ token: E
+ staticElement: self::@extension::E::@getter::x
+ staticType: null
+extension E on int {
+ static const int x;
+ constantInitializer
+ IntegerLiteral
+ literal: 0
+ staticType: int
+}
+''',
+ withFullyResolvedAst: true);
+ }
+
+ test_metadata_value_prefix_extension_staticField() async {
+ testFile = convertPath('/home/test/lib/test.dart');
+ addLibrarySource('/home/test/lib/foo.dart', '''
+extension E on int {
+ static const x = 0;
+}
+''');
+ var library = await checkLibrary('''
+import 'foo.dart' as foo;
+@foo.E.x
+class C {}
+''');
+ checkElementText(
+ library,
+ r'''
+import 'package:test/foo.dart' as foo;
+class C {
+}
+ metadata
+ Annotation
+ constructorName: SimpleIdentifier
+ staticElement: package:test/foo.dart::@extension::E::@getter::x
+ staticType: null
+ token: x
+ element: package:test/foo.dart::@extension::E::@getter::x
+ name: PrefixedIdentifier
+ identifier: SimpleIdentifier
+ staticElement: package:test/foo.dart::@extension::E
+ staticType: null
+ token: E
+ period: .
+ prefix: SimpleIdentifier
+ staticElement: self::@prefix::foo
+ staticType: null
+ token: foo
+ staticElement: package:test/foo.dart::@extension::E
+ staticType: null
+''',
+ withFullyResolvedAst: true);
+ }
+
test_method_documented() async {
var library = await checkLibrary('''
class C {
@@ -10595,6 +11327,18 @@
''');
}
+ test_mixin_first() async {
+ var library = await checkLibrary(r'''
+mixin M {}
+''');
+
+ // We intentionally ask `mixins` directly, to check that we can ask them
+ // separately, without asking classes.
+ var mixins = library.definingCompilationUnit.mixins;
+ expect(mixins, hasLength(1));
+ expect(mixins[0].name, 'M');
+ }
+
test_mixin_implicitObjectSuperclassConstraint() async {
var library = await checkLibrary(r'''
mixin M {}
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 150398a..c021511 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -104,6 +104,19 @@
expect(excludes, unorderedEquals(['foo/bar.dart', 'test/**']));
}
+ test_configure_excludes_withNonStrings() {
+ configureContext('''
+analyzer:
+ exclude:
+ - foo/bar.dart
+ - 'test/**'
+ - a: b
+''');
+
+ List<String> excludes = analysisOptions.excludePatterns;
+ expect(excludes, unorderedEquals(['foo/bar.dart', 'test/**']));
+ }
+
test_configure_plugins_list() {
configureContext('''
analyzer:
diff --git a/pkg/analyzer/test/src/workspace/bazel_test.dart b/pkg/analyzer/test/src/workspace/bazel_test.dart
index fe83186..3e22df8 100644
--- a/pkg/analyzer/test/src/workspace/bazel_test.dart
+++ b/pkg/analyzer/test/src/workspace/bazel_test.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
@@ -11,7 +9,6 @@
import 'package:async/async.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:watcher/watcher.dart';
import '../../generated/test_support.dart';
@@ -811,120 +808,6 @@
class BazelWorkspaceTest with ResourceProviderMixin {
late final BazelWorkspace workspace;
- void test_bazelFileWatcher() async {
- _addResources([
- '/workspace/WORKSPACE',
- ]);
- late _MockTimer timer;
- var timerFactory = (Duration _, void Function(Timer) callback) {
- timer = _MockTimer(callback);
- return timer;
- };
- var candidates = [
- convertPath('/workspace/bazel-bin/my/module/test1.dart'),
- convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
- ];
- var watcher = BazelFileWatcher(candidates, resourceProvider, Duration.zero,
- Duration.zero, timerFactory);
- var events = StreamQueue(watcher.events);
- watcher.start();
-
- // First do some tests with the first candidate path.
- _addResources([candidates[0]]);
- timer.triggerCallback();
-
- var event = await events.next;
- expect(event.type, ChangeType.ADD);
- expect(event.path, candidates[0]);
-
- modifyFile(candidates[0], 'const foo = 42;');
- timer.triggerCallback();
-
- event = await events.next;
- expect(event.type, ChangeType.MODIFY);
- expect(event.path, candidates[0]);
-
- _deleteResources([candidates[0]]);
- timer.triggerCallback();
-
- event = await events.next;
- expect(event.type, ChangeType.REMOVE);
- expect(event.path, candidates[0]);
-
- // Now check that if we add the *second* candidate, we'll get the
- // notification for it.
- _addResources([candidates[1]]);
- timer.triggerCallback();
-
- event = await events.next;
- expect(event.type, ChangeType.ADD);
- expect(event.path, candidates[1]);
-
- watcher.stop();
- expect(await events.rest.isEmpty, true);
- }
-
- void test_bazelFileWatcher_existingFile() async {
- _addResources([
- '/workspace/WORKSPACE',
- '/workspace/bazel-bin/my/module/test1.dart',
- ]);
- var workspace = BazelWorkspace.find(
- resourceProvider, convertPath('/workspace/my/module'))!;
- late _MockTimer timer;
- var timerFactory = (Duration _, void Function(Timer) callback) {
- timer = _MockTimer(callback);
- return timer;
- };
- var watcherCompleter = Completer<BazelFileWatcher>();
- workspace.bazelCandidateFiles.listen((notification) =>
- watcherCompleter.complete(notification.watcher(
- pollingDelayLong: Duration.zero,
- pollingDelayShort: Duration.zero,
- timerFactory: timerFactory)));
-
- var file1 =
- workspace.findFile(convertPath('/workspace/my/module/test1.dart'))!;
- expect(file1.exists, true);
- var watcher = await watcherCompleter.future;
- var events = StreamQueue(watcher.events);
- watcher.start();
-
- // Make sure that triggering the callback, will not generate extra events.
- timer.triggerCallback();
-
- var convertedPath =
- convertPath('/workspace/bazel-bin/my/module/test1.dart');
-
- // Change the file -- we should get a single MODIFY event and not an ADD
- // event, since the file already existed.
- modifyFile(convertedPath, 'const foo = 42;');
- timer.triggerCallback();
- var event = await events.next;
-
- expect(event.type, ChangeType.MODIFY);
- expect(event.path, convertedPath);
-
- // But if we delete the file and then re-create it, we should get an ADD
- // event (after the REMOVE one).
- deleteFile(convertedPath);
- timer.triggerCallback();
- event = await events.next;
-
- expect(event.type, ChangeType.REMOVE);
- expect(event.path, convertedPath);
-
- newFile(convertedPath);
- timer.triggerCallback();
- event = await events.next;
-
- expect(event.type, ChangeType.ADD);
- expect(event.path, convertedPath);
-
- watcher.stop();
- expect(await events.rest.isEmpty, true);
- }
-
void test_bazelNotifications() async {
_addResources([
'/workspace/WORKSPACE',
@@ -937,20 +820,22 @@
var file1 =
workspace.findFile(convertPath('/workspace/my/module/test1.dart'))!;
expect(file1.exists, true);
- var notification = await notifications.next;
- expect(notification.requested, convertPath('my/module/test1.dart'));
+ var info = await notifications.next;
+ expect(info.requestedPath, convertPath('my/module/test1.dart'));
expect(
- notification.candidates,
- containsAll(
- [convertPath('/workspace/bazel-bin/my/module/test1.dart')]));
+ info.candidatePaths,
+ containsAll([
+ convertPath('/workspace/bazel-bin/my/module/test1.dart'),
+ convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
+ ]));
var file2 =
workspace.findFile(convertPath('/workspace/my/module/test2.dart'))!;
expect(file2.exists, false);
- notification = await notifications.next;
- expect(notification.requested, convertPath('my/module/test2.dart'));
+ info = await notifications.next;
+ expect(info.requestedPath, convertPath('my/module/test2.dart'));
expect(
- notification.candidates,
+ info.candidatePaths,
containsAll([
convertPath('/workspace/bazel-bin/my/module/test2.dart'),
convertPath('/workspace/bazel-genfiles/my/module/test2.dart'),
@@ -1205,17 +1090,6 @@
}
}
- /// Create new files and directories from [paths].
- void _deleteResources(List<String> paths) {
- for (String path in paths) {
- if (path.endsWith('/')) {
- deleteFolder(path.substring(0, path.length - 1));
- } else {
- deleteFile(path);
- }
- }
- }
-
/// Expect that [BazelWorkspace.findFile], given [path], returns [equals].
void _expectFindFile(String path, {required String equals}) =>
expect(workspace.findFile(convertPath(path))!.path, convertPath(equals));
@@ -1232,20 +1106,3 @@
throw StateError('Unexpected invocation of ${invocation.memberName}');
}
}
-
-class _MockTimer implements Timer {
- final void Function(Timer) callback;
-
- @override
- bool isActive = true;
-
- _MockTimer(this.callback);
-
- @override
- int get tick => throw UnimplementedError();
-
- @override
- void cancel() => isActive = false;
-
- void triggerCallback() => callback(this);
-}
diff --git a/pkg/analyzer/test/src/workspace/bazel_watcher_test.dart b/pkg/analyzer/test/src/workspace/bazel_watcher_test.dart
new file mode 100644
index 0000000..5d9f119
--- /dev/null
+++ b/pkg/analyzer/test/src/workspace/bazel_watcher_test.dart
@@ -0,0 +1,269 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:isolate';
+
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/bazel_watcher.dart';
+import 'package:async/async.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:watcher/watcher.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(BazelWatcherTest);
+ });
+}
+
+@reflectiveTest
+class BazelWatcherTest with ResourceProviderMixin {
+ late final BazelWorkspace workspace;
+
+ void test_bazelFileWatcher() async {
+ _addResources([
+ '/workspace/WORKSPACE',
+ ]);
+ var candidates = [
+ convertPath('/workspace/bazel-bin/my/module/test1.dart'),
+ convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
+ ];
+ var watcher = BazelFilePoller(resourceProvider, candidates);
+
+ // First do some tests with the first candidate path.
+ _addResources([candidates[0]]);
+
+ var event = watcher.poll()!;
+
+ expect(event.type, ChangeType.ADD);
+ expect(event.path, candidates[0]);
+
+ modifyFile(candidates[0], 'const foo = 42;');
+
+ event = watcher.poll()!;
+
+ expect(event.type, ChangeType.MODIFY);
+ expect(event.path, candidates[0]);
+
+ _deleteResources([candidates[0]]);
+
+ event = watcher.poll()!;
+
+ expect(event.type, ChangeType.REMOVE);
+ expect(event.path, candidates[0]);
+
+ // Now check that if we add the *second* candidate, we'll get the
+ // notification for it.
+ _addResources([candidates[1]]);
+
+ event = watcher.poll()!;
+
+ expect(event.type, ChangeType.ADD);
+ expect(event.path, candidates[1]);
+
+ // Next poll should be `null` since there were no changes.
+ expect(watcher.poll(), isNull);
+ }
+
+ void test_bazelFileWatcherIsolate() async {
+ _addResources([
+ '/workspace/WORKSPACE',
+ ]);
+ var candidates1 = [
+ convertPath('/workspace/bazel-bin/my/module/test1.dart'),
+ convertPath('/workspace/bazel-genfiles/my/module/test1.dart'),
+ ];
+ var candidates2 = [
+ convertPath('/workspace/bazel-bin/my/module/test2.dart'),
+ convertPath('/workspace/bazel-genfiles/my/module/test2.dart'),
+ ];
+ var trigger = _MockPollTrigger();
+ var recPort = ReceivePort();
+ // Note that we provide below a dummy `ReceivePort` that will *not* be used.
+ // We'll directly call `handleRequest` to avoid any problems with various
+ // interleavings of async functions.
+ var dummyRecPort = ReceivePort();
+ var watcher = BazelFileWatcherIsolate(
+ dummyRecPort, recPort.sendPort, resourceProvider,
+ pollTriggerFactory: (_) => trigger)
+ ..start();
+ var queue = StreamQueue(recPort);
+
+ await queue.next as BazelWatcherIsolateStarted;
+
+ watcher.handleRequest(BazelWatcherStartWatching(
+ convertPath('/workspace'),
+ BazelSearchInfo(
+ convertPath('/workspace/my/module/test1.dart'), candidates1)));
+ watcher.handleRequest(BazelWatcherStartWatching(
+ convertPath('/workspace'),
+ BazelSearchInfo(
+ convertPath('/workspace/my/module/test2.dart'), candidates2)));
+
+ // First do some tests with the first candidate path.
+ _addResources([candidates1[0]]);
+
+ trigger.controller.add('');
+ var events = (await queue.next as BazelWatcherEvents).events;
+
+ expect(events, hasLength(1));
+ expect(events[0].path, candidates1[0]);
+ expect(events[0].type, ChangeType.ADD);
+
+ // Now let's take a look at the second file.
+ _addResources([candidates2[1]]);
+
+ trigger.controller.add('');
+ events = (await queue.next as BazelWatcherEvents).events;
+
+ expect(events, hasLength(1));
+ expect(events[0].path, candidates2[1]);
+ expect(events[0].type, ChangeType.ADD);
+
+ expect(watcher.numWatchedFiles(), 2);
+
+ watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace'),
+ convertPath('/workspace/my/module/test1.dart')));
+
+ expect(watcher.numWatchedFiles(), 1);
+
+ watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace'),
+ convertPath('/workspace/my/module/test2.dart')));
+
+ expect(watcher.numWatchedFiles(), 0);
+
+ watcher.handleRequest(BazelWatcherShutdownIsolate());
+ await watcher.hasFinished;
+
+ // We need to do this manually, since it's the callers responsibility to
+ // close this port (the one owned by `watcher` should've been closed when
+ // handling the "shutdown" request).
+ recPort.close();
+ }
+
+ void test_bazelFileWatcherIsolate_multipleWorkspaces() async {
+ _addResources([
+ '/workspace1/WORKSPACE',
+ '/workspace2/WORKSPACE',
+ ]);
+ var candidates1 = [
+ convertPath('/workspace1/bazel-bin/my/module/test1.dart'),
+ convertPath('/workspace1/bazel-genfiles/my/module/test1.dart'),
+ ];
+ var candidates2 = [
+ convertPath('/workspace2/bazel-bin/my/module/test2.dart'),
+ convertPath('/workspace2/bazel-genfiles/my/module/test2.dart'),
+ ];
+ _MockPollTrigger? trigger1;
+ _MockPollTrigger? trigger2;
+ var triggerFactory = (String workspace) {
+ if (workspace == '/workspace1') {
+ trigger1 = _MockPollTrigger();
+ return trigger1!;
+ } else if (workspace == '/workspace2') {
+ trigger2 = _MockPollTrigger();
+ return trigger2!;
+ } else {
+ throw ArgumentError('Got unexpected workspace: `$workspace`');
+ }
+ };
+ var recPort = ReceivePort();
+ // Note that we provide below a dummy `ReceivePort` that will *not* be used.
+ // We'll directly call `handleRequest` to avoid any problems with various
+ // interleavings of async functions.
+ var dummyRecPort = ReceivePort();
+ var watcher = BazelFileWatcherIsolate(
+ dummyRecPort, recPort.sendPort, resourceProvider,
+ pollTriggerFactory: triggerFactory)
+ ..start();
+ var queue = StreamQueue(recPort);
+
+ await queue.next as BazelWatcherIsolateStarted;
+
+ watcher.handleRequest(BazelWatcherStartWatching(
+ convertPath('/workspace1'),
+ BazelSearchInfo(
+ convertPath('/workspace1/my/module/test1.dart'), candidates1)));
+ watcher.handleRequest(BazelWatcherStartWatching(
+ convertPath('/workspace2'),
+ BazelSearchInfo(
+ convertPath('/workspace2/my/module/test2.dart'), candidates2)));
+
+ // First do some tests with the first candidate path.
+ _addResources([candidates1[0]]);
+
+ trigger1!.controller.add('');
+ var events = (await queue.next as BazelWatcherEvents).events;
+
+ expect(events, hasLength(1));
+ expect(events[0].path, candidates1[0]);
+ expect(events[0].type, ChangeType.ADD);
+
+ // Now let's take a look at the second file.
+ _addResources([candidates2[1]]);
+
+ trigger2!.controller.add('');
+ events = (await queue.next as BazelWatcherEvents).events;
+
+ expect(events, hasLength(1));
+ expect(events[0].path, candidates2[1]);
+ expect(events[0].type, ChangeType.ADD);
+
+ expect(watcher.numWatchedFiles(), 2);
+
+ watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace1'),
+ convertPath('/workspace1/my/module/test1.dart')));
+
+ expect(watcher.numWatchedFiles(), 1);
+
+ watcher.handleRequest(BazelWatcherStopWatching(convertPath('/workspace2'),
+ convertPath('/workspace2/my/module/test2.dart')));
+
+ expect(watcher.numWatchedFiles(), 0);
+
+ watcher.handleRequest(BazelWatcherShutdownIsolate());
+ await watcher.hasFinished;
+
+ // We need to do this manually, since it's the callers responsibility to
+ // close this port (the one owned by `watcher` should've been closed when
+ // handling the "shutdown" request).
+ recPort.close();
+ }
+
+ /// Create new files and directories from [paths].
+ void _addResources(List<String> paths) {
+ for (String path in paths) {
+ if (path.endsWith('/')) {
+ newFolder(path.substring(0, path.length - 1));
+ } else {
+ newFile(path);
+ }
+ }
+ }
+
+ /// Create new files and directories from [paths].
+ void _deleteResources(List<String> paths) {
+ for (String path in paths) {
+ if (path.endsWith('/')) {
+ deleteFolder(path.substring(0, path.length - 1));
+ } else {
+ deleteFile(path);
+ }
+ }
+ }
+}
+
+class _MockPollTrigger implements PollTrigger {
+ final controller = StreamController<Object>();
+
+ @override
+ Stream<Object> get stream => controller.stream;
+
+ @override
+ void cancel() {
+ return;
+ }
+}
diff --git a/pkg/analyzer/test/src/workspace/test_all.dart b/pkg/analyzer/test/src/workspace/test_all.dart
index edf5bd0..dc1b496 100644
--- a/pkg/analyzer/test/src/workspace/test_all.dart
+++ b/pkg/analyzer/test/src/workspace/test_all.dart
@@ -6,6 +6,7 @@
import 'basic_test.dart' as basic;
import 'bazel_test.dart' as bazel;
+import 'bazel_watcher_test.dart' as bazel_watcher;
import 'gn_test.dart' as gn;
import 'package_build_test.dart' as package_build;
import 'pub_test.dart' as pub;
@@ -14,6 +15,7 @@
defineReflectiveSuite(() {
basic.main();
bazel.main();
+ bazel_watcher.main();
gn.main();
package_build.main();
pub.main();
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index 768e479..52db9f4 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1579,6 +1579,18 @@
The one-based index of the column containing the first character of
the range.
</p>
+ </dd><dt class="field"><b>endLine: int</b></dt><dd>
+
+ <p>
+ The one-based index of the line containing the character immediately
+ following the range.
+ </p>
+ </dd><dt class="field"><b>endColumn: int</b></dt><dd>
+
+ <p>
+ The one-based index of the column containing the character immediately
+ following the range.
+ </p>
</dd></dl></dd><dt class="typeDefinition"><a name="type_NavigationRegion">NavigationRegion: object</a></dt><dd>
<p>
A description of a region from which the user can navigate to the
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 5dbc101..78e0b32 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -3495,6 +3495,8 @@
/// "length": int
/// "startLine": int
/// "startColumn": int
+/// "endLine": int
+/// "endColumn": int
/// }
///
/// Clients may not extend, implement or mix-in this class.
@@ -3509,6 +3511,10 @@
int _startColumn;
+ int _endLine;
+
+ int _endColumn;
+
/// The file containing the range.
String get file => _file;
@@ -3558,13 +3564,37 @@
_startColumn = value;
}
- Location(
- String file, int offset, int length, int startLine, int startColumn) {
+ /// The one-based index of the line containing the character immediately
+ /// following the range.
+ int get endLine => _endLine;
+
+ /// The one-based index of the line containing the character immediately
+ /// following the range.
+ set endLine(int value) {
+ assert(value != null);
+ _endLine = value;
+ }
+
+ /// The one-based index of the column containing the character immediately
+ /// following the range.
+ int get endColumn => _endColumn;
+
+ /// The one-based index of the column containing the character immediately
+ /// following the range.
+ set endColumn(int value) {
+ assert(value != null);
+ _endColumn = value;
+ }
+
+ Location(String file, int offset, int length, int startLine, int startColumn,
+ int endLine, int endColumn) {
this.file = file;
this.offset = offset;
this.length = length;
this.startLine = startLine;
this.startColumn = startColumn;
+ this.endLine = endLine;
+ this.endColumn = endColumn;
}
factory Location.fromJson(
@@ -3603,7 +3633,21 @@
} else {
throw jsonDecoder.mismatch(jsonPath, 'startColumn');
}
- return Location(file, offset, length, startLine, startColumn);
+ int endLine;
+ if (json.containsKey('endLine')) {
+ endLine = jsonDecoder.decodeInt(jsonPath + '.endLine', json['endLine']);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, 'endLine');
+ }
+ int endColumn;
+ if (json.containsKey('endColumn')) {
+ endColumn =
+ jsonDecoder.decodeInt(jsonPath + '.endColumn', json['endColumn']);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, 'endColumn');
+ }
+ return Location(
+ file, offset, length, startLine, startColumn, endLine, endColumn);
} else {
throw jsonDecoder.mismatch(jsonPath, 'Location', json);
}
@@ -3617,6 +3661,8 @@
result['length'] = length;
result['startLine'] = startLine;
result['startColumn'] = startColumn;
+ result['endLine'] = endLine;
+ result['endColumn'] = endColumn;
return result;
}
@@ -3630,7 +3676,9 @@
offset == other.offset &&
length == other.length &&
startLine == other.startLine &&
- startColumn == other.startColumn;
+ startColumn == other.startColumn &&
+ endLine == other.endLine &&
+ endColumn == other.endColumn;
}
return false;
}
@@ -3643,6 +3691,8 @@
hash = JenkinsSmiHash.combine(hash, length.hashCode);
hash = JenkinsSmiHash.combine(hash, startLine.hashCode);
hash = JenkinsSmiHash.combine(hash, startColumn.hashCode);
+ hash = JenkinsSmiHash.combine(hash, endLine.hashCode);
+ hash = JenkinsSmiHash.combine(hash, endColumn.hashCode);
return JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
index cc0e5b8..03e3ac4 100644
--- a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
+++ b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
@@ -29,12 +29,18 @@
var offset = error.offset;
var startLine = -1;
var startColumn = -1;
+ var endLine = -1;
+ var endColumn = -1;
if (lineInfo != null) {
- var lineLocation =
- lineInfo.getLocation(offset) as analyzer.CharacterLocation;
- if (lineLocation != null) {
- startLine = lineLocation.lineNumber;
- startColumn = lineLocation.columnNumber;
+ var startLocation = lineInfo.getLocation(offset);
+ if (startLocation != null) {
+ startLine = startLocation.lineNumber;
+ startColumn = startLocation.columnNumber;
+ }
+ var endLocation = lineInfo.getLocation(offset + error.length);
+ if (endLocation != null) {
+ endLine = endLocation.lineNumber;
+ endColumn = endLocation.columnNumber;
}
}
List<plugin.DiagnosticMessage> contextMessages;
@@ -48,7 +54,7 @@
convertErrorSeverity(severity),
convertErrorType(errorCode.type),
plugin.Location(error.source.fullName, offset, error.length, startLine,
- startColumn),
+ startColumn, endLine, endColumn),
error.message,
errorCode.name.toLowerCase(),
contextMessages: contextMessages,
@@ -94,16 +100,24 @@
var length = message.length;
var startLine = -1;
var startColumn = -1;
+ var endLine = -1;
+ var endColumn = -1;
if (lineInfo != null) {
- var lineLocation =
- lineInfo.getLocation(offset) as analyzer.CharacterLocation;
+ var lineLocation = lineInfo.getLocation(offset);
if (lineLocation != null) {
startLine = lineLocation.lineNumber;
startColumn = lineLocation.columnNumber;
}
+ var endLocation = lineInfo.getLocation(offset + length);
+ if (endLocation != null) {
+ endLine = endLocation.lineNumber;
+ endColumn = endLocation.columnNumber;
+ }
}
- return plugin.DiagnosticMessage(message.message,
- plugin.Location(file, offset, length, startLine, startColumn));
+ return plugin.DiagnosticMessage(
+ message.message,
+ plugin.Location(
+ file, offset, length, startLine, startColumn, endLine, endColumn));
}
/// Convert the given [element] from the 'analyzer' package to an element
@@ -382,18 +396,24 @@
analyzer.CompilationUnitElement unitElement, analyzer.SourceRange range) {
var startLine = 0;
var startColumn = 0;
+ var endLine = 0;
+ var endColumn = 0;
try {
var lineInfo = unitElement.lineInfo;
if (lineInfo != null) {
- var offsetLocation =
- lineInfo.getLocation(range.offset) as analyzer.CharacterLocation;
+ var offsetLocation = lineInfo.getLocation(range.offset);
startLine = offsetLocation.lineNumber;
startColumn = offsetLocation.columnNumber;
}
+ var endLocation = lineInfo.getLocation(range.offset + range.length);
+ if (endLocation != null) {
+ endLine = endLocation.lineNumber;
+ endColumn = endLocation.columnNumber;
+ }
} on analyzer.AnalysisException {
// Ignore exceptions
}
return plugin.Location(unitElement.source.fullName, range.offset,
- range.length, startLine, startColumn);
+ range.length, startLine, startColumn, endLine, endColumn);
}
}
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 1fe66bc..1a8fcb0 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -227,7 +227,7 @@
uriNode.offset,
uriNode.length,
protocol.ElementKind.LIBRARY,
- protocol.Location(source.fullName, 0, 0, 0, 0));
+ protocol.Location(source.fullName, 0, 0, 0, 0, 0, 0));
}
}
super.visitConfiguration(node);
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index e00577b..308bad8 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -589,13 +589,17 @@
/// "length": int
/// "startLine": int
/// "startColumn": int
+/// "endLine": int
+/// "endColumn": int
/// }
final Matcher isLocation = LazyMatcher(() => MatchesJsonObject('Location', {
'file': isFilePath,
'offset': isInt,
'length': isInt,
'startLine': isInt,
- 'startColumn': isInt
+ 'startColumn': isInt,
+ 'endLine': isInt,
+ 'endColumn': isInt
}));
/// NavigationRegion
diff --git a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
index 9763b14..0fde341 100644
--- a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
@@ -80,7 +80,8 @@
void computeNavigation(
NavigationRequest request, NavigationCollector collector) {
for (var i = 0; i < regionCount; i++) {
- collector.addRegion(i, 5, ElementKind.METHOD, Location('a', 5, 5, 1, 5));
+ collector.addRegion(
+ i, 5, ElementKind.METHOD, Location('a', 5, 5, 1, 5, 1, 10));
}
}
}
diff --git a/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart b/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
index de76c3c..45179b0 100644
--- a/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/navigation/navigation_test.dart
@@ -24,14 +24,14 @@
var targetStartColumnA1 = 4;
var targetKindA1 = ElementKind.CLASS;
var targetLocationA1 = Location(fileA, targetOffsetA1, targetLengthA1,
- targetStartLineA1, targetStartColumnA1);
+ targetStartLineA1, targetStartColumnA1, 0, 0);
var targetOffsetA2 = 5;
var targetLengthA2 = 6;
var targetStartLineA2 = 7;
var targetStartColumnA2 = 8;
var targetKindA2 = ElementKind.FUNCTION;
var targetLocationA2 = Location(fileA, targetOffsetA2, targetLengthA2,
- targetStartLineA2, targetStartColumnA2);
+ targetStartLineA2, targetStartColumnA2, 0, 0);
var fileB = 'b.dart';
var targetOffsetB1 = 9;
@@ -40,14 +40,14 @@
var targetStartColumnB1 = 12;
var targetKindB1 = ElementKind.ENUM;
var targetLocationB1 = Location(fileB, targetOffsetB1, targetLengthB1,
- targetStartLineB1, targetStartColumnB1);
+ targetStartLineB1, targetStartColumnB1, 0, 0);
var targetOffsetB2 = 13;
var targetLengthB2 = 14;
var targetStartLineB2 = 15;
var targetStartColumnB2 = 16;
var targetKindB2 = ElementKind.METHOD;
var targetLocationB2 = Location(fileB, targetOffsetB2, targetLengthB2,
- targetStartLineB2, targetStartColumnB2);
+ targetStartLineB2, targetStartColumnB2, 0, 0);
// Six regions targeting a1, b1, a2, b1, a1, b2
var regionOffsets = <int>[17, 18, 19, 20, 21, 22];
@@ -112,7 +112,7 @@
var targetStartLine = 5;
var targetStartColumn = 1;
var targetLocation = Location(targetFile, targetOffset, targetLength,
- targetStartLine, targetStartColumn);
+ targetStartLine, targetStartColumn, 0, 0);
collector.addRegion(regionOffset, regionLength, targetKind, targetLocation);
collector.createRegions();
expect(collector.files, [targetFile]);
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index 984b617..adadbe5 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -1056,6 +1056,20 @@
the range.
</p>
</field>
+ <field name="endLine">
+ <ref>int</ref>
+ <p>
+ The one-based index of the line containing the character immediately
+ following the range.
+ </p>
+ </field>
+ <field name="endColumn">
+ <ref>int</ref>
+ <p>
+ The one-based index of the column containing the character immediately
+ following the range.
+ </p>
+ </field>
</object>
</type>
<type name="NavigationRegion">
diff --git a/pkg/dev_compiler/lib/src/js_ast/printer.dart b/pkg/dev_compiler/lib/src/js_ast/printer.dart
index 9fabc56..c6d7581 100644
--- a/pkg/dev_compiler/lib/src/js_ast/printer.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/printer.dart
@@ -7,7 +7,7 @@
// ignore_for_file: slash_for_doc_comments, unnecessary_const
// ignore_for_file: always_declare_return_types, prefer_single_quotes
// ignore_for_file: prefer_collection_literals, omit_local_variable_types
-// ignore_for_file: prefer_generic_function_type_aliases, prefer_final_fields
+// ignore_for_file: prefer_final_fields
// ignore_for_file: use_function_type_syntax_for_parameters
part of js_ast;
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index 2a4517c..3236e1e 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -28,6 +28,7 @@
path: ../vm
dev_dependencies:
+ browser_launcher: ^0.1.5
expect:
path: ../expect
js:
@@ -42,3 +43,5 @@
test: any
testing:
path: ../testing
+ webkit_inspection_protocol: ^0.7.4
+
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_test.dart
new file mode 100644
index 0000000..bacd973
--- /dev/null
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_test.dart
@@ -0,0 +1,548 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+library dev_compiler.test.expression_compiler;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io' show Directory, File, Platform;
+
+import 'package:browser_launcher/browser_launcher.dart' as browser;
+import 'package:cli_util/cli_util.dart';
+import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/compiler/module_builder.dart';
+import 'package:dev_compiler/src/kernel/command.dart';
+import 'package:dev_compiler/src/kernel/module_metadata.dart';
+import 'package:front_end/src/api_unstable/ddc.dart' as fe;
+import 'package:front_end/src/compute_platform_binaries_location.dart' as fe;
+import 'package:front_end/src/fasta/incremental_serializer.dart' as fe;
+import 'package:kernel/ast.dart' show Component, Library;
+import 'package:kernel/target/targets.dart';
+import 'package:path/path.dart' as p;
+import 'package:source_maps/parser.dart' as source_maps;
+import 'package:source_maps/source_maps.dart' as source_maps;
+import 'package:test/test.dart';
+import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'
+ as wip;
+
+class DevelopmentIncrementalCompiler extends fe.IncrementalCompiler {
+ Uri entryPoint;
+
+ DevelopmentIncrementalCompiler(fe.CompilerOptions options, this.entryPoint,
+ [Uri initializeFrom,
+ bool outlineOnly,
+ fe.IncrementalSerializer incrementalSerializer])
+ : super(
+ fe.CompilerContext(
+ fe.ProcessedOptions(options: options, inputs: [entryPoint])),
+ initializeFrom,
+ outlineOnly,
+ incrementalSerializer);
+
+ DevelopmentIncrementalCompiler.fromComponent(fe.CompilerOptions options,
+ this.entryPoint, Component componentToInitializeFrom,
+ [bool outlineOnly, fe.IncrementalSerializer incrementalSerializer])
+ : super.fromComponent(
+ fe.CompilerContext(
+ fe.ProcessedOptions(options: options, inputs: [entryPoint])),
+ componentToInitializeFrom,
+ outlineOnly,
+ incrementalSerializer);
+}
+
+class SetupCompilerOptions {
+ static final sdkRoot = fe.computePlatformBinariesLocation();
+ static final sdkUnsoundSummaryPath = p.join(sdkRoot.path, 'ddc_sdk.dill');
+ static final sdkSoundSummaryPath =
+ p.join(sdkRoot.path, 'ddc_outline_sound.dill');
+ static final librariesSpecificationUri =
+ p.join(p.dirname(p.dirname(getSdkPath())), 'libraries.json');
+ static final String dartUnsoundComment = '// @dart = 2.9';
+ static final String dartSoundComment = '//';
+
+ final String dartLangComment;
+ final List<String> errors = [];
+ final List<String> diagnosticMessages = [];
+ final ModuleFormat moduleFormat;
+ final fe.CompilerOptions options;
+ final bool soundNullSafety;
+
+ static fe.CompilerOptions _getOptions(bool soundNullSafety) {
+ var options = fe.CompilerOptions()
+ ..verbose = false // set to true for debugging
+ ..sdkRoot = sdkRoot
+ ..target = DevCompilerTarget(TargetFlags())
+ ..librariesSpecificationUri = Uri.base.resolve('sdk/lib/libraries.json')
+ ..omitPlatform = true
+ ..sdkSummary = sdkRoot.resolve(
+ soundNullSafety ? sdkSoundSummaryPath : sdkUnsoundSummaryPath)
+ ..environmentDefines = const {}
+ ..nnbdMode = soundNullSafety ? fe.NnbdMode.Strong : fe.NnbdMode.Weak;
+ return options;
+ }
+
+ SetupCompilerOptions(
+ {this.soundNullSafety = true, this.moduleFormat = ModuleFormat.amd})
+ : options = _getOptions(soundNullSafety),
+ dartLangComment =
+ soundNullSafety ? dartSoundComment : dartUnsoundComment {
+ options.onDiagnostic = (fe.DiagnosticMessage m) {
+ diagnosticMessages.addAll(m.plainTextFormatted);
+ if (m.severity == fe.Severity.error) {
+ errors.addAll(m.plainTextFormatted);
+ }
+ };
+ }
+}
+
+class TestCompilationResult {
+ final String result;
+ final bool isSuccess;
+
+ TestCompilationResult(this.result, this.isSuccess);
+}
+
+class TestCompiler {
+ final SetupCompilerOptions setup;
+ Component component;
+ ExpressionCompiler evaluator;
+ ModuleMetadata metadata;
+ source_maps.SingleMapping sourceMap;
+
+ TestCompiler(this.setup);
+
+ Future<TestCompiler> init({Uri input, Uri output, Uri packages}) async {
+ // Initialize the incremental compiler and module component.
+ // TODO: extend this for multi-module compilations by storing separate
+ // compilers/components/names per module.
+ setup.options.packagesFileUri = packages;
+
+ var compiler = DevelopmentIncrementalCompiler(setup.options, input);
+ component = await compiler.computeDelta();
+ component.computeCanonicalNames();
+
+ // Initialize DDC.
+ var moduleName = '${p.basenameWithoutExtension(output.toFilePath())}';
+
+ var classHierarchy = compiler.getClassHierarchy();
+ var compilerOptions = SharedCompilerOptions(
+ replCompile: true,
+ moduleName: moduleName,
+ soundNullSafety: setup.soundNullSafety);
+ var coreTypes = compiler.getCoreTypes();
+
+ final importToSummary = Map<Library, Component>.identity();
+ final summaryToModule = Map<Component, String>.identity();
+ for (var lib in component.libraries) {
+ importToSummary[lib] = component;
+ }
+ summaryToModule[component] = moduleName;
+
+ var kernel2jsCompiler = ProgramCompiler(component, classHierarchy,
+ compilerOptions, importToSummary, summaryToModule,
+ coreTypes: coreTypes);
+ var module = kernel2jsCompiler.emitModule(component);
+
+ // Perform a full compile, writing the compiled JS + sourcemap.
+ var code = jsProgramToCode(
+ module,
+ setup.moduleFormat,
+ inlineSourceMap: true,
+ buildSourceMap: true,
+ emitDebugMetadata: true,
+ jsUrl: '$output',
+ mapUrl: '$output.map',
+ component: component,
+ );
+ metadata = code.metadata;
+ sourceMap = source_maps.SingleMapping.fromJson(code.sourceMap);
+ var codeBytes = utf8.encode(code.code);
+ var sourceMapBytes = utf8.encode(json.encode(code.sourceMap));
+
+ File('${output.toFilePath()}').writeAsBytesSync(codeBytes);
+ File('${output.toFilePath()}.map').writeAsBytesSync(sourceMapBytes);
+
+ // Save the expression evaluator for future evaluations.
+ evaluator = ExpressionCompiler(
+ setup.options,
+ setup.moduleFormat,
+ setup.errors,
+ compiler,
+ kernel2jsCompiler,
+ component,
+ );
+
+ if (setup.errors.isNotEmpty) {
+ throw Exception('Compilation failed with: ${setup.errors}');
+ }
+ setup.diagnosticMessages.clear();
+
+ return this;
+ }
+
+ Future<TestCompilationResult> compileExpression(
+ {Uri input,
+ int line,
+ int column,
+ Map<String, String> scope,
+ String expression}) async {
+ var libraryUri = metadataForLibraryUri(input);
+ var jsExpression = await evaluator.compileExpressionToJs(
+ libraryUri.importUri, line, column, scope, expression);
+ if (setup.errors.isNotEmpty) {
+ jsExpression = setup.errors.toString().replaceAll(
+ RegExp(
+ r'org-dartlang-debug:synthetic_debug_expression:[0-9]*:[0-9]*:'),
+ '');
+
+ return TestCompilationResult(jsExpression, false);
+ }
+
+ return TestCompilationResult(jsExpression, true);
+ }
+
+ LibraryMetadata metadataForLibraryUri(Uri libraryUri) =>
+ metadata.libraries.entries
+ .firstWhere((entry) => entry.value.fileUri == '$libraryUri')
+ .value;
+}
+
+class TestDriver {
+ SetupCompilerOptions setup;
+ String source;
+ Directory chromeDir;
+ Directory testDir;
+ String moduleFormatString;
+ Uri htmlBootstrapper;
+ Uri input;
+ Uri output;
+ Uri packagesFile;
+ browser.Chrome chrome;
+ wip.WipDebugger debugger;
+ wip.WipConnection connection;
+ TestCompiler compiler;
+
+ TestDriver._();
+
+ static Future<TestDriver> init(SetupCompilerOptions setup) async {
+ var driver = TestDriver._();
+ await driver.initChrome();
+ return driver;
+ }
+
+ /// Initializes a Chrome browser instance, tab connection, and debugger.
+ ///
+ /// Should be called once after creating TestDriver.
+ void initChrome() async {
+ // Create a temporary directory for holding Chrome tests.
+ var systemTempDir = Directory.systemTemp;
+ chromeDir = await systemTempDir.createTemp('ddc_eval_test_anchor');
+
+ // Start Chrome on an empty page with a single empty tab.
+ chrome = await browser.Chrome.startWithDebugPort(['about:blank'],
+ userDataDir: chromeDir.path, headless: true);
+
+ // Connect to the first 'normal' tab.
+ var tab = await chrome.chromeConnection
+ .getTab((tab) => !tab.isBackgroundPage && !tab.isChromeExtension);
+ connection = await tab.connect();
+ debugger = (await connection).debugger;
+ }
+
+ /// Must be called when testing a new Dart program.
+ ///
+ /// Depends on SDK artifacts (such as the sound and unsound dart_sdk.js
+ /// files) generated from the 'dartdevc_test' target.
+ void initSource(SetupCompilerOptions setup, String source) async {
+ this.setup = setup;
+ this.source = source;
+ testDir = await chromeDir.createTemp('ddc_eval_test');
+ var buildDir = p.dirname(p.dirname(p.dirname(Platform.resolvedExecutable)));
+ var scriptPath =
+ Platform.script.normalizePath().toFilePath(windows: Platform.isWindows);
+ var ddcPath = p.dirname(p.dirname(p.dirname(scriptPath)));
+ output = testDir.uri.resolve('test.js');
+ input = testDir.uri.resolve('test.dart');
+ File.fromUri(input)
+ ..createSync()
+ ..writeAsStringSync(source);
+
+ packagesFile = testDir.uri.resolve('package_config.json');
+ File.fromUri(packagesFile)
+ ..createSync()
+ ..writeAsStringSync('''
+ {
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "eval_test",
+ "rootUri": "./",
+ "packageUri": "./"
+ }
+ ]
+ }
+ ''');
+
+ // Initialize DDC and the incremental compiler, then perform a full compile.
+ compiler = await TestCompiler(setup)
+ .init(input: input, output: output, packages: packagesFile);
+
+ htmlBootstrapper = testDir.uri.resolve('bootstrapper.html');
+ var bootstrapFile = File.fromUri(htmlBootstrapper)..createSync();
+ var moduleName = compiler.metadata.name;
+ var mainLibraryName = compiler.metadataForLibraryUri(input).name;
+
+ switch (setup.moduleFormat) {
+ case ModuleFormat.ddc:
+ moduleFormatString = 'ddc';
+ var dartSdkPath = p.join(
+ buildDir,
+ 'gen',
+ 'utils',
+ 'dartdevc',
+ setup.soundNullSafety ? 'sound' : 'kernel',
+ 'legacy',
+ 'dart_sdk.js');
+ var dartLibraryPath =
+ p.join(ddcPath, 'lib', 'js', 'legacy', 'dart_library.js');
+ bootstrapFile.writeAsStringSync('''
+<script src='$dartLibraryPath'></script>
+<script src='$dartSdkPath'></script>
+<script src='${p.absolute(output.path)}'></script>
+<script>
+ 'use strict';
+ var sound = ${setup.soundNullSafety};
+ var sdk = dart_library.import('dart_sdk');
+
+ if (!sound) {
+ sdk.dart.weakNullSafetyWarnings(false);
+ sdk.dart.weakNullSafetyErrors(false);
+ }
+ sdk.dart.nonNullAsserts(true);
+ sdk.dart.nativeNonNullAsserts(true);
+ sdk._debugger.registerDevtoolsFormatter();
+ dart_library.start('$moduleName', '$mainLibraryName');
+</script>
+''');
+ break;
+ case ModuleFormat.amd:
+ moduleFormatString = 'amd';
+ var dartSdkPath = p.join(buildDir, 'gen', 'utils', 'dartdevc',
+ setup.soundNullSafety ? 'sound' : 'kernel', 'amd', 'dart_sdk');
+ var requirePath = p.join(buildDir, 'dart-sdk', 'lib', 'dev_compiler',
+ 'kernel', 'amd', 'require.js');
+ bootstrapFile.writeAsStringSync('''
+<script src='$requirePath'></script>
+<script>
+ require.config({
+ paths: {
+ 'dart_sdk': '$dartSdkPath',
+ '$moduleName': '${p.withoutExtension(p.absolute(output.path))}'
+ },
+ waitSeconds: 15
+ });
+ var sound = ${setup.soundNullSafety};
+
+ require(['dart_sdk', '$moduleName'],
+ function(sdk, app) {
+ 'use strict';
+
+ if (!sound) {
+ sdk.dart.weakNullSafetyWarnings(false);
+ sdk.dart.weakNullSafetyErrors(false);
+ }
+ sdk.dart.nonNullAsserts(true);
+ sdk.dart.nativeNonNullAsserts(true);
+ sdk._debugger.registerDevtoolsFormatter();
+ app.$mainLibraryName.main([]);
+ });
+</script>
+''');
+ break;
+ default:
+ throw Exception(
+ 'Unsupported module format for SDK evaluation tests: ${setup.moduleFormat}');
+ }
+
+ await debugger.enable();
+
+ // Pause as soon as the test file loads but before it executes.
+ var urlRegex = '.*${libraryUriToJsIdentifier(output)}.*';
+ await debugger.sendCommand('Debugger.setBreakpointByUrl', params: {
+ 'urlRegex': urlRegex,
+ 'lineNumber': 0,
+ });
+ }
+
+ void finish() {
+ chrome?.close();
+ chromeDir?.deleteSync(recursive: true);
+ }
+
+ void cleanupTest() async {
+ setup.diagnosticMessages.clear();
+ setup.errors.clear();
+ await debugger.disable();
+ }
+
+ void check(
+ {String breakpointId,
+ String expression,
+ String expectedError,
+ String expectedResult}) async {
+ assert(expectedError == null || expectedResult == null,
+ 'Cannot expect both an error and result.');
+
+ var subs = <StreamSubscription>[];
+ final controller = StreamController<wip.DebuggerPausedEvent>();
+ subs.add(debugger.onPaused.listen(controller.add));
+
+ // Navigate from the empty page and immediately pause on the preemptive
+ // breakpoint.
+ await connection.page.navigate('$htmlBootstrapper');
+ await Future.delayed(const Duration(seconds: 1));
+
+ // TODO: We use lastWhere since the debugger accumulates scriptIds across
+ // tests. We can use firstWhere if we clear debugger.scripts - perhaps by
+ // disabling and enabling the debugger.
+ final script = debugger.scripts.entries
+ .lastWhere((entry) => entry.value.url.endsWith('test.js'),
+ orElse: () => throw Exception(
+ 'Unable to find JS script corresponding to test file $output in ${debugger.scripts}.'))
+ .value;
+
+ // Breakpoint at the frst WIP location mapped from its Dart line.
+ var dartLine = _findBreakpointLine(breakpointId);
+ var location = await _jsLocationFromDartLine(script, dartLine);
+ var bp = await debugger.setBreakpoint(location);
+
+ // Continue to the next breakpoint, ignoring the first pause event since it
+ // corresponds to the preemptive URI breakpoint made prior to page
+ // navigation.
+ await debugger.resume();
+ final event = await controller.stream.skip(1).first;
+
+ // Retrieve the call frame and its scope variables.
+ var frame = event.getCallFrames().first;
+ var scope = await _collectScopeVariables(frame);
+
+ // Perform an incremental compile.
+ var result = await compiler.compileExpression(
+ input: input,
+ line: dartLine,
+ column: 1,
+ scope: scope,
+ expression: expression);
+
+ if (expectedError != null) {
+ expect(
+ result,
+ const TypeMatcher<TestCompilationResult>()
+ .having((r) => result.result, 'result', _matches(expectedError)));
+ setup.diagnosticMessages.clear();
+ setup.errors.clear();
+ return;
+ }
+
+ if (!result.isSuccess) {
+ throw Exception(
+ 'Unexpected expression evaluation failure:\n${result.result}');
+ }
+
+ var evalResult = await debugger.evaluateOnCallFrame(
+ frame.callFrameId, result.result,
+ returnByValue: false);
+
+ await debugger.removeBreakpoint(bp.breakpointId);
+
+ var value = evalResult.type == 'function'
+ ? evalResult.description
+ : evalResult.value;
+
+ expect(
+ result,
+ const TypeMatcher<TestCompilationResult>()
+ .having((_) => '$value', 'result', _matches(expectedResult)));
+ }
+
+ /// Collects local JS variables visible at a breakpoint during evaluation.
+ ///
+ /// Adapted from webdev/dwds/lib/src/services/expression_evaluator.dart.
+ Future<Map<String, String>> _collectScopeVariables(
+ wip.WipCallFrame frame) async {
+ var jsScope = <String, String>{};
+
+ for (var scope in filterScopes(frame)) {
+ var response = await connection.runtime
+ .getProperties(scope.object, ownProperties: true);
+ for (var prop in response) {
+ var propKey = '${prop.name}';
+ var propValue = '${prop.value.value}';
+ jsScope[propKey] = propValue == 'null' ? propKey : propValue;
+ }
+ }
+ return jsScope;
+ }
+
+ /// Used for matching error text emitted during expression evaluation.
+ Matcher _matches(String text) {
+ var unindented = RegExp.escape(text).replaceAll(RegExp('[ ]+'), '[ ]*');
+ return matches(RegExp(unindented, multiLine: true));
+ }
+
+ /// Finds the line number in [source] matching [breakpointId].
+ ///
+ /// A breakpoint ID is found by looking for a line that ends with a comment
+ /// of exactly this form: `// Breakpoint: <id>`.
+ ///
+ /// Throws if it can't find the matching line.
+ ///
+ /// Adapted from webdev/blob/master/dwds/test/fixtures/context.dart.
+ int _findBreakpointLine(String breakpointId) {
+ var lines = LineSplitter.split(source).toList();
+ var lineNumber =
+ lines.indexWhere((l) => l.endsWith('// Breakpoint: $breakpointId'));
+ if (lineNumber == -1) {
+ throw StateError(
+ 'Unable to find breakpoint in ${input} with id: $breakpointId');
+ }
+ return lineNumber + 1;
+ }
+
+ /// Finds the corresponding JS WipLocation for a given line in Dart.
+ Future<wip.WipLocation> _jsLocationFromDartLine(
+ wip.WipScript script, int dartLine) async {
+ var inputSourceUrl = input.pathSegments.last;
+ for (var lineEntry in compiler.sourceMap.lines) {
+ for (var entry in lineEntry.entries) {
+ if (entry.sourceUrlId != null &&
+ entry.sourceLine == dartLine &&
+ compiler.sourceMap.urls[entry.sourceUrlId] == inputSourceUrl) {
+ return wip.WipLocation.fromValues(script.scriptId, lineEntry.line);
+ }
+ }
+ }
+ throw StateError(
+ 'Unable to extract WIP Location from ${script.url} for Dart line $dartLine.');
+ }
+}
+
+/// Filters the provided frame scopes to those that are pertinent for Dart
+/// debugging.
+///
+/// Copied from webdev/dwds/lib/src/debugging/dart_scope.dart.
+List<wip.WipScope> filterScopes(wip.WipCallFrame frame) {
+ var scopes = frame.getScopeChain().toList();
+ // Remove outer scopes up to and including the Dart SDK.
+ while (
+ scopes.isNotEmpty && !(scopes.last.name?.startsWith('load__') ?? false)) {
+ scopes.removeLast();
+ }
+ if (scopes.isNotEmpty) scopes.removeLast();
+ return scopes;
+}
+
+void main() async => {};
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
index 3c2bd99..359b523 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
@@ -13,6 +13,6 @@
/*2:test*/ throw '>ExceptionMarker<';
// ignore: UNUSED_CATCH_CLAUSE
} on Error catch (e) {
- // ignore: EMPTY_CATCHES
+ // Ignored.
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index d2e276e..98a5aad 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -3342,6 +3342,10 @@
}
@override
+ ExecutionStatus visitBreakStatement(BreakStatement node) =>
+ new BreakStatus(node.target);
+
+ @override
ExecutionStatus visitIfStatement(IfStatement node) {
Constant condition = evaluate(node.condition);
if (condition is AbortConstant) return new AbortStatus(condition);
@@ -3403,6 +3407,15 @@
}
@override
+ ExecutionStatus visitLabeledStatement(LabeledStatement node) {
+ final ExecutionStatus status = node.body.accept(this);
+ if (status is BreakStatus && status.target == node) {
+ return const ProceedStatus();
+ }
+ return status;
+ }
+
+ @override
ExecutionStatus visitReturnStatement(ReturnStatement node) =>
new ReturnStatus(evaluate(node.expression));
@@ -3600,6 +3613,12 @@
AbortStatus(this.error);
}
+/// Status that the statement breaks out of an enclosing [LabeledStatement].
+class BreakStatus extends ExecutionStatus {
+ final LabeledStatement target;
+ BreakStatus(this.target);
+}
+
/// An intermediate result that is used within the [ConstantEvaluator].
class IntermediateValue implements Constant {
dynamic value;
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index bcf430e..a86117d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -1478,7 +1478,7 @@
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
- inferrer.flowAnalysis?.whyNotPromoted(receiver),
+ inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
element,
(type) => !type.isPotentiallyNullable));
}
@@ -1548,7 +1548,7 @@
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
- inferrer.flowAnalysis?.whyNotPromoted(receiver),
+ inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
element,
(type) => !type.isPotentiallyNullable));
_copyNonPromotionReasonToReplacement(element, replacement);
@@ -1986,7 +1986,7 @@
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
- inferrer.flowAnalysis?.whyNotPromoted(receiver),
+ inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
entry,
(type) => !type.isPotentiallyNullable));
_copyNonPromotionReasonToReplacement(entry, problem);
@@ -2006,7 +2006,7 @@
1,
context: inferrer.getWhyNotPromotedContext(
receiver,
- inferrer.flowAnalysis?.whyNotPromoted(receiver),
+ inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
entry,
(type) => !type.isPotentiallyNullable));
_copyNonPromotionReasonToReplacement(entry, problem);
@@ -2117,7 +2117,7 @@
messageNullableSpreadError, receiver.fileOffset, 1,
context: inferrer.getWhyNotPromotedContext(
receiver,
- inferrer.flowAnalysis?.whyNotPromoted(receiver),
+ inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
entry,
(type) => !type.isPotentiallyNullable));
_copyNonPromotionReasonToReplacement(entry, keyError);
@@ -4878,7 +4878,7 @@
propertyName.text.length,
context: inferrer.getWhyNotPromotedContext(
receiver,
- inferrer.flowAnalysis?.whyNotPromoted(receiver),
+ inferrer.flowAnalysis?.whyNotPromoted(receiver)(),
read,
(type) => !type.isPotentiallyNullable));
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index fe251d2..d754099 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -627,7 +627,7 @@
declaredContextType ?? contextType, isNonNullableByDefault),
context: getWhyNotPromotedContext(
expression,
- flowAnalysis?.whyNotPromoted(expression),
+ flowAnalysis?.whyNotPromoted(expression)(),
expression,
(type) => typeSchemaEnvironment.isSubtypeOf(type,
contextType, SubtypeCheckMode.withNullabilities)));
@@ -2838,7 +2838,7 @@
// }
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
- flowAnalysis?.whyNotPromoted(receiver),
+ flowAnalysis?.whyNotPromoted(receiver)(),
staticInvocation,
(type) => !type.isPotentiallyNullable);
result = wrapExpressionInferenceResultInProblem(
@@ -2870,7 +2870,7 @@
if (!isTopLevel && target.isNullable) {
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
- flowAnalysis?.whyNotPromoted(receiver),
+ flowAnalysis?.whyNotPromoted(receiver)(),
staticInvocation,
(type) => !type.isPotentiallyNullable);
if (isImplicitCall) {
@@ -2969,7 +2969,7 @@
if (!isTopLevel && target.isNullableCallFunction) {
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
- flowAnalysis?.whyNotPromoted(receiver),
+ flowAnalysis?.whyNotPromoted(receiver)(),
expression,
(type) => !type.isPotentiallyNullable);
if (isImplicitCall) {
@@ -3144,7 +3144,7 @@
if (!isTopLevel && target.isNullable) {
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
- flowAnalysis?.whyNotPromoted(receiver),
+ flowAnalysis?.whyNotPromoted(receiver)(),
expression,
(type) => !type.isPotentiallyNullable);
if (isImplicitCall) {
@@ -3305,7 +3305,7 @@
// }
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
- flowAnalysis?.whyNotPromoted(receiver),
+ flowAnalysis?.whyNotPromoted(receiver)(),
invocationResult.expression,
(type) => !type.isPotentiallyNullable);
invocationResult = wrapExpressionInferenceResultInProblem(
@@ -3411,7 +3411,7 @@
receiver = _hoist(receiver, receiverType, hoistedExpressions);
}
- Map<DartType, NonPromotionReason> whyNotPromotedInfo;
+ Map<DartType, NonPromotionReason> Function() whyNotPromotedInfo;
if (!isTopLevel && target.isNullable) {
// We won't report the error until later (after we have an
// invocationResult), but we need to gather "why not promoted" info now,
@@ -3502,7 +3502,7 @@
// in this scenario?
List<LocatedMessage> context = getWhyNotPromotedContext(
receiver,
- whyNotPromotedInfo,
+ whyNotPromotedInfo(),
invocationResult.expression,
(type) => !type.isPotentiallyNullable);
invocationResult = wrapExpressionInferenceResultInProblem(
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 342696f..0863ec7 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -412,6 +412,7 @@
faced
factor
factored
+fairly
fangorn
fasta
favored
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart
index bfc8001..6b365ed 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart
@@ -4,8 +4,6 @@
// Tests for statements for const functions.
-// SharedOptions=--enable-experiment=const-functions
-
import "package:expect/expect.dart";
const var1 = fn(2);
@@ -37,10 +35,58 @@
}
}
+const var6 = fnContinue();
+int fnContinue() {
+ int a = 0;
+ for (int i = 0; i < 5; i++) {
+ if (i % 2 == 1) continue;
+ a += i;
+ }
+ return a;
+}
+
+const var7 = fnBreak(2);
+const var8 = fnBreak(3);
+int fnBreak(int a) {
+ int b = a;
+ for (int i = 0; i < 2; i++) {
+ if (b == 2) break;
+ b += a;
+ }
+ return b;
+}
+
+const var9 = fnNestedFor();
+int fnNestedFor() {
+ int a = 0;
+ for (;;) {
+ for (;;) {
+ break;
+ }
+ return 1;
+ }
+}
+
+const var10 = fnBreakLabel();
+int fnBreakLabel() {
+ foo:
+ for (;;) {
+ for (;;) {
+ break foo;
+ }
+ }
+ return 3;
+}
+
void main() {
Expect.equals(var1, 6);
Expect.equals(var2, 9);
Expect.equals(var3, 18);
Expect.equals(var4, 27);
Expect.equals(var5, 11);
+ Expect.equals(var6, 6);
+ Expect.equals(var7, 2);
+ Expect.equals(var8, 9);
+ Expect.equals(var9, 1);
+ Expect.equals(var10, 3);
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.expect
index 801153f..b8210ed 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.expect
@@ -10,6 +10,11 @@
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
static method fn(core::int a) → core::int {
core::int b = a;
for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
@@ -32,12 +37,57 @@
}
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1))
+ break #L1;
+ a = a.{core::num::+}(i);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ #L2:
+ for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ }
+ return b;
+}
+static method fnNestedFor() → core::int {
+ core::int a = 0;
+ for (; ; ) {
+ #L3:
+ for (; ; ) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ for (; ; ) {
+ for (; ; ) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
exp::Expect::equals(#C5, 11);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C6, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C7, 1);
+ exp::Expect::equals(#C8, 3);
}
constants {
@@ -46,4 +96,7 @@
#C3 = 18
#C4 = 27
#C5 = 11
+ #C6 = 2
+ #C7 = 1
+ #C8 = 3
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.transformed.expect
index 801153f..b8210ed 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.strong.transformed.expect
@@ -10,6 +10,11 @@
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
static method fn(core::int a) → core::int {
core::int b = a;
for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
@@ -32,12 +37,57 @@
}
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1))
+ break #L1;
+ a = a.{core::num::+}(i);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ #L2:
+ for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ }
+ return b;
+}
+static method fnNestedFor() → core::int {
+ core::int a = 0;
+ for (; ; ) {
+ #L3:
+ for (; ; ) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ for (; ; ) {
+ for (; ; ) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
exp::Expect::equals(#C5, 11);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C6, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C7, 1);
+ exp::Expect::equals(#C8, 3);
}
constants {
@@ -46,4 +96,7 @@
#C3 = 18
#C4 = 27
#C5 = 11
+ #C6 = 2
+ #C7 = 1
+ #C8 = 3
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline.expect
index b8f0c47..7c59b2e 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline.expect
@@ -8,4 +8,13 @@
int fn1(int a) {}
const var5 = fn2();
int fn2() {}
+const var6 = fnContinue();
+int fnContinue() {}
+const var7 = fnBreak(2);
+const var8 = fnBreak(3);
+int fnBreak(int a) {}
+const var9 = fnNestedFor();
+int fnNestedFor() {}
+const var10 = fnBreakLabel();
+int fnBreakLabel() {}
void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline_modelled.expect
index 5431f56..8aa5055 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.textual_outline_modelled.expect
@@ -1,11 +1,20 @@
import "package:expect/expect.dart";
const var1 = fn(2);
+const var10 = fnBreakLabel();
const var2 = fn(3);
const var3 = fn1(2);
const var4 = fn1(3);
const var5 = fn2();
+const var6 = fnContinue();
+const var7 = fnBreak(2);
+const var8 = fnBreak(3);
+const var9 = fnNestedFor();
int fn(int a) {}
int fn1(int a) {}
int fn2() {}
+int fnBreak(int a) {}
+int fnBreakLabel() {}
+int fnContinue() {}
+int fnNestedFor() {}
void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.expect
index 801153f..b8210ed 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.expect
@@ -10,6 +10,11 @@
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
static method fn(core::int a) → core::int {
core::int b = a;
for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
@@ -32,12 +37,57 @@
}
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1))
+ break #L1;
+ a = a.{core::num::+}(i);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ #L2:
+ for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ }
+ return b;
+}
+static method fnNestedFor() → core::int {
+ core::int a = 0;
+ for (; ; ) {
+ #L3:
+ for (; ; ) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ for (; ; ) {
+ for (; ; ) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
exp::Expect::equals(#C5, 11);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C6, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C7, 1);
+ exp::Expect::equals(#C8, 3);
}
constants {
@@ -46,4 +96,7 @@
#C3 = 18
#C4 = 27
#C5 = 11
+ #C6 = 2
+ #C7 = 1
+ #C8 = 3
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.outline.expect
index add1c85..b9034e2 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.outline.expect
@@ -9,11 +9,24 @@
static const field core::int var3 = self::fn1(2);
static const field core::int var4 = self::fn1(3);
static const field core::int var5 = self::fn2();
+static const field core::int var6 = self::fnContinue();
+static const field core::int var7 = self::fnBreak(2);
+static const field core::int var8 = self::fnBreak(3);
+static const field core::int var9 = self::fnNestedFor();
+static const field core::int var10 = self::fnBreakLabel();
static method fn(core::int a) → core::int
;
static method fn1(core::int a) → core::int
;
static method fn2() → core::int
;
+static method fnContinue() → core::int
+ ;
+static method fnBreak(core::int a) → core::int
+ ;
+static method fnNestedFor() → core::int
+ ;
+static method fnBreakLabel() → core::int
+ ;
static method main() → void
;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.transformed.expect
index 801153f..b8210ed 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_for_statements.dart.weak.transformed.expect
@@ -10,6 +10,11 @@
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
static const field core::int var5 = #C5;
+static const field core::int var6 = #C1;
+static const field core::int var7 = #C6;
+static const field core::int var8 = #C2;
+static const field core::int var9 = #C7;
+static const field core::int var10 = #C8;
static method fn(core::int a) → core::int {
core::int b = a;
for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
@@ -32,12 +37,57 @@
}
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ for (core::int i = 0; i.{core::num::<}(5); i = i.{core::num::+}(1))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1))
+ break #L1;
+ a = a.{core::num::+}(i);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ #L2:
+ for (core::int i = 0; i.{core::num::<}(2); i = i.{core::num::+}(1)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ }
+ return b;
+}
+static method fnNestedFor() → core::int {
+ core::int a = 0;
+ for (; ; ) {
+ #L3:
+ for (; ; ) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ for (; ; ) {
+ for (; ; ) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
exp::Expect::equals(#C5, 11);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C6, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C7, 1);
+ exp::Expect::equals(#C8, 3);
}
constants {
@@ -46,4 +96,7 @@
#C3 = 18
#C4 = 27
#C5 = 11
+ #C6 = 2
+ #C7 = 1
+ #C8 = 3
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart
index cceb2b2..5730e6e 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart
@@ -28,9 +28,64 @@
}
}
+const var5 = fnContinue();
+int fnContinue() {
+ int a = 0;
+ int i = 0;
+ while (i < 5) {
+ if (i % 2 == 1) {
+ i++;
+ continue;
+ }
+ a += i;
+ i++;
+ }
+ return a;
+}
+
+const var6 = fnBreak(2);
+const var7 = fnBreak(3);
+int fnBreak(int a) {
+ int b = a;
+ int i = 0;
+ while (i < 2) {
+ if (b == 2) break;
+ b += a;
+ i++;
+ }
+ return b;
+}
+
+const var8 = fnNestedWhile();
+int fnNestedWhile() {
+ int a = 0;
+ while (true) {
+ while (true) {
+ break;
+ }
+ return 1;
+ }
+}
+
+const var9 = fnBreakLabel();
+int fnBreakLabel() {
+ foo:
+ while (true) {
+ while (true) {
+ break foo;
+ }
+ }
+ return 3;
+}
+
void main() {
Expect.equals(var1, 6);
Expect.equals(var2, 9);
Expect.equals(var3, 18);
Expect.equals(var4, 27);
+ Expect.equals(var5, 6);
+ Expect.equals(var6, 2);
+ Expect.equals(var7, 9);
+ Expect.equals(var8, 1);
+ Expect.equals(var9, 3);
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.expect
index 9f4a00e..00d3c60 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.expect
@@ -9,6 +9,11 @@
static const field core::int var2 = #C2;
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
static method fn(core::int a) → core::int {
core::int b = a;
core::int i = 0;
@@ -26,11 +31,62 @@
return b;
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ core::int i = 0;
+ while (i.{core::num::<}(5))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1)) {
+ i = i.{core::num::+}(1);
+ break #L1;
+ }
+ a = a.{core::num::+}(i);
+ i = i.{core::num::+}(1);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ core::int i = 0;
+ #L2:
+ while (i.{core::num::<}(2)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ i = i.{core::num::+}(1);
+ }
+ return b;
+}
+static method fnNestedWhile() → core::int {
+ core::int a = 0;
+ while (true) {
+ #L3:
+ while (true) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ while (true) {
+ while (true) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C5, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C6, 1);
+ exp::Expect::equals(#C7, 3);
}
constants {
@@ -38,4 +94,7 @@
#C2 = 9
#C3 = 18
#C4 = 27
+ #C5 = 2
+ #C6 = 1
+ #C7 = 3
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.transformed.expect
index 9f4a00e..00d3c60 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.strong.transformed.expect
@@ -9,6 +9,11 @@
static const field core::int var2 = #C2;
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
static method fn(core::int a) → core::int {
core::int b = a;
core::int i = 0;
@@ -26,11 +31,62 @@
return b;
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ core::int i = 0;
+ while (i.{core::num::<}(5))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1)) {
+ i = i.{core::num::+}(1);
+ break #L1;
+ }
+ a = a.{core::num::+}(i);
+ i = i.{core::num::+}(1);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ core::int i = 0;
+ #L2:
+ while (i.{core::num::<}(2)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ i = i.{core::num::+}(1);
+ }
+ return b;
+}
+static method fnNestedWhile() → core::int {
+ core::int a = 0;
+ while (true) {
+ #L3:
+ while (true) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ while (true) {
+ while (true) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C5, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C6, 1);
+ exp::Expect::equals(#C7, 3);
}
constants {
@@ -38,4 +94,7 @@
#C2 = 9
#C3 = 18
#C4 = 27
+ #C5 = 2
+ #C6 = 1
+ #C7 = 3
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline.expect
index 2f001f7..d7a2e9b 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline.expect
@@ -6,4 +6,13 @@
const var3 = fn1(2);
const var4 = fn1(3);
int fn1(int a) {}
+const var5 = fnContinue();
+int fnContinue() {}
+const var6 = fnBreak(2);
+const var7 = fnBreak(3);
+int fnBreak(int a) {}
+const var8 = fnNestedWhile();
+int fnNestedWhile() {}
+const var9 = fnBreakLabel();
+int fnBreakLabel() {}
void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline_modelled.expect
index d2a9f6b..8134c04 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.textual_outline_modelled.expect
@@ -4,6 +4,15 @@
const var2 = fn(3);
const var3 = fn1(2);
const var4 = fn1(3);
+const var5 = fnContinue();
+const var6 = fnBreak(2);
+const var7 = fnBreak(3);
+const var8 = fnNestedWhile();
+const var9 = fnBreakLabel();
int fn(int a) {}
int fn1(int a) {}
+int fnBreak(int a) {}
+int fnBreakLabel() {}
+int fnContinue() {}
+int fnNestedWhile() {}
void main() {}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.expect
index 9f4a00e..00d3c60 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.expect
@@ -9,6 +9,11 @@
static const field core::int var2 = #C2;
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
static method fn(core::int a) → core::int {
core::int b = a;
core::int i = 0;
@@ -26,11 +31,62 @@
return b;
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ core::int i = 0;
+ while (i.{core::num::<}(5))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1)) {
+ i = i.{core::num::+}(1);
+ break #L1;
+ }
+ a = a.{core::num::+}(i);
+ i = i.{core::num::+}(1);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ core::int i = 0;
+ #L2:
+ while (i.{core::num::<}(2)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ i = i.{core::num::+}(1);
+ }
+ return b;
+}
+static method fnNestedWhile() → core::int {
+ core::int a = 0;
+ while (true) {
+ #L3:
+ while (true) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ while (true) {
+ while (true) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C5, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C6, 1);
+ exp::Expect::equals(#C7, 3);
}
constants {
@@ -38,4 +94,7 @@
#C2 = 9
#C3 = 18
#C4 = 27
+ #C5 = 2
+ #C6 = 1
+ #C7 = 3
}
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.outline.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.outline.expect
index 005f16a..8d8170d 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.outline.expect
@@ -8,9 +8,22 @@
static const field core::int var2 = self::fn(3);
static const field core::int var3 = self::fn1(2);
static const field core::int var4 = self::fn1(3);
+static const field core::int var5 = self::fnContinue();
+static const field core::int var6 = self::fnBreak(2);
+static const field core::int var7 = self::fnBreak(3);
+static const field core::int var8 = self::fnNestedWhile();
+static const field core::int var9 = self::fnBreakLabel();
static method fn(core::int a) → core::int
;
static method fn1(core::int a) → core::int
;
+static method fnContinue() → core::int
+ ;
+static method fnBreak(core::int a) → core::int
+ ;
+static method fnNestedWhile() → core::int
+ ;
+static method fnBreakLabel() → core::int
+ ;
static method main() → void
;
diff --git a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.transformed.expect b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.transformed.expect
index 9f4a00e..00d3c60 100644
--- a/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/const_functions/const_functions_while_statements.dart.weak.transformed.expect
@@ -9,6 +9,11 @@
static const field core::int var2 = #C2;
static const field core::int var3 = #C3;
static const field core::int var4 = #C4;
+static const field core::int var5 = #C1;
+static const field core::int var6 = #C5;
+static const field core::int var7 = #C2;
+static const field core::int var8 = #C6;
+static const field core::int var9 = #C7;
static method fn(core::int a) → core::int {
core::int b = a;
core::int i = 0;
@@ -26,11 +31,62 @@
return b;
}
}
+static method fnContinue() → core::int {
+ core::int a = 0;
+ core::int i = 0;
+ while (i.{core::num::<}(5))
+ #L1:
+ {
+ if(i.{core::num::%}(2).{core::num::==}(1)) {
+ i = i.{core::num::+}(1);
+ break #L1;
+ }
+ a = a.{core::num::+}(i);
+ i = i.{core::num::+}(1);
+ }
+ return a;
+}
+static method fnBreak(core::int a) → core::int {
+ core::int b = a;
+ core::int i = 0;
+ #L2:
+ while (i.{core::num::<}(2)) {
+ if(b.{core::num::==}(2))
+ break #L2;
+ b = b.{core::num::+}(a);
+ i = i.{core::num::+}(1);
+ }
+ return b;
+}
+static method fnNestedWhile() → core::int {
+ core::int a = 0;
+ while (true) {
+ #L3:
+ while (true) {
+ break #L3;
+ }
+ return 1;
+ }
+}
+static method fnBreakLabel() → core::int {
+ #L4:
+ while (true) {
+ while (true) {
+ break #L4;
+ }
+ }
+ return 3;
+}
static method main() → void {
exp::Expect::equals(#C1, 6);
exp::Expect::equals(#C2, 9);
exp::Expect::equals(#C3, 18);
exp::Expect::equals(#C4, 27);
+ exp::Expect::equals(#C1, 6);
+ exp::Expect::equals(#C5, 2);
+ exp::Expect::equals(#C2, 9);
+ exp::Expect::equals(#C6, 1);
+ exp::Expect::equals(#C7, 3);
}
constants {
@@ -38,4 +94,7 @@
#C2 = 9
#C3 = 18
#C4 = 27
+ #C5 = 2
+ #C6 = 1
+ #C7 = 3
}
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index 20e8f55..cf5fc65 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -277,7 +277,8 @@
var edit = SourceEdit(offset, configText.length, newText);
listener.addSourceFileEdit(
'enable Null Safety language feature',
- Location(packageConfigFile.path, offset, newText.length, line, 0),
+ Location(
+ packageConfigFile.path, offset, newText.length, line, 0, 0, 0),
SourceFileEdit(packageConfigFile.path, 0, edits: [edit]));
}
} on FormatException catch (e) {
@@ -598,7 +599,7 @@
var edit = SourceEdit(offset, 0, content);
listener.addSourceFileEdit(
'enable Null Safety language feature',
- Location(path, offset, content.length, line, 0),
+ Location(path, offset, content.length, line, 0, 0, 0),
SourceFileEdit(path, 0, edits: [edit]));
}
@@ -608,7 +609,7 @@
var edit = SourceEdit(offset, span.length, content);
listener.addSourceFileEdit(
'enable Null Safety language feature',
- Location(path, offset, content.length, line, 0),
+ Location(path, offset, content.length, line, 0, 0, 0),
SourceFileEdit(path, 0, edits: [edit]));
}
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 69bde9d..4e235b0 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -276,13 +276,16 @@
static Location _computeLocation(
LineInfo lineInfo, SourceEdit edit, Source source) {
- final locationInfo = lineInfo.getLocation(edit.offset);
+ final startLocation = lineInfo.getLocation(edit.offset);
+ final endLocation = lineInfo.getLocation(edit.end);
var location = Location(
source.fullName,
edit.offset,
edit.length,
- locationInfo.lineNumber,
- locationInfo.columnNumber,
+ startLocation.lineNumber,
+ startLocation.columnNumber,
+ endLocation.lineNumber,
+ endLocation.columnNumber,
);
return location;
}
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index 550cd92..313c365 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -65,7 +65,7 @@
// Add a source change for analysis_options, which has no UnitInfo.
dartfixListener.addSourceFileEdit(
'enable experiment',
- Location(analysisOptionsPath, 9, 0, 1, 9),
+ Location(analysisOptionsPath, 9, 0, 1, 9, 1, 9),
SourceFileEdit(analysisOptionsPath, 0, edits: [
SourceEdit(9, 0, '\n enable-experiment:\n - non-nullable')
]));
@@ -100,7 +100,7 @@
file.writeAsStringSync(currentContent);
dartfixListener.addSourceFileEdit(
'test change',
- Location(path, 10, 0, 1, 10),
+ Location(path, 10, 0, 1, 10, 1, 10),
SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
expect(() => site.performApply([]), throwsA(isA<StateError>()));
expect(file.readAsStringSync(), currentContent);
@@ -115,7 +115,7 @@
site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
dartfixListener.addSourceFileEdit(
'test change',
- Location(path, 10, 0, 1, 10),
+ Location(path, 10, 0, 1, 10, 1, 10),
SourceFileEdit(path, 0, edits: [
SourceEdit(10, 0, 'List args'),
SourceEdit(13, 0, '\n print(args);\n')
@@ -136,7 +136,7 @@
site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
dartfixListener.addSourceFileEdit(
'test change',
- Location(path, 10, 0, 1, 10),
+ Location(path, 10, 0, 1, 10, 1, 10),
SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
site.performApply([]);
expect(file.readAsStringSync(), 'void main(List args) {}');
@@ -159,12 +159,6 @@
equals('// comment\n\n// @dart=2.9\n\nvoid main() {}'));
}
- void test_optOutOfNullSafety_commentThenSemicolon() {
- expect(
- IncrementalPlan.optCodeOutOfNullSafety('// comment\n;\nvoid main() {}'),
- equals('// comment\n\n// @dart=2.9\n\n;\nvoid main() {}'));
- }
-
void test_optOutOfNullSafety_commentThenCode_windows() {
expect(
IncrementalPlan.optCodeOutOfNullSafety(
@@ -187,6 +181,12 @@
'// comment\n// comment\n\n// @dart=2.9\n\nimport "dart:core";'));
}
+ void test_optOutOfNullSafety_commentThenSemicolon() {
+ expect(
+ IncrementalPlan.optCodeOutOfNullSafety('// comment\n;\nvoid main() {}'),
+ equals('// comment\n\n// @dart=2.9\n\n;\nvoid main() {}'));
+ }
+
void test_optOutOfNullSafety_empty() {
expect(IncrementalPlan.optCodeOutOfNullSafety(''), equals('// @dart=2.9'));
}
@@ -388,6 +388,32 @@
expect(state.needsRerun, true);
}
+ void test_applyMigration_doNotOptOutFileNotInPathsToProcess() async {
+ final pathA = convertPath('$projectPath/lib/a.dart');
+ final pathB = convertPath('$projectPath/lib/b.dart');
+ final content = 'void main() {}';
+ await setUpMigrationInfo({pathA: content, pathB: content},
+ // Neither [pathA] nor [[pathB] should be migrated.
+ shouldBeMigratedFunction: (String path) => false,
+ pathsToProcess: [pathA]);
+ site.unitInfoMap[pathA] = UnitInfo(pathA)
+ ..diskContent = content
+ ..wasExplicitlyOptedOut = false
+ ..migrationStatus = UnitMigrationStatus.optingOut;
+ site.unitInfoMap[pathB] = UnitInfo(pathB)
+ ..diskContent = content
+ ..wasExplicitlyOptedOut = false
+ ..migrationStatus = UnitMigrationStatus.optingOut;
+ var navigationTree =
+ NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
+ site.performApply(navigationTree);
+ expect(getFile(pathA).readAsStringSync(), '''
+// @dart=2.9
+
+void main() {}''');
+ expect(getFile(pathB).readAsStringSync(), 'void main() {}');
+ }
+
void test_applyMigration_migratePreviouslyOptedOutFile() async {
final path = convertPath('$projectPath/lib/a.dart');
final content = '''
@@ -400,7 +426,7 @@
..wasExplicitlyOptedOut = true;
dartfixListener.addSourceFileEdit(
'remove DLV comment',
- Location(path, 0, 14, 1, 1),
+ Location(path, 0, 14, 1, 1, 3, 1),
SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
var navigationTree =
NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
@@ -441,7 +467,7 @@
..wasExplicitlyOptedOut = false;
dartfixListener.addSourceFileEdit(
'test change',
- Location(path, 10, 0, 1, 10),
+ Location(path, 10, 0, 1, 10, 1, 10),
SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
var navigationTree =
NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
@@ -482,32 +508,6 @@
'''));
}
- void test_applyMigration_doNotOptOutFileNotInPathsToProcess() async {
- final pathA = convertPath('$projectPath/lib/a.dart');
- final pathB = convertPath('$projectPath/lib/b.dart');
- final content = 'void main() {}';
- await setUpMigrationInfo({pathA: content, pathB: content},
- // Neither [pathA] nor [[pathB] should be migrated.
- shouldBeMigratedFunction: (String path) => false,
- pathsToProcess: [pathA]);
- site.unitInfoMap[pathA] = UnitInfo(pathA)
- ..diskContent = content
- ..wasExplicitlyOptedOut = false
- ..migrationStatus = UnitMigrationStatus.optingOut;
- site.unitInfoMap[pathB] = UnitInfo(pathB)
- ..diskContent = content
- ..wasExplicitlyOptedOut = false
- ..migrationStatus = UnitMigrationStatus.optingOut;
- var navigationTree =
- NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
- site.performApply(navigationTree);
- expect(getFile(pathA).readAsStringSync(), '''
-// @dart=2.9
-
-void main() {}''');
- expect(getFile(pathB).readAsStringSync(), 'void main() {}');
- }
-
void test_applyMigration_optOutOne_migrateAnother() async {
final pathA = convertPath('$projectPath/lib/a.dart');
final pathB = convertPath('$projectPath/lib/b.dart');
@@ -521,11 +521,11 @@
..wasExplicitlyOptedOut = false;
dartfixListener.addSourceFileEdit(
'test change',
- Location(pathA, 10, 0, 1, 10),
+ Location(pathA, 10, 0, 1, 10, 1, 10),
SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
dartfixListener.addSourceFileEdit(
'test change',
- Location(pathB, 10, 0, 1, 10),
+ Location(pathB, 10, 0, 1, 10, 1, 10),
SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
var navigationTree =
NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
@@ -559,7 +559,7 @@
..wasExplicitlyOptedOut = true;
dartfixListener.addSourceFileEdit(
'remove DLV comment',
- Location(path, 0, 14, 1, 1),
+ Location(path, 0, 14, 1, 1, 3, 1),
SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
var navigationTree =
NavigationTreeRenderer(migrationInfo, state.pathMapper).render();
diff --git a/pkg/vm_service/example/vm_service_tester.dart b/pkg/vm_service/example/vm_service_tester.dart
index 2406111..eb5158b 100644
--- a/pkg/vm_service/example/vm_service_tester.dart
+++ b/pkg/vm_service/example/vm_service_tester.dart
@@ -44,9 +44,7 @@
// ignore: unawaited_futures
process!.exitCode.then((code) => print('vm exited: ${code}'));
- // ignore: strong_mode_down_cast_composite
process!.stdout.transform(utf8.decoder).listen(print);
- // ignore: strong_mode_down_cast_composite
process!.stderr.transform(utf8.decoder).listen(print);
await Future.delayed(Duration(milliseconds: 500));
@@ -76,7 +74,6 @@
}
expect(originalJson, isNotNull, reason: 'Unrecognized event type! $json');
- // ignore: invalid_use_of_visible_for_testing_member
var instance =
createServiceObject(originalJson, const ['Event', 'Success']);
expect(instance, isNotNull,
diff --git a/pkg/vm_snapshot_analysis/CHANGELOG.md b/pkg/vm_snapshot_analysis/CHANGELOG.md
index 96e8132..b011f35 100644
--- a/pkg/vm_snapshot_analysis/CHANGELOG.md
+++ b/pkg/vm_snapshot_analysis/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 0.6.0
+
+- Update to latest args, path, meta dependency.
+
## 0.5.6
- Fix for flutter/flutter#76313 causing issues with profiles containing
WSRs serialized as smi-s instead of actual WSR objects.=
diff --git a/pkg/vm_snapshot_analysis/pubspec.yaml b/pkg/vm_snapshot_analysis/pubspec.yaml
index fdac362..5b75e91 100644
--- a/pkg/vm_snapshot_analysis/pubspec.yaml
+++ b/pkg/vm_snapshot_analysis/pubspec.yaml
@@ -1,6 +1,6 @@
name: vm_snapshot_analysis
description: Utilities for analysing AOT snapshot size.
-version: 0.5.6
+version: 0.6.0
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_snapshot_analysis
@@ -11,10 +11,10 @@
snapshot_analysis: analyse
dependencies:
- args: ^1.6.0
- path: ^1.7.0
- meta: ^1.1.8
+ args: ^2.0.0
+ path: ^1.8.0
+ meta: ^1.3.0
dev_dependencies:
- pedantic: ^1.9.0
- test: ^1.15.1
+ pedantic: ^1.11.0
+ test: ^1.16.8
diff --git a/runtime/platform/utils.cc b/runtime/platform/utils.cc
index dc10160..0799742 100644
--- a/runtime/platform/utils.cc
+++ b/runtime/platform/utils.cc
@@ -5,6 +5,7 @@
#include "platform/utils.h"
#include "platform/allocation.h"
+#include "platform/globals.h"
namespace dart {
@@ -212,31 +213,103 @@
*shift = p - 64;
}
+// This implementation is based on the public domain MurmurHash
+// version 2.0. The constants M and R have been determined
+// to work well experimentally.
+static constexpr uint32_t kStringHashM = 0x5bd1e995;
+static constexpr int kStringHashR = 24;
+
+// hash and part must be lvalues.
+#define MIX(hash, part) \
+ { \
+ (part) *= kStringHashM; \
+ (part) ^= (part) >> kStringHashR; \
+ (part) *= kStringHashM; \
+ (hash) *= kStringHashM; \
+ (hash) ^= (part); \
+ }
+
uint32_t Utils::StringHash(const char* data, int length) {
- // This implementation is based on the public domain MurmurHash
- // version 2.0. It assumes that the underlying CPU can read from
- // unaligned addresses. The constants M and R have been determined
- // to work well experimentally.
- // TODO(3158902): need to account for unaligned address access on ARM.
- const uint32_t M = 0x5bd1e995;
- const int R = 24;
int size = length;
uint32_t hash = size;
- // Mix four bytes at a time into the hash.
- const uint8_t* cursor = reinterpret_cast<const uint8_t*>(data);
- while (size >= 4) {
- uint32_t part = *reinterpret_cast<const uint32_t*>(cursor);
- part *= M;
- part ^= part >> R;
- part *= M;
- hash *= M;
- hash ^= part;
- cursor += 4;
- size -= 4;
+ auto cursor = reinterpret_cast<const uint8_t*>(data);
+
+ if (size >= kInt32Size) {
+ const intptr_t misalignment =
+ reinterpret_cast<intptr_t>(cursor) % kInt32Size;
+ if (misalignment > 0) {
+ // Stores 4-byte values starting from the start of the string to mimic
+ // the algorithm on aligned data.
+ uint32_t data_window = 0;
+
+ // Shift sizes for adjusting the data window when adding the next aligned
+ // piece of data.
+ const uint32_t sr = misalignment * kBitsPerByte;
+ const uint32_t sl = kBitsPerInt32 - sr;
+
+ const intptr_t pre_alignment_length = kInt32Size - misalignment;
+ switch (pre_alignment_length) {
+ case 3:
+ data_window |= cursor[2] << 16;
+ FALL_THROUGH;
+ case 2:
+ data_window |= cursor[1] << 8;
+ FALL_THROUGH;
+ case 1:
+ data_window |= cursor[0];
+ }
+ cursor += pre_alignment_length;
+ size -= pre_alignment_length;
+
+ // Mix four bytes at a time now that we're at an aligned spot.
+ for (; size >= kInt32Size; cursor += kInt32Size, size -= kInt32Size) {
+ uint32_t aligned_part = *reinterpret_cast<const uint32_t*>(cursor);
+ data_window |= (aligned_part << sl);
+ MIX(hash, data_window);
+ data_window = aligned_part >> sr;
+ }
+
+ if (size >= misalignment) {
+ // There's one more full window in the data. We'll let the normal tail
+ // code handle any partial window.
+ switch (misalignment) {
+ case 3:
+ data_window |= cursor[2] << (16 + sl);
+ FALL_THROUGH;
+ case 2:
+ data_window |= cursor[1] << (8 + sl);
+ FALL_THROUGH;
+ case 1:
+ data_window |= cursor[0] << sl;
+ }
+ MIX(hash, data_window);
+ cursor += misalignment;
+ size -= misalignment;
+ } else {
+ // This is a partial window, so just xor and multiply by M.
+ switch (size) {
+ case 2:
+ data_window |= cursor[1] << (8 + sl);
+ FALL_THROUGH;
+ case 1:
+ data_window |= cursor[0] << sl;
+ }
+ hash ^= data_window;
+ hash *= kStringHashM;
+ cursor += size;
+ size = 0;
+ }
+ } else {
+ // Mix four bytes at a time into the hash.
+ for (; size >= kInt32Size; size -= kInt32Size, cursor += kInt32Size) {
+ uint32_t part = *reinterpret_cast<const uint32_t*>(cursor);
+ MIX(hash, part);
+ }
+ }
}
- // Handle the last few bytes of the string.
+ // Handle the last few bytes of the string if any.
switch (size) {
case 3:
hash ^= cursor[2] << 16;
@@ -246,17 +319,19 @@
FALL_THROUGH;
case 1:
hash ^= cursor[0];
- hash *= M;
+ hash *= kStringHashM;
}
// Do a few final mixes of the hash to ensure the last few bytes are
// well-incorporated.
hash ^= hash >> 13;
- hash *= M;
+ hash *= kStringHashM;
hash ^= hash >> 15;
return hash;
}
+#undef MIX
+
uint32_t Utils::WordHash(intptr_t key) {
// TODO(iposva): Need to check hash spreading.
// This example is from http://www.concentric.net/~Ttwang/tech/inthash.htm
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index ef653b0..81908d7 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -299,7 +299,7 @@
private:
void WriteClass(Serializer* s, ClassPtr cls) {
- AutoTraceObjectName(cls, cls->untag()->name_);
+ AutoTraceObjectName(cls, cls->untag()->name());
WriteFromTo(cls);
intptr_t class_id = cls->untag()->id_;
if (class_id == kIllegalCid) {
@@ -338,7 +338,7 @@
// unsound nullability mode.
if (cls->untag()->host_type_arguments_field_offset_in_words_ ==
Class::kNoTypeArguments ||
- cls->untag()->constants_ == Array::null()) {
+ cls->untag()->constants() == Array::null()) {
return false;
}
Zone* zone = Thread::Current()->zone();
@@ -885,11 +885,11 @@
PushFromTo(func);
if (kind == Snapshot::kFullAOT) {
- s->Push(func->untag()->code_);
+ s->Push(func->untag()->code());
} else if (kind == Snapshot::kFullJIT) {
- NOT_IN_PRECOMPILED(s->Push(func->untag()->unoptimized_code_));
- s->Push(func->untag()->code_);
- s->Push(func->untag()->ic_data_array_);
+ NOT_IN_PRECOMPILED(s->Push(func->untag()->unoptimized_code()));
+ s->Push(func->untag()->code());
+ s->Push(func->untag()->ic_data_array());
}
}
@@ -911,11 +911,11 @@
AutoTraceObjectName(func, MakeDisambiguatedFunctionName(s, func));
WriteFromTo(func);
if (kind == Snapshot::kFullAOT) {
- WriteField(func, code_);
+ WriteField(func, code());
} else if (s->kind() == Snapshot::kFullJIT) {
- NOT_IN_PRECOMPILED(WriteField(func, unoptimized_code_));
- WriteField(func, code_);
- WriteField(func, ic_data_array_);
+ NOT_IN_PRECOMPILED(WriteField(func, unoptimized_code()));
+ WriteField(func, code());
+ WriteField(func, ic_data_array());
}
if (kind != Snapshot::kFullAOT) {
@@ -1019,12 +1019,12 @@
Function& func = Function::Handle(d->zone());
for (intptr_t i = start_index_; i < stop_index_; i++) {
func ^= refs.At(i);
- ASSERT(func.ptr()->untag()->code_->IsCode());
- uword entry_point = func.ptr()->untag()->code_->untag()->entry_point_;
+ ASSERT(func.ptr()->untag()->code()->IsCode());
+ uword entry_point = func.ptr()->untag()->code()->untag()->entry_point_;
ASSERT(entry_point != 0);
func.ptr()->untag()->entry_point_ = entry_point;
uword unchecked_entry_point =
- func.ptr()->untag()->code_->untag()->unchecked_entry_point_;
+ func.ptr()->untag()->code()->untag()->unchecked_entry_point_;
ASSERT(unchecked_entry_point != 0);
func.ptr()->untag()->unchecked_entry_point_ = unchecked_entry_point;
}
@@ -1064,11 +1064,11 @@
objects_.Add(data);
if (s->kind() != Snapshot::kFullAOT) {
- s->Push(data->untag()->context_scope_);
+ s->Push(data->untag()->context_scope());
}
- s->Push(data->untag()->parent_function_);
- s->Push(data->untag()->closure_);
- s->Push(data->untag()->default_type_arguments_);
+ s->Push(data->untag()->parent_function());
+ s->Push(data->untag()->closure());
+ s->Push(data->untag()->default_type_arguments());
}
void WriteAlloc(Serializer* s) {
@@ -1087,11 +1087,11 @@
ClosureDataPtr data = objects_[i];
AutoTraceObject(data);
if (s->kind() != Snapshot::kFullAOT) {
- WriteField(data, context_scope_);
+ WriteField(data, context_scope());
}
- WriteField(data, parent_function_);
- WriteField(data, closure_);
- WriteField(data, default_type_arguments_);
+ WriteField(data, parent_function());
+ WriteField(data, closure());
+ WriteField(data, default_type_arguments());
s->WriteUnsigned(
static_cast<intptr_t>(data->untag()->default_type_arguments_kind_));
}
@@ -1175,7 +1175,7 @@
s->WriteUnsigned(data->untag()->callback_id_);
} else {
// FFI callbacks can only be written to AOT snapshots.
- ASSERT(data->untag()->callback_target_ == Object::null());
+ ASSERT(data->untag()->callback_target() == Object::null());
}
}
}
@@ -1229,22 +1229,22 @@
Snapshot::Kind kind = s->kind();
- s->Push(field->untag()->name_);
- s->Push(field->untag()->owner_);
- s->Push(field->untag()->type_);
+ s->Push(field->untag()->name());
+ s->Push(field->untag()->owner());
+ s->Push(field->untag()->type());
// Write out the initializer function
- s->Push(field->untag()->initializer_function_);
+ s->Push(field->untag()->initializer_function());
if (kind != Snapshot::kFullAOT) {
- s->Push(field->untag()->guarded_list_length_);
+ s->Push(field->untag()->guarded_list_length());
}
if (kind == Snapshot::kFullJIT) {
- s->Push(field->untag()->dependent_code_);
+ s->Push(field->untag()->dependent_code());
}
// Write out either the initial static value or field offset.
if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
const intptr_t field_id =
- Smi::Value(field->untag()->host_offset_or_field_id_);
+ Smi::Value(field->untag()->host_offset_or_field_id());
s->Push(s->initial_field_table()->At(field_id));
} else {
s->Push(Smi::New(Field::TargetOffsetOf(field)));
@@ -1266,18 +1266,18 @@
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
FieldPtr field = objects_[i];
- AutoTraceObjectName(field, field->untag()->name_);
+ AutoTraceObjectName(field, field->untag()->name());
- WriteField(field, name_);
- WriteField(field, owner_);
- WriteField(field, type_);
+ WriteField(field, name());
+ WriteField(field, owner());
+ WriteField(field, type());
// Write out the initializer function and initial value if not in AOT.
- WriteField(field, initializer_function_);
+ WriteField(field, initializer_function());
if (kind != Snapshot::kFullAOT) {
- WriteField(field, guarded_list_length_);
+ WriteField(field, guarded_list_length());
}
if (kind == Snapshot::kFullJIT) {
- WriteField(field, dependent_code_);
+ WriteField(field, dependent_code());
}
if (kind != Snapshot::kFullAOT) {
@@ -1293,7 +1293,7 @@
// Write out either the initial static value or field offset.
if (Field::StaticBit::decode(field->untag()->kind_bits_)) {
const intptr_t field_id =
- Smi::Value(field->untag()->host_offset_or_field_id_);
+ Smi::Value(field->untag()->host_offset_or_field_id());
WriteFieldValue("static value", s->initial_field_table()->At(field_id));
s->WriteUnsigned(field_id);
} else {
@@ -1373,7 +1373,7 @@
Smi::RawCast(value_or_offset);
#if !defined(DART_PRECOMPILED_RUNTIME)
field->untag()->target_offset_ =
- Smi::Value(field->untag()->host_offset_or_field_id_);
+ Smi::Value(field->untag()->host_offset_or_field_id());
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
}
@@ -1429,7 +1429,7 @@
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
ScriptPtr script = objects_[i];
- AutoTraceObjectName(script, script->untag()->url_);
+ AutoTraceObjectName(script, script->untag()->url());
WriteFromTo(script);
s->Write<int32_t>(script->untag()->line_offset_);
s->Write<int32_t>(script->untag()->col_offset_);
@@ -1513,7 +1513,7 @@
const intptr_t count = objects_.length();
for (intptr_t i = 0; i < count; i++) {
LibraryPtr lib = objects_[i];
- AutoTraceObjectName(lib, lib->untag()->url_);
+ AutoTraceObjectName(lib, lib->untag()->url());
WriteFromTo(lib);
s->Write<int32_t>(lib->untag()->index_);
s->Write<uint16_t>(lib->untag()->num_imports_);
@@ -2789,7 +2789,7 @@
ExceptionHandlersPtr handlers = ExceptionHandlers::RawCast(object);
objects_.Add(handlers);
- s->Push(handlers->untag()->handled_types_data_);
+ s->Push(handlers->untag()->handled_types_data());
}
void WriteAlloc(Serializer* s) {
@@ -2814,7 +2814,7 @@
AutoTraceObject(handlers);
const intptr_t length = handlers->untag()->num_entries_;
s->WriteUnsigned(length);
- WriteField(handlers, handled_types_data_);
+ WriteField(handlers, handled_types_data());
for (intptr_t j = 0; j < length; j++) {
const ExceptionHandlerInfo& info = handlers->untag()->data()[j];
s->Write<uint32_t>(info.handler_pc_offset);
@@ -3344,7 +3344,7 @@
void Trace(Serializer* s, ObjectPtr object) {
LoadingUnitPtr unit = LoadingUnit::RawCast(object);
objects_.Add(unit);
- s->Push(unit->untag()->parent_);
+ s->Push(unit->untag()->parent());
}
void WriteAlloc(Serializer* s) {
@@ -3362,7 +3362,7 @@
for (intptr_t i = 0; i < count; i++) {
LoadingUnitPtr unit = objects_[i];
AutoTraceObject(unit);
- WriteField(unit, parent_);
+ WriteField(unit, parent());
s->Write<int32_t>(unit->untag()->id_);
}
}
@@ -3854,7 +3854,7 @@
SmiPtr raw_type_class_id = Smi::RawCast(type->untag()->type_class_id_);
ClassPtr type_class =
s->isolate_group()->class_table()->At(Smi::Value(raw_type_class_id));
- if (type_class->untag()->declaration_type_ != type) {
+ if (type_class->untag()->declaration_type() != type) {
return true;
}
@@ -6226,28 +6226,28 @@
name = FunctionSerializationCluster::MakeDisambiguatedFunctionName(this,
func);
owner_ref_name = "owner_";
- owner = func->untag()->owner_;
+ owner = func->untag()->owner();
break;
}
case kClassCid: {
ClassPtr cls = static_cast<ClassPtr>(obj);
type = "Class";
- name_string = cls->untag()->name_;
+ name_string = cls->untag()->name();
owner_ref_name = "library_";
- owner = cls->untag()->library_;
+ owner = cls->untag()->library();
break;
}
case kPatchClassCid: {
PatchClassPtr patch_cls = static_cast<PatchClassPtr>(obj);
type = "PatchClass";
owner_ref_name = "patched_class_";
- owner = patch_cls->untag()->patched_class_;
+ owner = patch_cls->untag()->patched_class();
break;
}
case kLibraryCid: {
LibraryPtr lib = static_cast<LibraryPtr>(obj);
type = "Library";
- name_string = lib->untag()->url_;
+ name_string = lib->untag()->url();
break;
}
default:
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index 3dd730e..403b206 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -348,20 +348,21 @@
template <typename T, typename... P>
void WriteFromTo(T obj, P&&... args) {
- ObjectPtr* from = obj->untag()->from();
- ObjectPtr* to = obj->untag()->to_snapshot(kind(), args...);
- for (ObjectPtr* p = from; p <= to; p++) {
- WriteOffsetRef(*p, (p - reinterpret_cast<ObjectPtr*>(obj->untag())) *
- sizeof(ObjectPtr));
+ auto* from = obj->untag()->from();
+ auto* to = obj->untag()->to_snapshot(kind(), args...);
+ for (auto* p = from; p <= to; p++) {
+ WriteOffsetRef(
+ p->Decompress(obj->heap_base()),
+ reinterpret_cast<uword>(p) - reinterpret_cast<uword>(obj->untag()));
}
}
template <typename T, typename... P>
void PushFromTo(T obj, P&&... args) {
- ObjectPtr* from = obj->untag()->from();
- ObjectPtr* to = obj->untag()->to_snapshot(kind(), args...);
- for (ObjectPtr* p = from; p <= to; p++) {
- Push(*p);
+ auto* from = obj->untag()->from();
+ auto* to = obj->untag()->to_snapshot(kind(), args...);
+ for (auto* p = from; p <= to; p++) {
+ Push(p->Decompress(obj->heap_base()));
}
}
@@ -625,17 +626,17 @@
template <typename T, typename... P>
void ReadFromTo(T obj, P&&... params) {
- ObjectPtr* from = obj->untag()->from();
- ObjectPtr* to_snapshot = obj->untag()->to_snapshot(kind(), params...);
- ObjectPtr* to = obj->untag()->to(params...);
- for (ObjectPtr* p = from; p <= to_snapshot; p++) {
+ auto* from = obj->untag()->from();
+ auto* to_snapshot = obj->untag()->to_snapshot(kind(), params...);
+ auto* to = obj->untag()->to(params...);
+ for (auto* p = from; p <= to_snapshot; p++) {
*p = ReadRef();
}
// This is necessary because, unlike Object::Allocate, the clustered
// deserializer allocates object without null-initializing them. Instead,
// each deserialization cluster is responsible for initializing every field,
// ensuring that every field is written to exactly once.
- for (ObjectPtr* p = to_snapshot + 1; p <= to; p++) {
+ for (auto* p = to_snapshot + 1; p <= to; p++) {
*p = Object::null();
}
}
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 2729e66..de299cd 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -286,8 +286,7 @@
return true;
}
- if (FlowGraphCompiler::SupportsUnboxedInt64() &&
- FlowGraphCompiler::CanConvertInt64ToDouble()) {
+ if (FlowGraphCompiler::CanConvertInt64ToDouble()) {
return true;
}
}
@@ -315,8 +314,7 @@
if (input->Type()->ToNullableCid() == kSmiCid) {
conversion = new (Z) SmiToDoubleInstr(input, call->source());
- } else if (FlowGraphCompiler::SupportsUnboxedInt64() &&
- FlowGraphCompiler::CanConvertInt64ToDouble()) {
+ } else if (FlowGraphCompiler::CanConvertInt64ToDouble()) {
conversion = new (Z) Int64ToDoubleInstr(input, DeoptId::kNone,
Instruction::kNotSpeculative);
} else {
@@ -506,11 +504,8 @@
case Token::kLTE:
case Token::kGT:
case Token::kGTE: {
- const bool supports_unboxed_int =
- FlowGraphCompiler::SupportsUnboxedInt64();
const bool can_use_equality_compare =
- supports_unboxed_int && is_equality_op && left_type->IsInt() &&
- right_type->IsInt();
+ is_equality_op && left_type->IsInt() && right_type->IsInt();
// We prefer equality compare, since it doesn't require boxing.
if (!can_use_equality_compare && can_use_strict_compare) {
@@ -522,33 +517,23 @@
break;
}
- if (supports_unboxed_int) {
- if (can_use_equality_compare) {
- replacement = new (Z) EqualityCompareInstr(
- instr->source(), op_kind, left_value->CopyWithType(Z),
- right_value->CopyWithType(Z), kMintCid, DeoptId::kNone,
- Instruction::kNotSpeculative);
- break;
- } else if (Token::IsRelationalOperator(op_kind)) {
- left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
- right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
- replacement = new (Z) RelationalOpInstr(
- instr->source(), op_kind, left_value, right_value, kMintCid,
- DeoptId::kNone, Instruction::kNotSpeculative);
- break;
- } else {
- // TODO(dartbug.com/30480): Figure out how to handle null in
- // equality comparisons.
- replacement = new (Z)
- CheckedSmiComparisonInstr(op_kind, left_value->CopyWithType(Z),
- right_value->CopyWithType(Z), instr);
- break;
- }
+ if (can_use_equality_compare) {
+ replacement = new (Z) EqualityCompareInstr(
+ instr->source(), op_kind, left_value->CopyWithType(Z),
+ right_value->CopyWithType(Z), kMintCid, DeoptId::kNone,
+ Instruction::kNotSpeculative);
+ } else if (Token::IsRelationalOperator(op_kind)) {
+ left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+ right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
+ replacement = new (Z) RelationalOpInstr(
+ instr->source(), op_kind, left_value, right_value, kMintCid,
+ DeoptId::kNone, Instruction::kNotSpeculative);
} else {
+ // TODO(dartbug.com/30480): Figure out how to handle null in
+ // equality comparisons.
replacement = new (Z)
CheckedSmiComparisonInstr(op_kind, left_value->CopyWithType(Z),
right_value->CopyWithType(Z), instr);
- break;
}
break;
}
@@ -580,28 +565,18 @@
case Token::kSUB:
FALL_THROUGH;
case Token::kMUL: {
- if (FlowGraphCompiler::SupportsUnboxedInt64()) {
- if (op_kind == Token::kSHL || op_kind == Token::kSHR ||
- op_kind == Token::kUSHR) {
- left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
- right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
- replacement = new (Z) ShiftInt64OpInstr(
- op_kind, left_value, right_value, DeoptId::kNone);
- break;
- } else {
- left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
- right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
- replacement = new (Z) BinaryInt64OpInstr(
- op_kind, left_value, right_value, DeoptId::kNone,
- Instruction::kNotSpeculative);
- break;
- }
- }
- if (op_kind != Token::kMOD && op_kind != Token::kTRUNCDIV) {
- replacement =
- new (Z) CheckedSmiOpInstr(op_kind, left_value->CopyWithType(Z),
- right_value->CopyWithType(Z), instr);
- break;
+ if (op_kind == Token::kSHL || op_kind == Token::kSHR ||
+ op_kind == Token::kUSHR) {
+ left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+ right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
+ replacement = new (Z) ShiftInt64OpInstr(op_kind, left_value,
+ right_value, DeoptId::kNone);
+ } else {
+ left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+ right_value = PrepareStaticOpInput(right_value, kMintCid, instr);
+ replacement = new (Z)
+ BinaryInt64OpInstr(op_kind, left_value, right_value,
+ DeoptId::kNone, Instruction::kNotSpeculative);
}
break;
}
@@ -618,12 +593,10 @@
return false;
}
- if (FlowGraphCompiler::SupportsUnboxedInt64()) {
- if (op_kind == Token::kNEGATE || op_kind == Token::kBIT_NOT) {
- left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
- replacement = new (Z) UnaryInt64OpInstr(
- op_kind, left_value, DeoptId::kNone, Instruction::kNotSpeculative);
- }
+ if (op_kind == Token::kNEGATE || op_kind == Token::kBIT_NOT) {
+ left_value = PrepareStaticOpInput(left_value, kMintCid, instr);
+ replacement = new (Z) UnaryInt64OpInstr(
+ op_kind, left_value, DeoptId::kNone, Instruction::kNotSpeculative);
}
}
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 059575b..c3c64be 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1569,7 +1569,8 @@
__ CompareImmediate(R3, 0);
__ b(normal_ir_body, NE);
- __ ldr(R0, FieldAddress(R2, target::Class::declaration_type_offset()));
+ __ LoadCompressed(R0,
+ FieldAddress(R2, target::Class::declaration_type_offset()));
__ CompareObject(R0, NullObject());
__ b(normal_ir_body, EQ);
__ ret();
@@ -2311,7 +2312,8 @@
__ eor(R5, R5, Operand(R5));
// Tail-call the function.
- __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(R0, target::Function::code_offset()));
__ ldr(R1, FieldAddress(R0, target::Function::entry_point_offset()));
__ br(R1);
}
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index a2b59ef..9cf721d 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1492,7 +1492,8 @@
__ movzxw(RCX, FieldAddress(RDI, target::Class::num_type_arguments_offset()));
__ cmpq(RCX, Immediate(0));
__ j(NOT_EQUAL, normal_ir_body, Assembler::kNearJump);
- __ movq(RAX, FieldAddress(RDI, target::Class::declaration_type_offset()));
+ __ LoadCompressed(
+ RAX, FieldAddress(RDI, target::Class::declaration_type_offset()));
__ CompareObject(RAX, NullObject());
__ j(EQUAL, normal_ir_body, Assembler::kNearJump); // Not yet set.
__ ret();
@@ -2233,7 +2234,8 @@
__ xorq(RCX, RCX);
// Tail-call the function.
- __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(RAX, target::Function::code_offset()));
__ movq(RDI, FieldAddress(RAX, target::Function::entry_point_offset()));
__ jmp(RDI);
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 4efc1e9..3a221a5 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -933,6 +933,13 @@
Condition cond = AL) {
LoadFromOffset(reg, base, offset - kHeapObjectTag, type, cond);
}
+ void LoadCompressedFieldFromOffset(Register reg,
+ Register base,
+ int32_t offset,
+ OperandSize type = kFourBytes,
+ Condition cond = AL) {
+ LoadFieldFromOffset(reg, base, offset, type, cond);
+ }
// For loading indexed payloads out of tagged objects like Arrays. If the
// payload objects are word-sized, use TIMES_HALF_WORD_SIZE if the contents of
// [index] is a Smi, otherwise TIMES_WORD_SIZE if unboxed.
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 0417af4..1682a69 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1687,6 +1687,11 @@
OperandSize sz = kEightBytes) {
LoadFromOffset(dest, base, offset - kHeapObjectTag, sz);
}
+ void LoadCompressedFieldFromOffset(Register dest,
+ Register base,
+ int32_t offset) {
+ LoadCompressed(dest, FieldAddress(base, offset));
+ }
// For loading indexed payloads out of tagged objects like Arrays. If the
// payload objects are word-sized, use TIMES_HALF_WORD_SIZE if the contents of
// [index] is a Smi, otherwise TIMES_WORD_SIZE if unboxed.
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index ed03442..1573131 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -595,6 +595,12 @@
OperandSize type = kFourBytes) {
LoadFromOffset(reg, base, offset - kHeapObjectTag, type);
}
+ void LoadCompressedFieldFromOffset(Register reg,
+ Register base,
+ int32_t offset,
+ OperandSize type = kFourBytes) {
+ LoadFieldFromOffset(reg, base, offset, type);
+ }
void LoadIndexedFieldFromOffset(Register reg,
Register base,
int32_t offset,
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 82d7b89..a855106 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -939,6 +939,11 @@
OperandSize sz = kEightBytes) {
LoadFromOffset(dst, FieldAddress(base, offset), sz);
}
+ void LoadCompressedFieldFromOffset(Register dst,
+ Register base,
+ int32_t offset) {
+ LoadCompressed(dst, FieldAddress(base, offset));
+ }
void LoadIndexedPayload(Register dst,
Register base,
int32_t payload_offset,
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index 192d541..9d81af6 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -197,8 +197,7 @@
return true;
}
if (cid_ == kIllegalCid || cid_ == kDynamicCid) {
- return type_ != nullptr &&
- (compiler::IsIntType(*type_) || compiler::IsSmiType(*type_));
+ return type_ != nullptr && compiler::IsSubtypeOfInt(*type_);
}
return false;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 20440a1..ba7725c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -2536,8 +2536,9 @@
// kScratch2 is no longer used, so restore it.
__ PopRegister(kScratch2Reg);
#endif
- __ LoadFieldFromOffset(kScratch1Reg, kScratch1Reg,
- compiler::target::Class::super_type_offset());
+ __ LoadCompressedFieldFromOffset(
+ kScratch1Reg, kScratch1Reg,
+ compiler::target::Class::super_type_offset());
__ LoadFieldFromOffset(kScratch1Reg, kScratch1Reg,
compiler::target::Type::type_class_id_offset());
__ CompareImmediate(kScratch1Reg, Smi::RawValue(type_class.id()));
@@ -2748,7 +2749,6 @@
return SubtypeTestCache::null();
}
-#if !defined(TARGET_ARCH_IA32)
// If instanceof type test cannot be performed successfully at compile time and
// therefore eliminated, optimize it by adding inlined tests for:
// - Null -> see comment below.
@@ -2810,6 +2810,7 @@
__ Bind(&done);
}
+#if !defined(TARGET_ARCH_IA32)
// Expected inputs (from TypeTestABI):
// - kInstanceReg: instance (preserved).
// - kDstTypeReg: destination type (for test_kind != kTestTypeOneArg).
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 54e19ba..b77578b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -436,7 +436,6 @@
~FlowGraphCompiler();
static bool SupportsUnboxedDoubles();
- static bool SupportsUnboxedInt64();
static bool SupportsUnboxedSimd128();
static bool SupportsHardwareDivision();
static bool CanConvertInt64ToDouble();
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index d12a177..c4d084f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -25,7 +25,6 @@
namespace dart {
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
DECLARE_FLAG(bool, enable_simd_inline);
@@ -70,10 +69,6 @@
return TargetCPUFeatures::vfp_supported() && FLAG_unbox_doubles;
}
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
- return FLAG_unbox_mints;
-}
-
bool FlowGraphCompiler::SupportsUnboxedSimd128() {
return TargetCPUFeatures::neon_supported() && FLAG_enable_simd_inline;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 9448800..d7bf55f 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -26,7 +26,6 @@
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
DECLARE_FLAG(bool, enable_simd_inline);
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
void FlowGraphCompiler::ArchSpecificInitialization() {
if (FLAG_precompiled_mode && FLAG_use_bare_instructions) {
@@ -66,10 +65,6 @@
return true;
}
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
- return FLAG_unbox_mints;
-}
-
bool FlowGraphCompiler::SupportsUnboxedSimd128() {
return FLAG_enable_simd_inline;
}
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index b5e050d..025ac3b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -26,7 +26,6 @@
namespace dart {
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
DECLARE_FLAG(bool, enable_simd_inline);
@@ -45,10 +44,6 @@
return true;
}
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
- return FLAG_unbox_mints;
-}
-
bool FlowGraphCompiler::SupportsUnboxedSimd128() {
return FLAG_enable_simd_inline;
}
@@ -252,75 +247,6 @@
return type_test_cache.ptr();
}
-// If instanceof type test cannot be performed successfully at compile time and
-// therefore eliminated, optimize it by adding inlined tests for:
-// - Null -> see comment below.
-// - Smi -> compile time subtype check (only if dst class is not parameterized).
-// - Class equality (only if class is not parameterized).
-// Inputs:
-// - EAX: object.
-// - EDX: instantiator type arguments or raw_null.
-// - ECX: function type arguments or raw_null.
-// Returns:
-// - true or false in EAX.
-void FlowGraphCompiler::GenerateInstanceOf(const InstructionSource& source,
- intptr_t deopt_id,
- const AbstractType& type,
- LocationSummary* locs) {
- ASSERT(type.IsFinalized());
- ASSERT(!type.IsTopTypeForInstanceOf()); // Already checked.
-
- const compiler::Immediate& raw_null =
- compiler::Immediate(static_cast<intptr_t>(Object::null()));
- compiler::Label is_instance, is_not_instance;
- // 'null' is an instance of Null, Object*, Never*, void, and dynamic.
- // In addition, 'null' is an instance of any nullable type.
- // It is also an instance of FutureOr<T> if it is an instance of T.
- const AbstractType& unwrapped_type =
- AbstractType::Handle(type.UnwrapFutureOr());
- if (!unwrapped_type.IsTypeParameter() || unwrapped_type.IsNullable()) {
- // Only nullable type parameter remains nullable after instantiation.
- // See NullIsInstanceOf().
- __ cmpl(EAX, raw_null);
- __ j(EQUAL, (unwrapped_type.IsNullable() ||
- (unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType()))
- ? &is_instance
- : &is_not_instance);
- }
-
- // Generate inline instanceof test.
- SubtypeTestCache& test_cache = SubtypeTestCache::ZoneHandle(zone());
- test_cache =
- GenerateInlineInstanceof(source, type, &is_instance, &is_not_instance);
-
- // test_cache is null if there is no fall-through.
- compiler::Label done;
- if (!test_cache.IsNull()) {
- // Generate runtime call.
- __ PushObject(Object::null_object()); // Make room for the result.
- __ pushl(TypeTestABI::kInstanceReg); // Push the instance.
- __ PushObject(type); // Push the type.
- __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
- __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
- // Can reuse kInstanceReg as scratch here since it was pushed above.
- __ LoadObject(TypeTestABI::kInstanceReg, test_cache);
- __ pushl(TypeTestABI::kInstanceReg);
- GenerateRuntimeCall(source, deopt_id, kInstanceofRuntimeEntry, 5, locs);
- // Pop the parameters supplied to the runtime entry. The result of the
- // instanceof runtime call will be left as the result of the operation.
- __ Drop(5);
- __ popl(TypeTestABI::kInstanceOfResultReg);
- __ jmp(&done, compiler::Assembler::kNearJump);
- }
- __ Bind(&is_not_instance);
- __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(false));
- __ jmp(&done, compiler::Assembler::kNearJump);
-
- __ Bind(&is_instance);
- __ LoadObject(TypeTestABI::kInstanceOfResultReg, Bool::Get(true));
- __ Bind(&done);
-}
-
// Optimize assignable type check by adding inlined tests for:
// - NULL -> return NULL.
// - Smi -> compile time subtype check (only if dst class is not parameterized).
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index efbe4a5..d5d9020 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -25,7 +25,6 @@
namespace dart {
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
DECLARE_FLAG(bool, enable_simd_inline);
void FlowGraphCompiler::ArchSpecificInitialization() {
@@ -67,10 +66,6 @@
return true;
}
-bool FlowGraphCompiler::SupportsUnboxedInt64() {
- return FLAG_unbox_mints;
-}
-
bool FlowGraphCompiler::SupportsUnboxedSimd128() {
return FLAG_enable_simd_inline;
}
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index af6199b..0c2dcff 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -2474,10 +2474,9 @@
if ((left_type->ToCid() == kSmiCid) && (right_type->ToCid() == kSmiCid)) {
op_cid = kSmiCid;
- } else if (FlowGraphCompiler::SupportsUnboxedInt64() &&
- // TODO(dartbug.com/30480): handle nullable types here
- left_type->IsNullableInt() && !left_type->is_nullable() &&
- right_type->IsNullableInt() && !right_type->is_nullable()) {
+ } else if ( // TODO(dartbug.com/30480): handle nullable types here
+ left_type->IsNullableInt() && !left_type->is_nullable() &&
+ right_type->IsNullableInt() && !right_type->is_nullable()) {
op_cid = kMintCid;
speculative_mode = kNotSpeculative;
}
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 5d39a46..b9a9ff2 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -7158,6 +7158,14 @@
virtual Definition* Canonicalize(FlowGraph* flow_graph);
+ virtual bool ComputeCanDeoptimize() const {
+ if (SpeculativeModeOfInputs() == kNotSpeculative) {
+ return false;
+ }
+
+ return !value()->Type()->IsInt();
+ }
+
DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt64)
private:
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 57629ea..a4d8689 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -521,8 +521,8 @@
// R0: Function.
ASSERT(locs()->in(0).reg() == R0);
if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
- __ LoadFieldFromOffset(CODE_REG, R0,
- compiler::target::Function::code_offset());
+ __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+ compiler::target::Function::code_offset());
}
__ LoadFieldFromOffset(
R2, R0, compiler::target::Function::entry_point_offset(entry_kind()));
@@ -2314,8 +2314,9 @@
compiler::FieldAddress(
field_reg, Field::guarded_list_length_in_object_offset_offset()),
compiler::kByte);
- __ ldr(length_reg, compiler::FieldAddress(
- field_reg, Field::guarded_list_length_offset()));
+ __ LoadCompressed(
+ length_reg,
+ compiler::FieldAddress(field_reg, Field::guarded_list_length_offset()));
__ tst(offset_reg, compiler::Operand(offset_reg));
__ b(&ok, MI);
@@ -2626,6 +2627,7 @@
__ Bind(&store_pointer);
}
+ ASSERT(!slot().is_compressed()); // Unimplemented.
if (ShouldEmitStoreBarrier()) {
const Register value_reg = locs()->in(1).reg();
__ StoreIntoObjectOffset(instance_reg, offset_in_bytes, value_reg,
@@ -3016,7 +3018,11 @@
__ Bind(&load_pointer);
}
- __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
+ if (slot().is_compressed()) {
+ __ LoadCompressedFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
+ } else {
+ __ LoadFieldFromOffset(result_reg, instance_reg, OffsetInBytes());
+ }
if (calls_initializer()) {
EmitNativeCodeForInitializerCall(compiler);
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 1bef8cf..574395a 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -2343,8 +2343,9 @@
offset_reg,
compiler::FieldAddress(
field_reg, Field::guarded_list_length_in_object_offset_offset()));
- __ movq(length_reg, compiler::FieldAddress(
- field_reg, Field::guarded_list_length_offset()));
+ __ LoadCompressed(
+ length_reg,
+ compiler::FieldAddress(field_reg, Field::guarded_list_length_offset()));
__ cmpq(offset_reg, compiler::Immediate(0));
__ j(NEGATIVE, &ok);
@@ -2696,6 +2697,7 @@
__ Bind(&store_pointer);
}
+ ASSERT(!slot().is_compressed()); // Unimplemented.
if (ShouldEmitStoreBarrier()) {
Register value_reg = locs()->in(1).reg();
__ StoreIntoObject(instance_reg,
@@ -3099,7 +3101,12 @@
__ Bind(&load_pointer);
}
- __ movq(result, compiler::FieldAddress(instance_reg, OffsetInBytes()));
+ if (slot().is_compressed()) {
+ __ LoadCompressed(result,
+ compiler::FieldAddress(instance_reg, OffsetInBytes()));
+ } else {
+ __ movq(result, compiler::FieldAddress(instance_reg, OffsetInBytes()));
+ }
if (calls_initializer()) {
EmitNativeCodeForInitializerCall(compiler);
@@ -7327,8 +7334,9 @@
// Function in RAX.
ASSERT(locs()->in(0).reg() == RAX);
if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
- __ movq(CODE_REG, compiler::FieldAddress(
- RAX, compiler::target::Function::code_offset()));
+ __ LoadCompressed(
+ CODE_REG,
+ compiler::FieldAddress(RAX, compiler::target::Function::code_offset()));
}
__ movq(
RCX,
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 95ba032..094aeab 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -2385,17 +2385,6 @@
return FlowGraphCompiler::SupportsUnboxedDoubles();
}
-static bool ShouldInlineInt64ArrayOps() {
- return FlowGraphCompiler::SupportsUnboxedInt64();
-}
-
-static bool CanUnboxInt32() {
- // Int32/Uint32 can be unboxed if it fits into a smi or the platform
- // supports unboxed mints.
- return (compiler::target::kSmiBits >= 32) ||
- FlowGraphCompiler::SupportsUnboxedInt64();
-}
-
// Quick access to the current one.
#undef Z
#define Z (flow_graph->zone())
@@ -3672,16 +3661,10 @@
call, receiver, graph_entry, entry, last, result);
case MethodRecognizer::kInt32ArrayGetIndexed:
case MethodRecognizer::kUint32ArrayGetIndexed:
- if (!CanUnboxInt32()) {
- return false;
- }
return InlineGetIndexed(flow_graph, can_speculate, is_dynamic_call, kind,
call, receiver, graph_entry, entry, last, result);
case MethodRecognizer::kInt64ArrayGetIndexed:
case MethodRecognizer::kUint64ArrayGetIndexed:
- if (!ShouldInlineInt64ArrayOps()) {
- return false;
- }
return InlineGetIndexed(flow_graph, can_speculate, is_dynamic_call, kind,
call, receiver, graph_entry, entry, last, result);
case MethodRecognizer::kClassIDgetID:
@@ -3732,9 +3715,6 @@
}
case MethodRecognizer::kInt64ArraySetIndexed:
case MethodRecognizer::kUint64ArraySetIndexed:
- if (!ShouldInlineInt64ArrayOps()) {
- return false;
- }
return InlineSetIndexed(flow_graph, kind, target, call, receiver, source,
/* value_check = */ NULL, exactness, graph_entry,
entry, last, result);
@@ -3783,30 +3763,18 @@
kTypedDataUint16ArrayCid, graph_entry,
entry, last, result);
case MethodRecognizer::kByteArrayBaseGetInt32:
- if (!CanUnboxInt32()) {
- return false;
- }
return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
kTypedDataInt32ArrayCid, graph_entry,
entry, last, result);
case MethodRecognizer::kByteArrayBaseGetUint32:
- if (!CanUnboxInt32()) {
- return false;
- }
return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
kTypedDataUint32ArrayCid, graph_entry,
entry, last, result);
case MethodRecognizer::kByteArrayBaseGetInt64:
- if (!ShouldInlineInt64ArrayOps()) {
- return false;
- }
return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
kTypedDataInt64ArrayCid, graph_entry,
entry, last, result);
case MethodRecognizer::kByteArrayBaseGetUint64:
- if (!ShouldInlineInt64ArrayOps()) {
- return false;
- }
return InlineByteArrayBaseLoad(flow_graph, call, receiver, receiver_cid,
kTypedDataUint64ArrayCid, graph_entry,
entry, last, result);
@@ -3863,16 +3831,10 @@
receiver_cid, kTypedDataUint32ArrayCid,
graph_entry, entry, last, result);
case MethodRecognizer::kByteArrayBaseSetInt64:
- if (!ShouldInlineInt64ArrayOps()) {
- return false;
- }
return InlineByteArrayBaseStore(flow_graph, target, call, receiver,
receiver_cid, kTypedDataInt64ArrayCid,
graph_entry, entry, last, result);
case MethodRecognizer::kByteArrayBaseSetUint64:
- if (!ShouldInlineInt64ArrayOps()) {
- return false;
- }
return InlineByteArrayBaseStore(flow_graph, target, call, receiver,
receiver_cid, kTypedDataUint64ArrayCid,
graph_entry, entry, last, result);
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index 5b814c5..56e7709 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -124,6 +124,9 @@
Slot* new_value = new Slot[kNativeSlotsCount]{
#define NULLABLE_FIELD_FINAL \
(IsNullableBit::encode(true) | IsImmutableBit::encode(true))
+#define NULLABLE_FIELD_FINAL_COMPRESSED \
+ (IsNullableBit::encode(true) | IsImmutableBit::encode(true) | \
+ IsCompressedBit::encode(true))
#define NULLABLE_FIELD_VAR (IsNullableBit::encode(true))
#define DEFINE_NULLABLE_BOXED_NATIVE_FIELD(ClassName, UnderlyingType, \
FieldName, cid, mutability) \
@@ -138,6 +141,8 @@
#undef NULLABLE_FIELD_VAR
#define NONNULLABLE_FIELD_FINAL (Slot::IsImmutableBit::encode(true))
+#define NONNULLABLE_FIELD_FINAL_COMPRESSED \
+ (Slot::IsImmutableBit::encode(true) | Slot::IsCompressedBit::encode(true))
#define NONNULLABLE_FIELD_VAR (0)
#define DEFINE_NONNULLABLE_BOXED_NATIVE_FIELD(ClassName, UnderlyingType, \
FieldName, cid, mutability) \
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 8096b2d..655b10c 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -52,14 +52,14 @@
// (i.e. initialized once at construction time and does not change after
// that) or like a non-final field.
#define NULLABLE_BOXED_NATIVE_SLOTS_LIST(V) \
- V(Function, UntaggedFunction, signature, FunctionType, FINAL) \
+ V(Function, UntaggedFunction, signature, FunctionType, FINAL_COMPRESSED) \
V(Context, UntaggedContext, parent, Context, FINAL) \
V(Closure, UntaggedClosure, instantiator_type_arguments, TypeArguments, \
FINAL) \
V(Closure, UntaggedClosure, delayed_type_arguments, TypeArguments, FINAL) \
V(Closure, UntaggedClosure, function_type_arguments, TypeArguments, FINAL) \
V(ClosureData, UntaggedClosureData, default_type_arguments, TypeArguments, \
- FINAL) \
+ FINAL_COMPRESSED) \
V(Type, UntaggedType, arguments, TypeArguments, FINAL) \
V(FunctionType, UntaggedFunctionType, type_parameters, TypeArguments, FINAL) \
V(WeakProperty, UntaggedWeakProperty, key, Dynamic, VAR) \
@@ -83,7 +83,7 @@
V(Closure, UntaggedClosure, function, Function, FINAL) \
V(Closure, UntaggedClosure, context, Context, FINAL) \
V(Closure, UntaggedClosure, hash, Context, VAR) \
- V(Function, UntaggedFunction, data, Dynamic, FINAL) \
+ V(Function, UntaggedFunction, data, Dynamic, FINAL_COMPRESSED) \
V(FunctionType, UntaggedFunctionType, parameter_names, Array, FINAL) \
V(FunctionType, UntaggedFunctionType, parameter_types, Array, FINAL) \
V(GrowableObjectArray, UntaggedGrowableObjectArray, length, Smi, VAR) \
@@ -241,6 +241,8 @@
// of the corresponding Dart field.
bool is_guarded_field() const { return IsGuardedBit::decode(flags_); }
+ bool is_compressed() const { return IsCompressedBit::decode(flags_); }
+
// Static type of the slots if any.
//
// A value that is read from the slot is guaranteed to be assignable to its
@@ -295,6 +297,7 @@
using IsImmutableBit = BitField<int8_t, bool, 0, 1>;
using IsNullableBit = BitField<int8_t, bool, IsImmutableBit::kNextBit, 1>;
using IsGuardedBit = BitField<int8_t, bool, IsNullableBit::kNextBit, 1>;
+ using IsCompressedBit = BitField<int8_t, bool, IsGuardedBit::kNextBit, 1>;
template <typename T>
const T* DataAs() const {
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index 4791955..cb294e9 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -401,8 +401,7 @@
call->source()),
call->env(), FlowGraph::kEffect);
cid = kSmiCid;
- } else if (binary_feedback.OperandsAreSmiOrMint() &&
- FlowGraphCompiler::SupportsUnboxedInt64()) {
+ } else if (binary_feedback.OperandsAreSmiOrMint()) {
cid = kMintCid;
} else if (binary_feedback.OperandsAreSmiOrDouble() && CanUnboxDouble()) {
// Use double comparison.
@@ -477,8 +476,7 @@
call->source()),
call->env(), FlowGraph::kEffect);
cid = kSmiCid;
- } else if (binary_feedback.OperandsAreSmiOrMint() &&
- FlowGraphCompiler::SupportsUnboxedInt64()) {
+ } else if (binary_feedback.OperandsAreSmiOrMint()) {
cid = kMintCid;
} else if (binary_feedback.OperandsAreSmiOrDouble() && CanUnboxDouble()) {
// Use double comparison.
@@ -525,8 +523,7 @@
call->ic_data()->HasDeoptReason(ICData::kDeoptBinarySmiOp)
? kMintCid
: kSmiCid;
- } else if (binary_feedback.OperandsAreSmiOrMint() &&
- FlowGraphCompiler::SupportsUnboxedInt64()) {
+ } else if (binary_feedback.OperandsAreSmiOrMint()) {
// Don't generate mint code if the IC data is marked because of an
// overflow.
if (call->ic_data()->HasDeoptReason(ICData::kDeoptBinaryInt64Op))
@@ -638,7 +635,6 @@
call->deopt_id(), call->source());
ReplaceCall(call, double_bin_op);
} else if (operands_type == kMintCid) {
- if (!FlowGraphCompiler::SupportsUnboxedInt64()) return false;
if ((op_kind == Token::kSHL) || (op_kind == Token::kSHR) ||
(op_kind == Token::kUSHR)) {
SpeculativeShiftInt64OpInstr* shift_op = new (Z)
@@ -715,8 +711,7 @@
unary_op = new (Z)
UnarySmiOpInstr(op_kind, new (Z) Value(input), call->deopt_id());
} else if ((op_kind == Token::kBIT_NOT) &&
- call->Targets().ReceiverIsSmiOrMint() &&
- FlowGraphCompiler::SupportsUnboxedInt64()) {
+ call->Targets().ReceiverIsSmiOrMint()) {
unary_op = new (Z)
UnaryInt64OpInstr(op_kind, new (Z) Value(input), call->deopt_id());
} else if (call->Targets().ReceiverIs(kDoubleCid) &&
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index b7126d7..3b5421f 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -3456,9 +3456,7 @@
if (param_pos < function.maximum_unboxed_parameter_count()) {
switch (metadata->unboxed_args_info[param_index]) {
case UnboxingInfoMetadata::kUnboxedIntCandidate:
- if (FlowGraphCompiler::SupportsUnboxedInt64()) {
- function.set_unboxed_integer_parameter_at(param_pos);
- }
+ function.set_unboxed_integer_parameter_at(param_pos);
break;
case UnboxingInfoMetadata::kUnboxedDoubleCandidate:
if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
@@ -3482,9 +3480,7 @@
const UnboxingInfoMetadata* metadata) {
switch (metadata->return_info) {
case UnboxingInfoMetadata::kUnboxedIntCandidate:
- if (FlowGraphCompiler::SupportsUnboxedInt64()) {
- function.set_unboxed_integer_return();
- }
+ function.set_unboxed_integer_return();
break;
case UnboxingInfoMetadata::kUnboxedDoubleCandidate:
if (FlowGraphCompiler::SupportsUnboxedDoubles()) {
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index a8f9559..b4161bf 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -57,8 +57,7 @@
case MethodRecognizer::kUint64ArrayGetIndexed:
case MethodRecognizer::kUint64ArraySetIndexed:
// TODO(ajcbik): consider 32-bit as well.
- if (target::kBitsPerWord == 64 &&
- FlowGraphCompiler::SupportsUnboxedInt64()) {
+ if (target::kBitsPerWord == 64) {
break;
}
if (FLAG_trace_intrinsifier) {
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 88539e8..63fa7d6 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -70,8 +70,9 @@
return type.IsBoolType();
}
-bool IsIntType(const AbstractType& type) {
- return type.IsIntType();
+bool IsSubtypeOfInt(const AbstractType& type) {
+ return type.IsIntType() || type.IsIntegerImplementationType() ||
+ type.IsSmiType() || type.IsMintType();
}
bool IsSmiType(const AbstractType& type) {
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 7f0425a..43ec84a 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -127,8 +127,9 @@
// Returns true if [a] and [b] represent the same type (are equal).
bool IsEqualType(const AbstractType& a, const AbstractType& b);
-// Returns true if [type] is the "int" type.
-bool IsIntType(const AbstractType& type);
+// Returns true if [type] is a subtype of the "int" type (_Smi, _Mint, int or
+// _IntegerImplementation).
+bool IsSubtypeOfInt(const AbstractType& type);
// Returns true if [type] is the "double" type.
bool IsDoubleType(const AbstractType& type);
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 70016d86..7f85e9e 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -2163,14 +2163,14 @@
#if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
static constexpr dart::compiler::target::word Function_usage_counter_offset =
- 116;
+ 84;
static constexpr dart::compiler::target::word
ICData_receivers_static_type_offset = 32;
static constexpr dart::compiler::target::word
ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
static constexpr dart::compiler::target::word
- ExceptionHandlers_elements_start_offset = 24;
+ ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
12;
static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -2237,12 +2237,12 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 104;
+ 56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+ 92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- Class_host_type_arguments_field_offset_in_words_offset = 176;
+ Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word
SharedClassTable_class_heap_stats_table_offset = 0;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
@@ -2255,9 +2255,9 @@
static constexpr dart::compiler::target::word
Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_offset = 32;
+ ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_kind_offset = 40;
+ ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word Code_saved_instructions_offset =
48;
@@ -2272,24 +2272,24 @@
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- Field_initializer_function_offset = 32;
+ Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+ Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
-static constexpr dart::compiler::target::word Function_code_offset = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
static constexpr dart::compiler::target::word Function_packed_fields_offset =
- 108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+ 76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
8;
static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -2577,7 +2577,7 @@
static constexpr dart::compiler::target::word
UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- UnhandledException_stacktrace_offset = 16;
+ UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -2607,9 +2607,9 @@
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word Code_InstanceSize = 176;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
@@ -2620,7 +2620,7 @@
static constexpr dart::compiler::target::word Double_InstanceSize = 16;
static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word
ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -2628,11 +2628,11 @@
static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+ 32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 128;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
@@ -2646,9 +2646,9 @@
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
- 120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
+ 64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -2659,18 +2659,18 @@
static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
static constexpr dart::compiler::target::word Number_InstanceSize = 8;
static constexpr dart::compiler::target::word Object_InstanceSize = 8;
static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 104;
+static constexpr dart::compiler::target::word Script_InstanceSize = 72;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
@@ -2679,7 +2679,7 @@
static constexpr dart::compiler::target::word String_InstanceSize = 16;
static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
@@ -2691,25 +2691,25 @@
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
static constexpr dart::compiler::target::word
- WeakSerializationReference_InstanceSize = 24;
+ WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
static constexpr dart::compiler::target::word Function_usage_counter_offset =
- 116;
+ 84;
static constexpr dart::compiler::target::word
ICData_receivers_static_type_offset = 32;
static constexpr dart::compiler::target::word
ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
static constexpr dart::compiler::target::word
- ExceptionHandlers_elements_start_offset = 24;
+ ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
12;
static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -2776,12 +2776,12 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 104;
+ 56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+ 92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- Class_host_type_arguments_field_offset_in_words_offset = 176;
+ Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word
SharedClassTable_class_heap_stats_table_offset = 0;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
@@ -2794,9 +2794,9 @@
static constexpr dart::compiler::target::word
Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_offset = 32;
+ ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_kind_offset = 40;
+ ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word Code_saved_instructions_offset =
48;
@@ -2811,24 +2811,24 @@
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- Field_initializer_function_offset = 32;
+ Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+ Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
-static constexpr dart::compiler::target::word Function_code_offset = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
static constexpr dart::compiler::target::word Function_packed_fields_offset =
- 108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+ 76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
8;
static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -3116,7 +3116,7 @@
static constexpr dart::compiler::target::word
UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- UnhandledException_stacktrace_offset = 16;
+ UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -3147,9 +3147,9 @@
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word Code_InstanceSize = 176;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
@@ -3160,7 +3160,7 @@
static constexpr dart::compiler::target::word Double_InstanceSize = 16;
static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word
ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -3168,11 +3168,11 @@
static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+ 32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 128;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
@@ -3186,9 +3186,9 @@
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
- 120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
+ 64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -3199,18 +3199,18 @@
static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
static constexpr dart::compiler::target::word Number_InstanceSize = 8;
static constexpr dart::compiler::target::word Object_InstanceSize = 8;
static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 104;
+static constexpr dart::compiler::target::word Script_InstanceSize = 72;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
@@ -3219,7 +3219,7 @@
static constexpr dart::compiler::target::word String_InstanceSize = 16;
static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
@@ -3231,13 +3231,13 @@
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
static constexpr dart::compiler::target::word
- WeakSerializationReference_InstanceSize = 24;
+ WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
#else // !defined(PRODUCT)
@@ -5364,14 +5364,14 @@
#if defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
static constexpr dart::compiler::target::word Function_usage_counter_offset =
- 116;
+ 84;
static constexpr dart::compiler::target::word
ICData_receivers_static_type_offset = 32;
static constexpr dart::compiler::target::word
ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
static constexpr dart::compiler::target::word
- ExceptionHandlers_elements_start_offset = 24;
+ ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
12;
static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -5438,12 +5438,12 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 104;
+ 56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+ 92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- Class_host_type_arguments_field_offset_in_words_offset = 176;
+ Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 24;
@@ -5454,9 +5454,9 @@
static constexpr dart::compiler::target::word
Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_offset = 32;
+ ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_kind_offset = 40;
+ ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word Code_saved_instructions_offset =
48;
@@ -5471,24 +5471,24 @@
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- Field_initializer_function_offset = 32;
+ Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+ Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
-static constexpr dart::compiler::target::word Function_code_offset = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
static constexpr dart::compiler::target::word Function_packed_fields_offset =
- 108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+ 76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
8;
static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -5775,7 +5775,7 @@
static constexpr dart::compiler::target::word
UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- UnhandledException_stacktrace_offset = 16;
+ UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -5802,9 +5802,9 @@
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word Code_InstanceSize = 144;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
@@ -5815,7 +5815,7 @@
static constexpr dart::compiler::target::word Double_InstanceSize = 16;
static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word
ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -5823,11 +5823,11 @@
static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+ 32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 128;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
@@ -5841,9 +5841,9 @@
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
- 120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
+ 64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -5854,18 +5854,18 @@
static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
static constexpr dart::compiler::target::word Number_InstanceSize = 8;
static constexpr dart::compiler::target::word Object_InstanceSize = 8;
static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
@@ -5874,7 +5874,7 @@
static constexpr dart::compiler::target::word String_InstanceSize = 16;
static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
@@ -5886,25 +5886,25 @@
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
static constexpr dart::compiler::target::word
- WeakSerializationReference_InstanceSize = 24;
+ WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
static constexpr dart::compiler::target::word Function_usage_counter_offset =
- 116;
+ 84;
static constexpr dart::compiler::target::word
ICData_receivers_static_type_offset = 32;
static constexpr dart::compiler::target::word
ContextScope_elements_start_offset = 16;
-static constexpr dart::compiler::target::word ContextScope_element_size = 64;
+static constexpr dart::compiler::target::word ContextScope_element_size = 32;
static constexpr dart::compiler::target::word
- ExceptionHandlers_elements_start_offset = 24;
+ ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_element_size =
12;
static constexpr dart::compiler::target::word ObjectPool_elements_start_offset =
@@ -5971,12 +5971,12 @@
static constexpr dart::compiler::target::word Array_tags_offset = 0;
static constexpr dart::compiler::target::word Array_type_arguments_offset = 8;
static constexpr dart::compiler::target::word Class_declaration_type_offset =
- 104;
+ 56;
static constexpr dart::compiler::target::word Class_num_type_arguments_offset =
- 164;
-static constexpr dart::compiler::target::word Class_super_type_offset = 88;
+ 92;
+static constexpr dart::compiler::target::word Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- Class_host_type_arguments_field_offset_in_words_offset = 176;
+ Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word Closure_context_offset = 40;
static constexpr dart::compiler::target::word
Closure_delayed_type_arguments_offset = 24;
@@ -5987,9 +5987,9 @@
static constexpr dart::compiler::target::word
Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_offset = 32;
+ ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- ClosureData_default_type_arguments_kind_offset = 40;
+ ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word Code_saved_instructions_offset =
48;
@@ -6004,24 +6004,24 @@
static constexpr dart::compiler::target::word Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- Field_initializer_function_offset = 32;
+ Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word Field_guarded_cid_offset = 80;
+ Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word Field_guarded_cid_offset = 48;
static constexpr dart::compiler::target::word
- Field_guarded_list_length_in_object_offset_offset = 88;
+ Field_guarded_list_length_in_object_offset_offset = 56;
static constexpr dart::compiler::target::word Field_guarded_list_length_offset =
- 48;
-static constexpr dart::compiler::target::word Field_is_nullable_offset = 82;
-static constexpr dart::compiler::target::word Field_kind_bits_offset = 90;
-static constexpr dart::compiler::target::word Function_code_offset = 72;
-static constexpr dart::compiler::target::word Function_data_offset = 56;
+ 28;
+static constexpr dart::compiler::target::word Field_is_nullable_offset = 50;
+static constexpr dart::compiler::target::word Field_kind_bits_offset = 58;
+static constexpr dart::compiler::target::word Function_code_offset = 48;
+static constexpr dart::compiler::target::word Function_data_offset = 40;
static constexpr dart::compiler::target::word Function_entry_point_offset[] = {
8, 16};
-static constexpr dart::compiler::target::word Function_kind_tag_offset = 104;
+static constexpr dart::compiler::target::word Function_kind_tag_offset = 72;
static constexpr dart::compiler::target::word Function_packed_fields_offset =
- 108;
-static constexpr dart::compiler::target::word Function_signature_offset = 48;
+ 76;
+static constexpr dart::compiler::target::word Function_signature_offset = 36;
static constexpr dart::compiler::target::word FutureOr_type_arguments_offset =
8;
static constexpr dart::compiler::target::word GrowableObjectArray_data_offset =
@@ -6308,7 +6308,7 @@
static constexpr dart::compiler::target::word
UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- UnhandledException_stacktrace_offset = 16;
+ UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -6336,9 +6336,9 @@
static constexpr dart::compiler::target::word Array_header_size = 24;
static constexpr dart::compiler::target::word Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word Class_InstanceSize = 200;
+static constexpr dart::compiler::target::word Class_InstanceSize = 128;
static constexpr dart::compiler::target::word Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word Code_InstanceSize = 144;
static constexpr dart::compiler::target::word CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word CompressedStackMaps_HeaderSize =
@@ -6349,7 +6349,7 @@
static constexpr dart::compiler::target::word Double_InstanceSize = 16;
static constexpr dart::compiler::target::word DynamicLibrary_InstanceSize = 16;
static constexpr dart::compiler::target::word ExceptionHandlers_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word
ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -6357,11 +6357,11 @@
static constexpr dart::compiler::target::word ExternalTypedData_InstanceSize =
24;
static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word Field_InstanceSize = 96;
+ 32;
+static constexpr dart::compiler::target::word Field_InstanceSize = 64;
static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word Function_InstanceSize = 128;
+static constexpr dart::compiler::target::word Function_InstanceSize = 96;
static constexpr dart::compiler::target::word FunctionType_InstanceSize = 72;
static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16;
static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize =
@@ -6375,9 +6375,9 @@
static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
- 120;
-static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 160;
+ 64;
+static constexpr dart::compiler::target::word LanguageError_InstanceSize = 32;
+static constexpr dart::compiler::target::word Library_InstanceSize = 104;
static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -6388,18 +6388,18 @@
static constexpr dart::compiler::target::word MirrorReference_InstanceSize = 16;
static constexpr dart::compiler::target::word
MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word NativeArguments_StructSize = 32;
static constexpr dart::compiler::target::word Number_InstanceSize = 8;
static constexpr dart::compiler::target::word Object_InstanceSize = 8;
static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16;
-static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48;
+static constexpr dart::compiler::target::word PatchClass_InstanceSize = 32;
static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word Script_InstanceSize = 64;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
32;
@@ -6408,7 +6408,7 @@
static constexpr dart::compiler::target::word String_InstanceSize = 16;
static constexpr dart::compiler::target::word SubtypeTestCache_InstanceSize =
16;
-static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word TwoByteString_InstanceSize = 16;
@@ -6420,13 +6420,13 @@
static constexpr dart::compiler::target::word TypedDataBase_InstanceSize = 24;
static constexpr dart::compiler::target::word TypedDataView_InstanceSize = 40;
static constexpr dart::compiler::target::word UnhandledException_InstanceSize =
- 24;
+ 16;
static constexpr dart::compiler::target::word UnlinkedCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word WeakProperty_InstanceSize = 32;
static constexpr dart::compiler::target::word
- WeakSerializationReference_InstanceSize = 24;
+ WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
#endif // !defined(PRODUCT)
@@ -8231,9 +8231,9 @@
static constexpr dart::compiler::target::word
AOT_ContextScope_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
- 64;
+ 32;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_elements_start_offset = 24;
+ AOT_ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word
AOT_ExceptionHandlers_element_size = 12;
static constexpr dart::compiler::target::word
@@ -8305,12 +8305,12 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 104;
+ AOT_Class_declaration_type_offset = 56;
static constexpr dart::compiler::target::word
- AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+ AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+ AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word
AOT_SharedClassTable_class_heap_stats_table_offset = 0;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
@@ -8323,9 +8323,9 @@
static constexpr dart::compiler::target::word
AOT_Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_offset = 32;
+ AOT_ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_kind_offset = 40;
+ AOT_ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word
AOT_Code_saved_instructions_offset = 48;
@@ -8341,25 +8341,25 @@
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Field_initializer_function_offset = 32;
+ AOT_Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+ AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+ AOT_Field_guarded_list_length_in_object_offset_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+ AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
static constexpr dart::compiler::target::word
- AOT_Function_packed_fields_offset = 84;
+ AOT_Function_packed_fields_offset = 56;
static constexpr dart::compiler::target::word AOT_Function_signature_offset =
- 48;
+ 36;
static constexpr dart::compiler::target::word
AOT_FutureOr_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
@@ -8682,7 +8682,7 @@
static constexpr dart::compiler::target::word
AOT_UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_stacktrace_offset = 16;
+ AOT_UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -8716,9 +8716,9 @@
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 152;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word
@@ -8731,7 +8731,7 @@
static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
16;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_InstanceSize = 24;
+ AOT_ExceptionHandlers_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -8739,11 +8739,11 @@
static constexpr dart::compiler::target::word
AOT_ExternalTypedData_InstanceSize = 24;
static constexpr dart::compiler::target::word
- AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+ AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
72;
static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
@@ -8758,10 +8758,10 @@
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word
- AOT_KernelProgramInfo_InstanceSize = 120;
+ AOT_KernelProgramInfo_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+ 32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
40;
static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -8775,7 +8775,7 @@
16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
32;
static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -8783,12 +8783,12 @@
static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
@@ -8797,7 +8797,7 @@
static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
@@ -8814,24 +8814,24 @@
static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
40;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_InstanceSize = 24;
+ AOT_UnhandledException_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
32;
static constexpr dart::compiler::target::word
- AOT_WeakSerializationReference_InstanceSize = 24;
+ AOT_WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
static constexpr dart::compiler::target::word
AOT_ContextScope_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
- 64;
+ 32;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_elements_start_offset = 24;
+ AOT_ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word
AOT_ExceptionHandlers_element_size = 12;
static constexpr dart::compiler::target::word
@@ -8903,12 +8903,12 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 104;
+ AOT_Class_declaration_type_offset = 56;
static constexpr dart::compiler::target::word
- AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+ AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+ AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word
AOT_SharedClassTable_class_heap_stats_table_offset = 0;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
@@ -8921,9 +8921,9 @@
static constexpr dart::compiler::target::word
AOT_Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_offset = 32;
+ AOT_ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_kind_offset = 40;
+ AOT_ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word
AOT_Code_saved_instructions_offset = 48;
@@ -8939,25 +8939,25 @@
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Field_initializer_function_offset = 32;
+ AOT_Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+ AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+ AOT_Field_guarded_list_length_in_object_offset_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+ AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
static constexpr dart::compiler::target::word
- AOT_Function_packed_fields_offset = 84;
+ AOT_Function_packed_fields_offset = 56;
static constexpr dart::compiler::target::word AOT_Function_signature_offset =
- 48;
+ 36;
static constexpr dart::compiler::target::word
AOT_FutureOr_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
@@ -9280,7 +9280,7 @@
static constexpr dart::compiler::target::word
AOT_UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_stacktrace_offset = 16;
+ AOT_UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -9315,9 +9315,9 @@
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 152;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word
@@ -9330,7 +9330,7 @@
static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
16;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_InstanceSize = 24;
+ AOT_ExceptionHandlers_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -9338,11 +9338,11 @@
static constexpr dart::compiler::target::word
AOT_ExternalTypedData_InstanceSize = 24;
static constexpr dart::compiler::target::word
- AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+ AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
72;
static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
@@ -9357,10 +9357,10 @@
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word
- AOT_KernelProgramInfo_InstanceSize = 120;
+ AOT_KernelProgramInfo_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+ 32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
40;
static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -9374,7 +9374,7 @@
16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
32;
static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -9382,12 +9382,12 @@
static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
@@ -9396,7 +9396,7 @@
static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
@@ -9413,15 +9413,15 @@
static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
40;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_InstanceSize = 24;
+ AOT_UnhandledException_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
32;
static constexpr dart::compiler::target::word
- AOT_WeakSerializationReference_InstanceSize = 24;
+ AOT_WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
#else // !defined(PRODUCT)
@@ -11203,9 +11203,9 @@
static constexpr dart::compiler::target::word
AOT_ContextScope_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
- 64;
+ 32;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_elements_start_offset = 24;
+ AOT_ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word
AOT_ExceptionHandlers_element_size = 12;
static constexpr dart::compiler::target::word
@@ -11277,12 +11277,12 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 104;
+ AOT_Class_declaration_type_offset = 56;
static constexpr dart::compiler::target::word
- AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+ AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+ AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 24;
@@ -11293,9 +11293,9 @@
static constexpr dart::compiler::target::word
AOT_Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_offset = 32;
+ AOT_ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_kind_offset = 40;
+ AOT_ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word
AOT_Code_saved_instructions_offset = 48;
@@ -11311,25 +11311,25 @@
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Field_initializer_function_offset = 32;
+ AOT_Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+ AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+ AOT_Field_guarded_list_length_in_object_offset_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+ AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
static constexpr dart::compiler::target::word
- AOT_Function_packed_fields_offset = 84;
+ AOT_Function_packed_fields_offset = 56;
static constexpr dart::compiler::target::word AOT_Function_signature_offset =
- 48;
+ 36;
static constexpr dart::compiler::target::word
AOT_FutureOr_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
@@ -11650,7 +11650,7 @@
static constexpr dart::compiler::target::word
AOT_UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_stacktrace_offset = 16;
+ AOT_UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -11681,9 +11681,9 @@
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 120;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word
@@ -11696,7 +11696,7 @@
static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
16;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_InstanceSize = 24;
+ AOT_ExceptionHandlers_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -11704,11 +11704,11 @@
static constexpr dart::compiler::target::word
AOT_ExternalTypedData_InstanceSize = 24;
static constexpr dart::compiler::target::word
- AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+ AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
72;
static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
@@ -11723,10 +11723,10 @@
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word
- AOT_KernelProgramInfo_InstanceSize = 120;
+ AOT_KernelProgramInfo_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+ 32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
40;
static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -11740,7 +11740,7 @@
16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
32;
static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -11748,12 +11748,12 @@
static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
@@ -11762,7 +11762,7 @@
static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
@@ -11779,24 +11779,24 @@
static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
40;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_InstanceSize = 24;
+ AOT_UnhandledException_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
32;
static constexpr dart::compiler::target::word
- AOT_WeakSerializationReference_InstanceSize = 24;
+ AOT_WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_X64) && defined(DART_COMPRESSED_POINTERS)
#if defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
static constexpr dart::compiler::target::word
AOT_ContextScope_elements_start_offset = 16;
static constexpr dart::compiler::target::word AOT_ContextScope_element_size =
- 64;
+ 32;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_elements_start_offset = 24;
+ AOT_ExceptionHandlers_elements_start_offset = 16;
static constexpr dart::compiler::target::word
AOT_ExceptionHandlers_element_size = 12;
static constexpr dart::compiler::target::word
@@ -11868,12 +11868,12 @@
static constexpr dart::compiler::target::word AOT_Array_type_arguments_offset =
8;
static constexpr dart::compiler::target::word
- AOT_Class_declaration_type_offset = 104;
+ AOT_Class_declaration_type_offset = 56;
static constexpr dart::compiler::target::word
- AOT_Class_num_type_arguments_offset = 164;
-static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 88;
+ AOT_Class_num_type_arguments_offset = 92;
+static constexpr dart::compiler::target::word AOT_Class_super_type_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Class_host_type_arguments_field_offset_in_words_offset = 176;
+ AOT_Class_host_type_arguments_field_offset_in_words_offset = 104;
static constexpr dart::compiler::target::word AOT_Closure_context_offset = 40;
static constexpr dart::compiler::target::word
AOT_Closure_delayed_type_arguments_offset = 24;
@@ -11884,9 +11884,9 @@
static constexpr dart::compiler::target::word
AOT_Closure_instantiator_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_offset = 32;
+ AOT_ClosureData_default_type_arguments_offset = 20;
static constexpr dart::compiler::target::word
- AOT_ClosureData_default_type_arguments_kind_offset = 40;
+ AOT_ClosureData_default_type_arguments_kind_offset = 24;
static constexpr dart::compiler::target::word AOT_Code_object_pool_offset = 40;
static constexpr dart::compiler::target::word
AOT_Code_saved_instructions_offset = 48;
@@ -11902,25 +11902,25 @@
static constexpr dart::compiler::target::word AOT_Float32x4_value_offset = 8;
static constexpr dart::compiler::target::word AOT_Float64x2_value_offset = 8;
static constexpr dart::compiler::target::word
- AOT_Field_initializer_function_offset = 32;
+ AOT_Field_initializer_function_offset = 20;
static constexpr dart::compiler::target::word
- AOT_Field_host_offset_or_field_id_offset = 40;
-static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 72;
+ AOT_Field_host_offset_or_field_id_offset = 24;
+static constexpr dart::compiler::target::word AOT_Field_guarded_cid_offset = 44;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_in_object_offset_offset = 76;
+ AOT_Field_guarded_list_length_in_object_offset_offset = 48;
static constexpr dart::compiler::target::word
- AOT_Field_guarded_list_length_offset = 48;
-static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 74;
-static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 78;
-static constexpr dart::compiler::target::word AOT_Function_code_offset = 72;
-static constexpr dart::compiler::target::word AOT_Function_data_offset = 56;
+ AOT_Field_guarded_list_length_offset = 28;
+static constexpr dart::compiler::target::word AOT_Field_is_nullable_offset = 46;
+static constexpr dart::compiler::target::word AOT_Field_kind_bits_offset = 50;
+static constexpr dart::compiler::target::word AOT_Function_code_offset = 48;
+static constexpr dart::compiler::target::word AOT_Function_data_offset = 40;
static constexpr dart::compiler::target::word
AOT_Function_entry_point_offset[] = {8, 16};
-static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 80;
+static constexpr dart::compiler::target::word AOT_Function_kind_tag_offset = 52;
static constexpr dart::compiler::target::word
- AOT_Function_packed_fields_offset = 84;
+ AOT_Function_packed_fields_offset = 56;
static constexpr dart::compiler::target::word AOT_Function_signature_offset =
- 48;
+ 36;
static constexpr dart::compiler::target::word
AOT_FutureOr_type_arguments_offset = 8;
static constexpr dart::compiler::target::word
@@ -12241,7 +12241,7 @@
static constexpr dart::compiler::target::word
AOT_UnhandledException_exception_offset = 8;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_stacktrace_offset = 16;
+ AOT_UnhandledException_stacktrace_offset = 12;
static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -12273,9 +12273,9 @@
static constexpr dart::compiler::target::word AOT_Array_header_size = 24;
static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 184;
+static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112;
static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56;
-static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 48;
+static constexpr dart::compiler::target::word AOT_ClosureData_InstanceSize = 32;
static constexpr dart::compiler::target::word AOT_Code_InstanceSize = 120;
static constexpr dart::compiler::target::word AOT_CodeSourceMap_HeaderSize = 16;
static constexpr dart::compiler::target::word
@@ -12288,7 +12288,7 @@
static constexpr dart::compiler::target::word AOT_DynamicLibrary_InstanceSize =
16;
static constexpr dart::compiler::target::word
- AOT_ExceptionHandlers_InstanceSize = 24;
+ AOT_ExceptionHandlers_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_ExternalOneByteString_InstanceSize = 32;
static constexpr dart::compiler::target::word
@@ -12296,11 +12296,11 @@
static constexpr dart::compiler::target::word
AOT_ExternalTypedData_InstanceSize = 24;
static constexpr dart::compiler::target::word
- AOT_FfiTrampolineData_InstanceSize = 48;
-static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 80;
+ AOT_FfiTrampolineData_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_Field_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_Float32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Float64x2_InstanceSize = 24;
-static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Function_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_FunctionType_InstanceSize =
72;
static constexpr dart::compiler::target::word AOT_FutureOr_InstanceSize = 16;
@@ -12315,10 +12315,10 @@
static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8;
static constexpr dart::compiler::target::word
- AOT_KernelProgramInfo_InstanceSize = 120;
+ AOT_KernelProgramInfo_InstanceSize = 64;
static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
- 48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152;
+ 32;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 96;
static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
40;
static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -12332,7 +12332,7 @@
16;
static constexpr dart::compiler::target::word
AOT_MonomorphicSmiableCall_InstanceSize = 32;
-static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_Namespace_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_NativeArguments_StructSize =
32;
static constexpr dart::compiler::target::word AOT_Number_InstanceSize = 8;
@@ -12340,12 +12340,12 @@
static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize =
16;
-static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40;
+static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16;
static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_ReceivePort_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 88;
+static constexpr dart::compiler::target::word AOT_Script_InstanceSize = 56;
static constexpr dart::compiler::target::word AOT_SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_SingleTargetCache_InstanceSize = 32;
@@ -12354,7 +12354,7 @@
static constexpr dart::compiler::target::word AOT_String_InstanceSize = 16;
static constexpr dart::compiler::target::word
AOT_SubtypeTestCache_InstanceSize = 16;
-static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 32;
+static constexpr dart::compiler::target::word AOT_LoadingUnit_InstanceSize = 24;
static constexpr dart::compiler::target::word
AOT_TransferableTypedData_InstanceSize = 8;
static constexpr dart::compiler::target::word AOT_TwoByteString_InstanceSize =
@@ -12371,15 +12371,15 @@
static constexpr dart::compiler::target::word AOT_TypedDataView_InstanceSize =
40;
static constexpr dart::compiler::target::word
- AOT_UnhandledException_InstanceSize = 24;
+ AOT_UnhandledException_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UnlinkedCall_InstanceSize =
32;
-static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 24;
+static constexpr dart::compiler::target::word AOT_UnwindError_InstanceSize = 16;
static constexpr dart::compiler::target::word AOT_UserTag_InstanceSize = 24;
static constexpr dart::compiler::target::word AOT_WeakProperty_InstanceSize =
32;
static constexpr dart::compiler::target::word
- AOT_WeakSerializationReference_InstanceSize = 24;
+ AOT_WeakSerializationReference_InstanceSize = 16;
#endif // defined(TARGET_ARCH_ARM64) && defined(DART_COMPRESSED_POINTERS)
#endif // !defined(PRODUCT)
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 76492e7..03356ae 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -79,12 +79,12 @@
InitInstanceFieldABI::kResultReg == CallingConventions::kReturnReg,
"Result is a return value from initializer");
- __ LoadField(kFunctionReg,
- FieldAddress(InitInstanceFieldABI::kFieldReg,
- target::Field::initializer_function_offset()));
+ __ LoadCompressedFieldFromOffset(
+ kFunctionReg, InitInstanceFieldABI::kFieldReg,
+ target::Field::initializer_function_offset());
if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) {
- __ LoadField(CODE_REG,
- FieldAddress(kFunctionReg, target::Function::code_offset()));
+ __ LoadCompressedFieldFromOffset(CODE_REG, kFunctionReg,
+ target::Function::code_offset());
// Load a GC-safe value for the arguments descriptor (unused but tagged).
__ LoadImmediate(ARGS_DESC_REG, 0);
}
@@ -92,9 +92,14 @@
__ Drop(1); // Drop argument.
__ PopRegisterPair(kInstanceReg, kFieldReg);
- __ LoadField(
- kScratchReg,
- FieldAddress(kFieldReg, target::Field::host_offset_or_field_id_offset()));
+ __ LoadCompressedFieldFromOffset(
+ kScratchReg, kFieldReg, target::Field::host_offset_or_field_id_offset());
+#if defined(DART_COMPRESSED_POINTERS)
+ // TODO(compressed-pointers): Variant of LoadFieldAddressForRegOffset that
+ // ignores upper bits?
+ __ SmiUntag(kScratchReg);
+ __ SmiTag(kScratchReg);
+#endif
__ LoadFieldAddressForRegOffset(kAddressReg, kInstanceReg, kScratchReg);
Label throw_exception;
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index c8df259..e6f79d9 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -2468,7 +2468,8 @@
__ Comment("Call target");
__ Bind(&call_target_function);
// R0: target function.
- __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+ __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+ target::Function::code_offset());
if (save_entry_point) {
__ add(R2, R0, Operand(R8));
__ ldr(R2, Address(R2, 0));
@@ -2649,7 +2650,8 @@
// Get function and call it, if possible.
__ LoadFromOffset(R0, R6, target_offset);
- __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+ __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+ target::Function::code_offset());
__ add(R2, R0, Operand(R8));
__ ldr(R2, Address(R2, 0));
__ br(R2);
@@ -2703,7 +2705,8 @@
__ Pop(R4); // Restore arg desc.
__ LeaveStubFrame();
- __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+ __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+ target::Function::code_offset());
__ LoadFieldFromOffset(R2, R0, target::Function::entry_point_offset());
__ br(R2);
}
@@ -3103,7 +3106,8 @@
__ Pop(R0); // Discard argument.
__ Pop(R0); // Get Function object
__ Pop(R4); // Restore argument descriptor.
- __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset());
+ __ LoadCompressedFieldFromOffset(CODE_REG, R0,
+ target::Function::code_offset());
__ LoadFieldFromOffset(R1, R0, target::Function::entry_point_offset());
__ LeaveStubFrame();
__ br(R1);
@@ -3263,7 +3267,8 @@
__ ldr(
ARGS_DESC_REG,
FieldAddress(R5, target::CallSiteData::arguments_descriptor_offset()));
- __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(R0, target::Function::code_offset()));
}
__ br(R1);
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 2929038..a6425ad 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -2404,7 +2404,8 @@
__ Comment("Call target (via specified entry point)");
__ Bind(&call_target_function);
// RAX: Target function.
- __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(RAX, target::Function::code_offset()));
if (save_entry_point) {
__ addq(R8, RAX);
__ jmp(Address(R8, 0));
@@ -2421,7 +2422,8 @@
}
__ Comment("Call target (via unchecked entry point)");
__ movq(RAX, Address(R13, target_offset));
- __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(RAX, target::Function::code_offset()));
__ jmp(FieldAddress(
RAX, target::Function::entry_point_offset(CodeEntryKind::kUnchecked)));
}
@@ -2602,7 +2604,8 @@
// Get function and call it, if possible.
__ movq(RAX, Address(R12, target_offset));
- __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(RAX, target::Function::code_offset()));
__ addq(R8, RAX);
__ jmp(Address(R8, 0));
@@ -2653,7 +2656,8 @@
__ popq(R10); // Restore arguments descriptor array.
__ LeaveStubFrame();
- __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(RAX, target::Function::code_offset()));
__ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
__ jmp(RCX);
}
@@ -3056,7 +3060,8 @@
__ popq(RAX); // Get Code object.
__ popq(R10); // Restore argument descriptor.
__ LeaveStubFrame();
- __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(RAX, target::Function::code_offset()));
__ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
__ jmp(RCX);
__ int3();
@@ -3212,7 +3217,8 @@
__ movq(R10, FieldAddress(
RBX, target::CallSiteData::arguments_descriptor_offset()));
__ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset()));
- __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset()));
+ __ LoadCompressed(CODE_REG,
+ FieldAddress(RAX, target::Function::code_offset()));
__ jmp(RCX);
}
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 5f89dfd..6f0b4c3 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -339,8 +339,8 @@
// of this object. Note this could be a publishing store even if the
// object was promoted by an early invocation of ScavengePointer. Compare
// Object::Allocate.
- reinterpret_cast<std::atomic<ObjectPtr>*>(p)->store(
- new_obj, std::memory_order_release);
+ reinterpret_cast<std::atomic<CompressedObjectPtr>*>(p)->store(
+ static_cast<CompressedObjectPtr>(new_obj), std::memory_order_release);
} else {
*p = new_obj;
}
@@ -907,7 +907,20 @@
void VisitCompressedPointers(uword heap_base,
CompressedObjectPtr* from,
CompressedObjectPtr* to) {
- UNREACHABLE(); // Store buffer blocks are not compressed.
+ for (CompressedObjectPtr* ptr = from; ptr <= to; ptr++) {
+ ObjectPtr raw_obj = ptr->Decompress(heap_base);
+ if (raw_obj->IsHeapObject() && raw_obj->IsNewObject()) {
+ if (!is_remembered_) {
+ FATAL3(
+ "Old object %#" Px " references new object %#" Px
+ ", but it is not"
+ " in any store buffer. Consider using rr to watch the slot %p and"
+ " reverse-continue to find the store with a missing barrier.\n",
+ static_cast<uword>(visiting_), static_cast<uword>(raw_obj), ptr);
+ }
+ RELEASE_ASSERT(to_->Contains(UntaggedObject::ToAddr(raw_obj)));
+ }
+ }
}
private:
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 37da0f5..c47b47e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -529,7 +529,8 @@
uword address = heap->Allocate(Instance::InstanceSize(), Heap::kOld);
null_ = static_cast<InstancePtr>(address + kHeapObjectTag);
// The call below is using 'null_' to initialize itself.
- InitializeObject(address, kNullCid, Instance::InstanceSize());
+ InitializeObject(address, kNullCid, Instance::InstanceSize(),
+ /*compressed*/ false);
null_->untag()->SetCanonical();
}
@@ -540,14 +541,16 @@
{
// Allocate a dummy bool object to give true the desired alignment.
uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
- InitializeObject(address, kBoolCid, Bool::InstanceSize());
+ InitializeObject(address, kBoolCid, Bool::InstanceSize(),
+ /*compressed*/ false);
static_cast<BoolPtr>(address + kHeapObjectTag)->untag()->value_ = false;
}
{
// Allocate true.
uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
true_ = static_cast<BoolPtr>(address + kHeapObjectTag);
- InitializeObject(address, kBoolCid, Bool::InstanceSize());
+ InitializeObject(address, kBoolCid, Bool::InstanceSize(),
+ /*compressed*/ false);
true_->untag()->value_ = true;
true_->untag()->SetCanonical();
}
@@ -555,7 +558,8 @@
// Allocate false.
uword address = heap->Allocate(Bool::InstanceSize(), Heap::kOld);
false_ = static_cast<BoolPtr>(address + kHeapObjectTag);
- InitializeObject(address, kBoolCid, Bool::InstanceSize());
+ InitializeObject(address, kBoolCid, Bool::InstanceSize(),
+ /*compressed*/ false);
false_->untag()->value_ = false;
false_->untag()->SetCanonical();
}
@@ -704,7 +708,7 @@
intptr_t size = Class::InstanceSize();
uword address = heap->Allocate(size, Heap::kOld);
class_class_ = static_cast<ClassPtr>(address + kHeapObjectTag);
- InitializeObject(address, Class::kClassId, size);
+ InitializeObject(address, Class::kClassId, size, /*compressed*/ true);
Class fake;
// Initialization from Class::New<Class>.
@@ -764,19 +768,19 @@
// Allocate and initialize the sentinel values.
{
- *sentinel_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
+ *sentinel_ ^= Object::Allocate(kNeverCid, Instance::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
- *transition_sentinel_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
+ *transition_sentinel_ ^= Object::Allocate(
+ kNeverCid, Instance::InstanceSize(), Heap::kOld, /*compressed*/ false);
}
// Allocate and initialize optimizing compiler constants.
{
- *unknown_constant_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
- *non_constant_ ^=
- Object::Allocate(kNeverCid, Instance::InstanceSize(), Heap::kOld);
+ *unknown_constant_ ^= Object::Allocate(kNeverCid, Instance::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
+ *non_constant_ ^= Object::Allocate(kNeverCid, Instance::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
}
// Allocate the remaining VM internal classes.
@@ -926,7 +930,8 @@
// Allocate and initialize the empty_array instance.
{
uword address = heap->Allocate(Array::InstanceSize(0), Heap::kOld);
- InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0));
+ InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(0),
+ /*compressed*/ false);
Array::initializeHandle(empty_array_,
static_cast<ArrayPtr>(address + kHeapObjectTag));
empty_array_->untag()->set_length(Smi::New(0));
@@ -937,7 +942,8 @@
// Allocate and initialize the zero_array instance.
{
uword address = heap->Allocate(Array::InstanceSize(1), Heap::kOld);
- InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1));
+ InitializeObject(address, kImmutableArrayCid, Array::InstanceSize(1),
+ /*compressed*/ false);
Array::initializeHandle(zero_array_,
static_cast<ArrayPtr>(address + kHeapObjectTag));
zero_array_->untag()->set_length(Smi::New(1));
@@ -949,7 +955,8 @@
// Allocate and initialize the canonical empty context scope object.
{
uword address = heap->Allocate(ContextScope::InstanceSize(0), Heap::kOld);
- InitializeObject(address, kContextScopeCid, ContextScope::InstanceSize(0));
+ InitializeObject(address, kContextScopeCid, ContextScope::InstanceSize(0),
+ /*compressed*/ true);
ContextScope::initializeHandle(
empty_context_scope_,
static_cast<ContextScopePtr>(address + kHeapObjectTag));
@@ -963,7 +970,8 @@
// Allocate and initialize the canonical empty object pool object.
{
uword address = heap->Allocate(ObjectPool::InstanceSize(0), Heap::kOld);
- InitializeObject(address, kObjectPoolCid, ObjectPool::InstanceSize(0));
+ InitializeObject(address, kObjectPoolCid, ObjectPool::InstanceSize(0),
+ /*compressed*/ false);
ObjectPool::initializeHandle(
empty_object_pool_,
static_cast<ObjectPoolPtr>(address + kHeapObjectTag));
@@ -976,7 +984,8 @@
{
const intptr_t instance_size = CompressedStackMaps::InstanceSize(0);
uword address = heap->Allocate(instance_size, Heap::kOld);
- InitializeObject(address, kCompressedStackMapsCid, instance_size);
+ InitializeObject(address, kCompressedStackMapsCid, instance_size,
+ /*compressed*/ true);
CompressedStackMaps::initializeHandle(
empty_compressed_stackmaps_,
static_cast<CompressedStackMapsPtr>(address + kHeapObjectTag));
@@ -988,8 +997,8 @@
// Allocate and initialize the empty_descriptors instance.
{
uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld);
- InitializeObject(address, kPcDescriptorsCid,
- PcDescriptors::InstanceSize(0));
+ InitializeObject(address, kPcDescriptorsCid, PcDescriptors::InstanceSize(0),
+ /*compressed*/ true);
PcDescriptors::initializeHandle(
empty_descriptors_,
static_cast<PcDescriptorsPtr>(address + kHeapObjectTag));
@@ -1003,7 +1012,7 @@
uword address =
heap->Allocate(LocalVarDescriptors::InstanceSize(0), Heap::kOld);
InitializeObject(address, kLocalVarDescriptorsCid,
- LocalVarDescriptors::InstanceSize(0));
+ LocalVarDescriptors::InstanceSize(0), /*compressed*/ true);
LocalVarDescriptors::initializeHandle(
empty_var_descriptors_,
static_cast<LocalVarDescriptorsPtr>(address + kHeapObjectTag));
@@ -1019,7 +1028,7 @@
uword address =
heap->Allocate(ExceptionHandlers::InstanceSize(0), Heap::kOld);
InitializeObject(address, kExceptionHandlersCid,
- ExceptionHandlers::InstanceSize(0));
+ ExceptionHandlers::InstanceSize(0), /*compressed*/ true);
ExceptionHandlers::initializeHandle(
empty_exception_handlers_,
static_cast<ExceptionHandlersPtr>(address + kHeapObjectTag));
@@ -1031,8 +1040,8 @@
// Allocate and initialize the canonical empty type arguments object.
{
uword address = heap->Allocate(TypeArguments::InstanceSize(0), Heap::kOld);
- InitializeObject(address, kTypeArgumentsCid,
- TypeArguments::InstanceSize(0));
+ InitializeObject(address, kTypeArgumentsCid, TypeArguments::InstanceSize(0),
+ /*compressed*/ false);
TypeArguments::initializeHandle(
empty_type_arguments_,
static_cast<TypeArgumentsPtr>(address + kHeapObjectTag));
@@ -2492,7 +2501,10 @@
return String::null();
}
-void Object::InitializeObject(uword address, intptr_t class_id, intptr_t size) {
+void Object::InitializeObject(uword address,
+ intptr_t class_id,
+ intptr_t size,
+ bool compressed) {
// Note: we skip the header word here to avoid a racy read in the concurrent
// marker from observing the null object when it reads into a heap page
// allocated after marking started.
@@ -2520,6 +2532,12 @@
#endif
} else {
initial_value = static_cast<uword>(null_);
+#if defined(DART_COMPRESSED_POINTERS)
+ if (compressed) {
+ initial_value &= 0xFFFFFFFF;
+ initial_value |= initial_value << 32;
+ }
+#endif
needs_init = true;
}
if (needs_init) {
@@ -2576,7 +2594,10 @@
#endif
}
-ObjectPtr Object::Allocate(intptr_t cls_id, intptr_t size, Heap::Space space) {
+ObjectPtr Object::Allocate(intptr_t cls_id,
+ intptr_t size,
+ Heap::Space space,
+ bool compressed) {
ASSERT(Utils::IsAligned(size, kObjectAlignment));
Thread* thread = Thread::Current();
ASSERT(thread->execution_state() == Thread::kThreadInVM);
@@ -2606,7 +2627,7 @@
}
NoSafepointScope no_safepoint;
ObjectPtr raw_obj;
- InitializeObject(address, cls_id, size);
+ InitializeObject(address, cls_id, size, compressed);
raw_obj = static_cast<ObjectPtr>(address + kHeapObjectTag);
ASSERT(cls_id == UntaggedObject::ClassIdTag::decode(raw_obj->untag()->tags_));
if (raw_obj->IsOldObject() && UNLIKELY(thread->is_marking())) {
@@ -2697,7 +2718,8 @@
ObjectPtr Object::Clone(const Object& orig, Heap::Space space) {
const Class& cls = Class::Handle(orig.clazz());
intptr_t size = orig.ptr()->untag()->HeapSize();
- ObjectPtr raw_clone = Object::Allocate(cls.id(), size, space);
+ ObjectPtr raw_clone =
+ Object::Allocate(cls.id(), size, space, /*compressed*/ false);
NoSafepointScope no_safepoint;
// Copy the body of the original into the clone.
uword orig_addr = UntaggedObject::ToAddr(orig.ptr());
@@ -2795,8 +2817,8 @@
ASSERT(Object::class_class() != Class::null());
Class& result = Class::Handle();
{
- ObjectPtr raw =
- Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Class::kClassId, Class::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -4499,8 +4521,8 @@
ASSERT(Object::class_class() != Class::null());
Class& result = Class::Handle();
{
- ObjectPtr raw =
- Object::Allocate(Class::kClassId, Class::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Class::kClassId, Class::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -6621,7 +6643,8 @@
TypeArguments& result = TypeArguments::Handle();
{
ObjectPtr raw = Object::Allocate(TypeArguments::kClassId,
- TypeArguments::InstanceSize(len), space);
+ TypeArguments::InstanceSize(len), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
// Length must be set before we start storing into the array.
@@ -6765,8 +6788,9 @@
PatchClassPtr PatchClass::New() {
ASSERT(Object::patch_class_class() != Class::null());
- ObjectPtr raw = Object::Allocate(PatchClass::kClassId,
- PatchClass::InstanceSize(), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(PatchClass::kClassId, PatchClass::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<PatchClassPtr>(raw);
}
@@ -8678,8 +8702,8 @@
FunctionPtr Function::New(Heap::Space space) {
ASSERT(Object::function_class() != Class::null());
- ObjectPtr raw =
- Object::Allocate(Function::kClassId, Function::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Function::kClassId, Function::InstanceSize(),
+ space, /*compressed*/ true);
return static_cast<FunctionPtr>(raw);
}
@@ -9908,8 +9932,9 @@
ClosureDataPtr ClosureData::New() {
ASSERT(Object::closure_data_class() != Class::null());
- ObjectPtr raw = Object::Allocate(ClosureData::kClassId,
- ClosureData::InstanceSize(), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(ClosureData::kClassId, ClosureData::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<ClosureDataPtr>(raw);
}
@@ -9991,8 +10016,9 @@
}
FunctionTypePtr FunctionType::New(Heap::Space space) {
- ObjectPtr raw = Object::Allocate(FunctionType::kClassId,
- FunctionType::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(FunctionType::kClassId, FunctionType::InstanceSize(),
+ space, /*compressed*/ false);
return static_cast<FunctionTypePtr>(raw);
}
@@ -10082,9 +10108,9 @@
FfiTrampolineDataPtr FfiTrampolineData::New() {
ASSERT(Object::ffi_trampoline_data_class() != Class::null());
- ObjectPtr raw =
- Object::Allocate(FfiTrampolineData::kClassId,
- FfiTrampolineData::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(FfiTrampolineData::kClassId,
+ FfiTrampolineData::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
FfiTrampolineDataPtr data = static_cast<FfiTrampolineDataPtr>(raw);
data->untag()->callback_id_ = 0;
return data;
@@ -10342,8 +10368,8 @@
FieldPtr Field::New() {
ASSERT(Object::field_class() != Class::null());
- ObjectPtr raw =
- Object::Allocate(Field::kClassId, Field::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Field::kClassId, Field::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<FieldPtr>(raw);
}
@@ -11761,8 +11787,8 @@
ScriptPtr Script::New() {
ASSERT(Object::script_class() != Class::null());
- ObjectPtr raw =
- Object::Allocate(Script::kClassId, Script::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Script::kClassId, Script::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<ScriptPtr>(raw);
}
@@ -12821,8 +12847,8 @@
LibraryPtr Library::New() {
ASSERT(Object::library_class() != Class::null());
- ObjectPtr raw =
- Object::Allocate(Library::kClassId, Library::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Library::kClassId, Library::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<LibraryPtr>(raw);
}
@@ -13527,8 +13553,9 @@
}
LibraryPrefixPtr LibraryPrefix::New() {
- ObjectPtr raw = Object::Allocate(LibraryPrefix::kClassId,
- LibraryPrefix::InstanceSize(), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(LibraryPrefix::kClassId, LibraryPrefix::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
return static_cast<LibraryPrefixPtr>(raw);
}
@@ -13682,8 +13709,9 @@
NamespacePtr Namespace::New() {
ASSERT(Object::namespace_class() != Class::null());
- ObjectPtr raw = Object::Allocate(Namespace::kClassId,
- Namespace::InstanceSize(), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(Namespace::kClassId, Namespace::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<NamespacePtr>(raw);
}
@@ -13702,9 +13730,9 @@
}
KernelProgramInfoPtr KernelProgramInfo::New() {
- ObjectPtr raw =
- Object::Allocate(KernelProgramInfo::kClassId,
- KernelProgramInfo::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(KernelProgramInfo::kClassId,
+ KernelProgramInfo::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<KernelProgramInfoPtr>(raw);
}
@@ -14105,8 +14133,8 @@
Instructions& result = Instructions::Handle();
{
uword aligned_size = Instructions::InstanceSize(size);
- ObjectPtr raw =
- Object::Allocate(Instructions::kClassId, aligned_size, Heap::kCode);
+ ObjectPtr raw = Object::Allocate(Instructions::kClassId, aligned_size,
+ Heap::kCode, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetSize(size);
@@ -14148,7 +14176,8 @@
ObjectPool& result = ObjectPool::Handle();
{
uword size = ObjectPool::InstanceSize(len);
- ObjectPtr raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ObjectPool::kClassId, size, Heap::kOld,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -14263,8 +14292,9 @@
Thread* thread = Thread::Current();
PcDescriptors& result = PcDescriptors::Handle(thread->zone());
{
- ObjectPtr raw = Object::Allocate(
- PcDescriptors::kClassId, PcDescriptors::InstanceSize(size), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId,
+ PcDescriptors::InstanceSize(size),
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(size);
@@ -14279,7 +14309,8 @@
PcDescriptors& result = PcDescriptors::Handle(thread->zone());
{
uword size = PcDescriptors::InstanceSize(length);
- ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld,
+ /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(length);
@@ -14411,7 +14442,8 @@
CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
{
uword size = CodeSourceMap::InstanceSize(length);
- ObjectPtr raw = Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(CodeSourceMap::kClassId, size, Heap::kOld,
+ /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(length);
@@ -14600,9 +14632,9 @@
{
// CompressedStackMaps data objects are associated with a code object,
// allocate them in old generation.
- ObjectPtr raw =
- Object::Allocate(CompressedStackMaps::kClassId,
- CompressedStackMaps::InstanceSize(size), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(CompressedStackMaps::kClassId,
+ CompressedStackMaps::InstanceSize(size),
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(
@@ -14636,8 +14668,8 @@
StringPtr LocalVarDescriptors::GetName(intptr_t var_index) const {
ASSERT(var_index < Length());
- ASSERT(Object::Handle(*ptr()->untag()->nameAddrAt(var_index)).IsString());
- return *ptr()->untag()->nameAddrAt(var_index);
+ ASSERT(Object::Handle(ptr()->untag()->name(var_index)).IsString());
+ return ptr()->untag()->name(var_index);
}
void LocalVarDescriptors::SetVar(
@@ -14646,7 +14678,7 @@
UntaggedLocalVarDescriptors::VarInfo* info) const {
ASSERT(var_index < Length());
ASSERT(!name.IsNull());
- StorePointer(ptr()->untag()->nameAddrAt(var_index), name.ptr());
+ ptr()->untag()->set_name(var_index, name.ptr());
ptr()->untag()->data()[var_index] = *info;
}
@@ -14750,8 +14782,8 @@
LocalVarDescriptors& result = LocalVarDescriptors::Handle();
{
uword size = LocalVarDescriptors::InstanceSize(num_variables);
- ObjectPtr raw =
- Object::Allocate(LocalVarDescriptors::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(LocalVarDescriptors::kClassId, size,
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(&result.untag()->num_entries_, num_variables);
@@ -14851,8 +14883,8 @@
ExceptionHandlers& result = ExceptionHandlers::Handle();
{
uword size = ExceptionHandlers::InstanceSize(num_handlers);
- ObjectPtr raw =
- Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ExceptionHandlers::kClassId, size,
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(&result.untag()->num_entries_, num_handlers);
@@ -14876,8 +14908,8 @@
ExceptionHandlers& result = ExceptionHandlers::Handle();
{
uword size = ExceptionHandlers::InstanceSize(num_handlers);
- ObjectPtr raw =
- Object::Allocate(ExceptionHandlers::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ExceptionHandlers::kClassId, size,
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(&result.untag()->num_entries_, num_handlers);
@@ -14950,9 +14982,9 @@
SingleTargetCache& result = SingleTargetCache::Handle();
{
// IC data objects are long living objects, allocate them in old generation.
- ObjectPtr raw =
- Object::Allocate(SingleTargetCache::kClassId,
- SingleTargetCache::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(SingleTargetCache::kClassId,
+ SingleTargetCache::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -14983,8 +15015,9 @@
UnlinkedCallPtr UnlinkedCall::New() {
UnlinkedCall& result = UnlinkedCall::Handle();
- result ^= Object::Allocate(UnlinkedCall::kClassId,
- UnlinkedCall::InstanceSize(), Heap::kOld);
+ result ^=
+ Object::Allocate(UnlinkedCall::kClassId, UnlinkedCall::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
result.set_can_patch_to_monomorphic(!FLAG_precompiled_mode);
return result.ptr();
}
@@ -14992,9 +15025,9 @@
MonomorphicSmiableCallPtr MonomorphicSmiableCall::New(classid_t expected_cid,
const Code& target) {
auto& result = MonomorphicSmiableCall::Handle();
- result ^=
- Object::Allocate(MonomorphicSmiableCall::kClassId,
- MonomorphicSmiableCall::InstanceSize(), Heap::kOld);
+ result ^= Object::Allocate(MonomorphicSmiableCall::kClassId,
+ MonomorphicSmiableCall::InstanceSize(), Heap::kOld,
+ /*compressed*/ false);
result.untag()->set_target(target.ptr());
result.StoreNonPointer(&result.untag()->expected_cid_, expected_cid);
result.StoreNonPointer(&result.untag()->entrypoint_, target.EntryPoint());
@@ -15949,8 +15982,8 @@
ICData& result = ICData::Handle(zone);
{
// IC data objects are long living objects, allocate them in old generation.
- ObjectPtr raw =
- Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ICData::kClassId, ICData::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -15973,8 +16006,8 @@
ICData& result = ICData::Handle();
{
// IC data objects are long living objects, allocate them in old generation.
- ObjectPtr raw =
- Object::Allocate(ICData::kClassId, ICData::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ICData::kClassId, ICData::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -16131,7 +16164,7 @@
{
ObjectPtr raw = Object::Allocate(WeakSerializationReference::kClassId,
WeakSerializationReference::InstanceSize(),
- Heap::kOld);
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
@@ -16565,7 +16598,8 @@
Code& result = Code::Handle();
{
uword size = Code::InstanceSize(pointer_offsets_length);
- ObjectPtr raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Code::kClassId, size, Heap::kOld,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_pointer_offsets_length(pointer_offsets_length);
@@ -17103,8 +17137,9 @@
}
Context& result = Context::Handle();
{
- ObjectPtr raw = Object::Allocate(
- Context::kClassId, Context::InstanceSize(num_variables), space);
+ ObjectPtr raw = Object::Allocate(Context::kClassId,
+ Context::InstanceSize(num_variables),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_num_variables(num_variables);
@@ -17173,7 +17208,8 @@
intptr_t size = ContextScope::InstanceSize(num_variables);
ContextScope& result = ContextScope::Handle();
{
- ObjectPtr raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(ContextScope::kClassId, size, Heap::kOld,
+ /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_num_variables(num_variables);
@@ -17184,50 +17220,49 @@
TokenPosition ContextScope::TokenIndexAt(intptr_t scope_index) const {
return TokenPosition::Deserialize(
- Smi::Value(VariableDescAddr(scope_index)->token_pos));
+ Smi::Value(untag()->token_pos_at(scope_index)));
}
void ContextScope::SetTokenIndexAt(intptr_t scope_index,
TokenPosition token_pos) const {
- StoreSmi(&VariableDescAddr(scope_index)->token_pos,
- Smi::New(token_pos.Serialize()));
+ untag()->set_token_pos_at(scope_index, Smi::New(token_pos.Serialize()));
}
TokenPosition ContextScope::DeclarationTokenIndexAt(
intptr_t scope_index) const {
return TokenPosition::Deserialize(
- Smi::Value(VariableDescAddr(scope_index)->declaration_token_pos));
+ Smi::Value(untag()->declaration_token_pos_at(scope_index)));
}
void ContextScope::SetDeclarationTokenIndexAt(
intptr_t scope_index,
TokenPosition declaration_token_pos) const {
- StoreSmi(&VariableDescAddr(scope_index)->declaration_token_pos,
- Smi::New(declaration_token_pos.Serialize()));
+ untag()->set_declaration_token_pos_at(
+ scope_index, Smi::New(declaration_token_pos.Serialize()));
}
StringPtr ContextScope::NameAt(intptr_t scope_index) const {
- return VariableDescAddr(scope_index)->name;
+ return untag()->name_at(scope_index);
}
void ContextScope::SetNameAt(intptr_t scope_index, const String& name) const {
- StorePointer(&(VariableDescAddr(scope_index)->name), name.ptr());
+ untag()->set_name_at(scope_index, name.ptr());
}
void ContextScope::ClearFlagsAt(intptr_t scope_index) const {
- StoreSmi(&(VariableDescAddr(scope_index)->flags), 0);
+ untag()->set_flags_at(scope_index, Smi::New(0));
}
bool ContextScope::GetFlagAt(intptr_t scope_index, intptr_t mask) const {
- return (Smi::Value(VariableDescAddr(scope_index)->flags) & mask) != 0;
+ return (Smi::Value(untag()->flags_at(scope_index)) & mask) != 0;
}
void ContextScope::SetFlagAt(intptr_t scope_index,
intptr_t mask,
bool value) const {
- intptr_t flags = Smi::Value(VariableDescAddr(scope_index)->flags);
- StoreSmi(&(VariableDescAddr(scope_index)->flags),
- Smi::New(value ? flags | mask : flags & ~mask));
+ intptr_t flags = Smi::Value(untag()->flags_at(scope_index));
+ untag()->set_flags_at(scope_index,
+ Smi::New(value ? flags | mask : flags & ~mask));
}
bool ContextScope::IsFinalAt(intptr_t scope_index) const {
@@ -17257,54 +17292,51 @@
}
intptr_t ContextScope::LateInitOffsetAt(intptr_t scope_index) const {
- return Smi::Value(VariableDescAddr(scope_index)->late_init_offset);
+ return Smi::Value(untag()->late_init_offset_at(scope_index));
}
void ContextScope::SetLateInitOffsetAt(intptr_t scope_index,
intptr_t late_init_offset) const {
- StoreSmi(&(VariableDescAddr(scope_index)->late_init_offset),
- Smi::New(late_init_offset));
+ untag()->set_late_init_offset_at(scope_index, Smi::New(late_init_offset));
}
AbstractTypePtr ContextScope::TypeAt(intptr_t scope_index) const {
ASSERT(!IsConstAt(scope_index));
- return VariableDescAddr(scope_index)->type;
+ return untag()->type_at(scope_index);
}
void ContextScope::SetTypeAt(intptr_t scope_index,
const AbstractType& type) const {
- StorePointer(&(VariableDescAddr(scope_index)->type), type.ptr());
+ untag()->set_type_at(scope_index, type.ptr());
}
InstancePtr ContextScope::ConstValueAt(intptr_t scope_index) const {
ASSERT(IsConstAt(scope_index));
- return VariableDescAddr(scope_index)->value;
+ return untag()->value_at(scope_index);
}
void ContextScope::SetConstValueAt(intptr_t scope_index,
const Instance& value) const {
ASSERT(IsConstAt(scope_index));
- StorePointer(&(VariableDescAddr(scope_index)->value), value.ptr());
+ untag()->set_value_at(scope_index, value.ptr());
}
intptr_t ContextScope::ContextIndexAt(intptr_t scope_index) const {
- return Smi::Value(VariableDescAddr(scope_index)->context_index);
+ return Smi::Value(untag()->context_index_at(scope_index));
}
void ContextScope::SetContextIndexAt(intptr_t scope_index,
intptr_t context_index) const {
- StoreSmi(&(VariableDescAddr(scope_index)->context_index),
- Smi::New(context_index));
+ untag()->set_context_index_at(scope_index, Smi::New(context_index));
}
intptr_t ContextScope::ContextLevelAt(intptr_t scope_index) const {
- return Smi::Value(VariableDescAddr(scope_index)->context_level);
+ return Smi::Value(untag()->context_level_at(scope_index));
}
void ContextScope::SetContextLevelAt(intptr_t scope_index,
intptr_t context_level) const {
- StoreSmi(&(VariableDescAddr(scope_index)->context_level),
- Smi::New(context_level));
+ untag()->set_context_level_at(scope_index, Smi::New(context_level));
}
const char* ContextScope::ToCString() const {
@@ -17355,9 +17387,9 @@
MegamorphicCachePtr MegamorphicCache::New() {
MegamorphicCache& result = MegamorphicCache::Handle();
{
- ObjectPtr raw =
- Object::Allocate(MegamorphicCache::kClassId,
- MegamorphicCache::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(MegamorphicCache::kClassId,
+ MegamorphicCache::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17369,9 +17401,9 @@
const Array& arguments_descriptor) {
MegamorphicCache& result = MegamorphicCache::Handle();
{
- ObjectPtr raw =
- Object::Allocate(MegamorphicCache::kClassId,
- MegamorphicCache::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(MegamorphicCache::kClassId,
+ MegamorphicCache::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17555,9 +17587,9 @@
{
// SubtypeTestCache objects are long living objects, allocate them in the
// old generation.
- ObjectPtr raw =
- Object::Allocate(SubtypeTestCache::kClassId,
- SubtypeTestCache::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(SubtypeTestCache::kClassId,
+ SubtypeTestCache::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17836,8 +17868,9 @@
{
// LoadingUnit objects are long living objects, allocate them in the
// old generation.
- ObjectPtr raw = Object::Allocate(LoadingUnit::kClassId,
- LoadingUnit::InstanceSize(), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(LoadingUnit::kClassId, LoadingUnit::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17910,7 +17943,7 @@
ApiErrorPtr ApiError::New() {
ASSERT(Object::api_error_class() != Class::null());
ObjectPtr raw = Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(),
- Heap::kOld);
+ Heap::kOld, /*compressed*/ true);
return static_cast<ApiErrorPtr>(raw);
}
@@ -17926,7 +17959,8 @@
ApiError& result = ApiError::Handle();
{
ObjectPtr raw =
- Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space);
+ Object::Allocate(ApiError::kClassId, ApiError::InstanceSize(), space,
+ /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -17949,8 +17983,9 @@
LanguageErrorPtr LanguageError::New() {
ASSERT(Object::language_error_class() != Class::null());
- ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
- LanguageError::InstanceSize(), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(LanguageError::kClassId, LanguageError::InstanceSize(),
+ Heap::kOld, /*compressed*/ true);
return static_cast<LanguageErrorPtr>(raw);
}
@@ -17965,8 +18000,9 @@
ASSERT(Object::language_error_class() != Class::null());
LanguageError& result = LanguageError::Handle();
{
- ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
- LanguageError::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(LanguageError::kClassId, LanguageError::InstanceSize(),
+ space, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -18004,8 +18040,9 @@
ASSERT(Object::language_error_class() != Class::null());
LanguageError& result = LanguageError::Handle();
{
- ObjectPtr raw = Object::Allocate(LanguageError::kClassId,
- LanguageError::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(LanguageError::kClassId, LanguageError::InstanceSize(),
+ space, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -18076,7 +18113,8 @@
UnhandledException& result = UnhandledException::Handle();
{
ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
- UnhandledException::InstanceSize(), space);
+ UnhandledException::InstanceSize(), space,
+ /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -18090,7 +18128,8 @@
UnhandledException& result = UnhandledException::Handle();
{
ObjectPtr raw = Object::Allocate(UnhandledException::kClassId,
- UnhandledException::InstanceSize(), space);
+ UnhandledException::InstanceSize(), space,
+ /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -18146,8 +18185,9 @@
ASSERT(Object::unwind_error_class() != Class::null());
UnwindError& result = UnwindError::Handle();
{
- ObjectPtr raw = Object::Allocate(UnwindError::kClassId,
- UnwindError::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(UnwindError::kClassId, UnwindError::InstanceSize(),
+ space, /*compressed*/ true);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -18990,7 +19030,8 @@
}
intptr_t instance_size = cls.host_instance_size();
ASSERT(instance_size > 0);
- ObjectPtr raw = Object::Allocate(cls.id(), instance_size, space);
+ ObjectPtr raw =
+ Object::Allocate(cls.id(), instance_size, space, /*compressed*/ false);
return static_cast<InstancePtr>(raw);
}
@@ -18999,7 +19040,8 @@
Heap::Space heap) {
const intptr_t instance_size = shared_class_table->SizeAt(cid);
ASSERT(instance_size > 0);
- ObjectPtr raw = Object::Allocate(cid, instance_size, heap);
+ ObjectPtr raw =
+ Object::Allocate(cid, instance_size, heap, /*compressed*/ false);
return static_cast<InstancePtr>(raw);
}
@@ -19576,6 +19618,13 @@
(type_class() == Type::Handle(Type::IntType()).type_class());
}
+bool AbstractType::IsIntegerImplementationType() const {
+ return HasTypeClass() &&
+ (type_class() == IsolateGroup::Current()
+ ->object_store()
+ ->integer_implementation_class());
+}
+
bool AbstractType::IsDoubleType() const {
return HasTypeClass() &&
(type_class() == Type::Handle(Type::Double()).type_class());
@@ -20565,7 +20614,8 @@
}
TypePtr Type::New(Heap::Space space) {
- ObjectPtr raw = Object::Allocate(Type::kClassId, Type::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Type::kClassId, Type::InstanceSize(), space,
+ /*compressed*/ false);
return static_cast<TypePtr>(raw);
}
@@ -20959,8 +21009,8 @@
}
TypeRefPtr TypeRef::New() {
- ObjectPtr raw =
- Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(TypeRef::kClassId, TypeRef::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
return static_cast<TypeRefPtr>(raw);
}
@@ -21465,8 +21515,9 @@
}
TypeParameterPtr TypeParameter::New() {
- ObjectPtr raw = Object::Allocate(TypeParameter::kClassId,
- TypeParameter::InstanceSize(), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(TypeParameter::kClassId, TypeParameter::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
return static_cast<TypeParameterPtr>(raw);
}
@@ -21900,8 +21951,8 @@
Class::null());
Mint& result = Mint::Handle();
{
- ObjectPtr raw =
- Object::Allocate(Mint::kClassId, Mint::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Mint::kClassId, Mint::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -22022,8 +22073,8 @@
Class::null());
Double& result = Double::Handle();
{
- ObjectPtr raw =
- Object::Allocate(Double::kClassId, Double::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Double::kClassId, Double::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -23137,7 +23188,8 @@
}
{
ObjectPtr raw = Object::Allocate(OneByteString::kClassId,
- OneByteString::InstanceSize(len), space);
+ OneByteString::InstanceSize(len), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
OneByteStringPtr result = static_cast<OneByteStringPtr>(raw);
result->untag()->set_length(Smi::New(len));
@@ -23344,7 +23396,8 @@
String& result = String::Handle();
{
ObjectPtr raw = Object::Allocate(TwoByteString::kClassId,
- TwoByteString::InstanceSize(len), space);
+ TwoByteString::InstanceSize(len), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -23499,9 +23552,9 @@
}
String& result = String::Handle();
{
- ObjectPtr raw =
- Object::Allocate(ExternalOneByteString::kClassId,
- ExternalOneByteString::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(ExternalOneByteString::kClassId,
+ ExternalOneByteString::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -23529,9 +23582,9 @@
}
String& result = String::Handle();
{
- ObjectPtr raw =
- Object::Allocate(ExternalTwoByteString::kClassId,
- ExternalTwoByteString::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(ExternalTwoByteString::kClassId,
+ ExternalTwoByteString::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -23636,8 +23689,8 @@
FATAL1("Fatal error in Array::New: invalid len %" Pd "\n", len);
}
{
- ArrayPtr raw = static_cast<ArrayPtr>(
- Object::Allocate(class_id, Array::InstanceSize(len), space));
+ ArrayPtr raw = static_cast<ArrayPtr>(Object::Allocate(
+ class_id, Array::InstanceSize(len), space, /*compressed*/ false));
NoSafepointScope no_safepoint;
raw->untag()->set_length(Smi::New(len));
return raw;
@@ -23844,9 +23897,9 @@
Class::null());
GrowableObjectArray& result = GrowableObjectArray::Handle();
{
- ObjectPtr raw =
- Object::Allocate(GrowableObjectArray::kClassId,
- GrowableObjectArray::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(GrowableObjectArray::kClassId,
+ GrowableObjectArray::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(0);
@@ -23932,8 +23985,9 @@
Class::null());
LinkedHashMap& result = LinkedHashMap::Handle();
{
- ObjectPtr raw = Object::Allocate(LinkedHashMap::kClassId,
- LinkedHashMap::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(LinkedHashMap::kClassId, LinkedHashMap::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -23960,7 +24014,8 @@
Float32x4& result = Float32x4::Handle();
{
ObjectPtr raw =
- Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
+ Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -23977,7 +24032,8 @@
Float32x4& result = Float32x4::Handle();
{
ObjectPtr raw =
- Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space);
+ Object::Allocate(Float32x4::kClassId, Float32x4::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -24045,8 +24101,8 @@
Class::null());
Int32x4& result = Int32x4::Handle();
{
- ObjectPtr raw =
- Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -24062,8 +24118,8 @@
Class::null());
Int32x4& result = Int32x4::Handle();
{
- ObjectPtr raw =
- Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Int32x4::kClassId, Int32x4::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -24128,7 +24184,8 @@
Float64x2& result = Float64x2::Handle();
{
ObjectPtr raw =
- Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
+ Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -24143,7 +24200,8 @@
Float64x2& result = Float64x2::Handle();
{
ObjectPtr raw =
- Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space);
+ Object::Allocate(Float64x2::kClassId, Float64x2::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -24245,8 +24303,9 @@
TypedData& result = TypedData::Handle();
{
const intptr_t length_in_bytes = len * ElementSizeInBytes(class_id);
- ObjectPtr raw = Object::Allocate(
- class_id, TypedData::InstanceSize(length_in_bytes), space);
+ ObjectPtr raw =
+ Object::Allocate(class_id, TypedData::InstanceSize(length_in_bytes),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -24292,7 +24351,8 @@
ExternalTypedData& result = ExternalTypedData::Handle();
{
ObjectPtr raw =
- Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space);
+ Object::Allocate(class_id, ExternalTypedData::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
@@ -24313,8 +24373,8 @@
TypedDataViewPtr TypedDataView::New(intptr_t class_id, Heap::Space space) {
auto& result = TypedDataView::Handle();
{
- ObjectPtr raw =
- Object::Allocate(class_id, TypedDataView::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(class_id, TypedDataView::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.Clear();
@@ -24363,7 +24423,8 @@
cls.EnsureIsAllocateFinalized(Thread::Current());
Pointer& result = Pointer::Handle(zone);
- result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space);
+ result ^= Object::Allocate(kFfiPointerCid, Pointer::InstanceSize(), space,
+ /*compressed*/ false);
result.SetTypeArguments(type_args);
result.SetNativeAddress(native_address);
@@ -24379,8 +24440,9 @@
DynamicLibraryPtr DynamicLibrary::New(void* handle, Heap::Space space) {
DynamicLibrary& result = DynamicLibrary::Handle();
- result ^= Object::Allocate(kFfiDynamicLibraryCid,
- DynamicLibrary::InstanceSize(), space);
+ result ^=
+ Object::Allocate(kFfiDynamicLibraryCid, DynamicLibrary::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result.SetHandle(handle);
return result.ptr();
@@ -24402,8 +24464,9 @@
CapabilityPtr Capability::New(uint64_t id, Heap::Space space) {
Capability& result = Capability::Handle();
{
- ObjectPtr raw = Object::Allocate(Capability::kClassId,
- Capability::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(Capability::kClassId, Capability::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(&result.untag()->id_, id);
@@ -24431,8 +24494,9 @@
ReceivePort& result = ReceivePort::Handle(zone);
{
- ObjectPtr raw = Object::Allocate(ReceivePort::kClassId,
- ReceivePort::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(ReceivePort::kClassId, ReceivePort::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.untag()->set_send_port(send_port.ptr());
@@ -24464,7 +24528,8 @@
SendPort& result = SendPort::Handle();
{
ObjectPtr raw =
- Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space);
+ Object::Allocate(SendPort::kClassId, SendPort::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(&result.untag()->id_, id);
@@ -24490,9 +24555,9 @@
Thread* thread = Thread::Current();
TransferableTypedData& result = TransferableTypedData::Handle();
{
- ObjectPtr raw =
- Object::Allocate(TransferableTypedData::kClassId,
- TransferableTypedData::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(TransferableTypedData::kClassId,
+ TransferableTypedData::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
thread->heap()->SetPeer(raw, peer);
result ^= raw;
@@ -24623,8 +24688,8 @@
Heap::Space space) {
Closure& result = Closure::Handle();
{
- ObjectPtr raw =
- Object::Allocate(Closure::kClassId, Closure::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(Closure::kClassId, Closure::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.untag()->set_instantiator_type_arguments(
@@ -24638,8 +24703,8 @@
}
ClosurePtr Closure::New() {
- ObjectPtr raw =
- Object::Allocate(Closure::kClassId, Closure::InstanceSize(), Heap::kOld);
+ ObjectPtr raw = Object::Allocate(Closure::kClassId, Closure::InstanceSize(),
+ Heap::kOld, /*compressed*/ false);
return static_cast<ClosurePtr>(raw);
}
@@ -24734,8 +24799,9 @@
Heap::Space space) {
StackTrace& result = StackTrace::Handle();
{
- ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
- StackTrace::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(StackTrace::kClassId, StackTrace::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -24753,8 +24819,9 @@
Heap::Space space) {
StackTrace& result = StackTrace::Handle();
{
- ObjectPtr raw = Object::Allocate(StackTrace::kClassId,
- StackTrace::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(StackTrace::kClassId, StackTrace::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -25081,6 +25148,10 @@
}
}
+void RegExp::set_num_bracket_expressions(SmiPtr value) const {
+ untag()->set_num_bracket_expressions(value);
+}
+
void RegExp::set_num_bracket_expressions(intptr_t value) const {
untag()->set_num_bracket_expressions(Smi::New(value));
}
@@ -25092,8 +25163,8 @@
RegExpPtr RegExp::New(Heap::Space space) {
RegExp& result = RegExp::Handle();
{
- ObjectPtr raw =
- Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(RegExp::kClassId, RegExp::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
result.set_type(kUninitialized);
@@ -25172,8 +25243,9 @@
WeakPropertyPtr WeakProperty::New(Heap::Space space) {
ASSERT(IsolateGroup::Current()->object_store()->weak_property_class() !=
Class::null());
- ObjectPtr raw = Object::Allocate(WeakProperty::kClassId,
- WeakProperty::InstanceSize(), space);
+ ObjectPtr raw =
+ Object::Allocate(WeakProperty::kClassId, WeakProperty::InstanceSize(),
+ space, /*compressed*/ false);
return static_cast<WeakPropertyPtr>(raw);
}
@@ -25221,7 +25293,8 @@
MirrorReference& result = MirrorReference::Handle();
{
ObjectPtr raw = Object::Allocate(MirrorReference::kClassId,
- MirrorReference::InstanceSize(), space);
+ MirrorReference::InstanceSize(), space,
+ /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
@@ -25258,8 +25331,8 @@
}
// No tag with label exists, create and register with isolate tag table.
{
- ObjectPtr raw =
- Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(), space);
+ ObjectPtr raw = Object::Allocate(UserTag::kClassId, UserTag::InstanceSize(),
+ space, /*compressed*/ false);
NoSafepointScope no_safepoint;
result ^= raw;
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 740afd0..d603fdc 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -613,7 +613,10 @@
cpp_vtable vtable() const { return bit_copy<cpp_vtable>(*this); }
void set_vtable(cpp_vtable value) { *vtable_address() = value; }
- static ObjectPtr Allocate(intptr_t cls_id, intptr_t size, Heap::Space space);
+ static ObjectPtr Allocate(intptr_t cls_id,
+ intptr_t size,
+ Heap::Space space,
+ bool compressed);
static intptr_t RoundedAllocationSize(intptr_t size) {
return Utils::RoundUp(size, kObjectAlignment);
@@ -636,6 +639,13 @@
void StorePointer(type const* addr, type value) const {
ptr()->untag()->StorePointer<type, order>(addr, value);
}
+ template <typename type,
+ typename compressed_type,
+ std::memory_order order = std::memory_order_relaxed>
+ void StoreCompressedPointer(compressed_type const* addr, type value) const {
+ ptr()->untag()->StoreCompressedPointer<type, compressed_type, order>(addr,
+ value);
+ }
// Use for storing into an explicitly Smi-typed field of an object
// (i.e., both the previous and new value are Smis).
@@ -725,7 +735,10 @@
return -kWordSize;
}
- static void InitializeObject(uword address, intptr_t id, intptr_t size);
+ static void InitializeObject(uword address,
+ intptr_t id,
+ intptr_t size,
+ bool compressed);
static void RegisterClass(const Class& cls,
const String& name,
@@ -3738,11 +3751,11 @@
UntaggedClosureData::DefaultTypeArgumentsKind;
private:
- ContextScopePtr context_scope() const { return untag()->context_scope_; }
+ ContextScopePtr context_scope() const { return untag()->context_scope(); }
void set_context_scope(const ContextScope& value) const;
// Enclosing function of this local function.
- FunctionPtr parent_function() const { return untag()->parent_function_; }
+ FunctionPtr parent_function() const { return untag()->parent_function(); }
void set_parent_function(const Function& value) const;
InstancePtr implicit_static_closure() const {
@@ -3751,7 +3764,7 @@
void set_implicit_static_closure(const Instance& closure) const;
TypeArgumentsPtr default_type_arguments() const {
- return untag()->default_type_arguments_;
+ return untag()->default_type_arguments();
}
void set_default_type_arguments(const TypeArguments& value) const;
@@ -7737,6 +7750,9 @@
// Check if this type represents the 'int' type.
bool IsIntType() const;
+ // Check if this type represents the '_IntegerImplementation' type.
+ bool IsIntegerImplementationType() const;
+
// Check if this type represents the 'double' type.
bool IsDoubleType() const;
@@ -7755,6 +7771,9 @@
// Check if this type represents the '_Smi' type.
bool IsSmiType() const { return type_class_id() == kSmiCid; }
+ // Check if this type represents the '_Mint' type.
+ bool IsMintType() const { return type_class_id() == kMintCid; }
+
// Check if this type represents the 'String' type.
bool IsStringType() const;
@@ -10992,6 +11011,7 @@
bool sticky,
const TypedData& bytecode) const;
+ void set_num_bracket_expressions(SmiPtr value) const;
void set_num_bracket_expressions(intptr_t value) const;
void set_capture_name_map(const Array& array) const;
void set_is_global() const {
@@ -11236,7 +11256,7 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
return field->untag()->target_offset_;
#else
- return Smi::Value(field->untag()->host_offset_or_field_id_);
+ return Smi::Value(field->untag()->host_offset_or_field_id());
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
@@ -11385,7 +11405,7 @@
inline void FunctionType::SetHash(intptr_t value) const {
// This is only safe because we create a new Smi, which does not cause
// heap allocation.
- StoreSmi(&untag()->hash_, Smi::New(value));
+ untag()->set_hash(Smi::New(value));
}
inline intptr_t TypeParameter::Hash() const {
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index 0b7cd00..4963b07 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -960,7 +960,7 @@
Smi::Value(static_cast<ExternalTypedDataPtr>(obj)->untag()->length_));
} else if (cid == kFunctionCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<FunctionPtr>(obj)->untag()->name_);
+ ScrubAndWriteUtf8(static_cast<FunctionPtr>(obj)->untag()->name());
} else if (cid == kCodeCid) {
ObjectPtr owner = static_cast<CodePtr>(obj)->untag()->owner_;
if (!owner->IsHeapObject()) {
@@ -969,25 +969,25 @@
writer_->WriteUnsigned(kNoData);
} else if (owner->IsFunction()) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<FunctionPtr>(owner)->untag()->name_);
+ ScrubAndWriteUtf8(static_cast<FunctionPtr>(owner)->untag()->name());
} else if (owner->IsClass()) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<ClassPtr>(owner)->untag()->name_);
+ ScrubAndWriteUtf8(static_cast<ClassPtr>(owner)->untag()->name());
} else {
writer_->WriteUnsigned(kNoData);
}
} else if (cid == kFieldCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<FieldPtr>(obj)->untag()->name_);
+ ScrubAndWriteUtf8(static_cast<FieldPtr>(obj)->untag()->name());
} else if (cid == kClassCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<ClassPtr>(obj)->untag()->name_);
+ ScrubAndWriteUtf8(static_cast<ClassPtr>(obj)->untag()->name());
} else if (cid == kLibraryCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<LibraryPtr>(obj)->untag()->url_);
+ ScrubAndWriteUtf8(static_cast<LibraryPtr>(obj)->untag()->url());
} else if (cid == kScriptCid) {
writer_->WriteUnsigned(kNameData);
- ScrubAndWriteUtf8(static_cast<ScriptPtr>(obj)->untag()->url_);
+ ScrubAndWriteUtf8(static_cast<ScriptPtr>(obj)->untag()->url());
} else {
writer_->WriteUnsigned(kNoData);
}
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index cfe671e..18db2fd 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -442,7 +442,7 @@
Type##Ptr raw_obj, ObjectPointerVisitor* visitor) { \
/* Make sure that we got here with the tagged pointer as this. */ \
ASSERT(raw_obj->IsHeapObject()); \
- ASSERT_UNCOMPRESSED(Type); \
+ ASSERT_COMPRESSED(Type); \
visitor->VisitCompressedPointers(raw_obj->heap_base(), \
raw_obj->untag()->from(), \
raw_obj->untag()->to()); \
@@ -526,29 +526,31 @@
return 0; \
}
-REGULAR_VISITOR(Class)
+COMPRESSED_VISITOR(Class)
+COMPRESSED_VISITOR(PatchClass)
+COMPRESSED_VISITOR(ClosureData)
+COMPRESSED_VISITOR(FfiTrampolineData)
+COMPRESSED_VISITOR(Script)
+COMPRESSED_VISITOR(Library)
+COMPRESSED_VISITOR(Namespace)
+COMPRESSED_VISITOR(KernelProgramInfo)
+COMPRESSED_VISITOR(WeakSerializationReference)
REGULAR_VISITOR(Type)
REGULAR_VISITOR(FunctionType)
REGULAR_VISITOR(TypeRef)
REGULAR_VISITOR(TypeParameter)
-REGULAR_VISITOR(PatchClass)
-REGULAR_VISITOR(Function)
+COMPRESSED_VISITOR(Function)
REGULAR_VISITOR(Closure)
-REGULAR_VISITOR(ClosureData)
-REGULAR_VISITOR(FfiTrampolineData)
-REGULAR_VISITOR(Script)
-REGULAR_VISITOR(Library)
REGULAR_VISITOR(LibraryPrefix)
-REGULAR_VISITOR(Namespace)
REGULAR_VISITOR(SingleTargetCache)
REGULAR_VISITOR(UnlinkedCall)
REGULAR_VISITOR(MonomorphicSmiableCall)
REGULAR_VISITOR(ICData)
REGULAR_VISITOR(MegamorphicCache)
-REGULAR_VISITOR(ApiError)
-REGULAR_VISITOR(LanguageError)
-REGULAR_VISITOR(UnhandledException)
-REGULAR_VISITOR(UnwindError)
+COMPRESSED_VISITOR(ApiError)
+COMPRESSED_VISITOR(LanguageError)
+COMPRESSED_VISITOR(UnhandledException)
+COMPRESSED_VISITOR(UnwindError)
REGULAR_VISITOR(ExternalOneByteString)
REGULAR_VISITOR(ExternalTwoByteString)
REGULAR_VISITOR(GrowableObjectArray)
@@ -562,18 +564,16 @@
REGULAR_VISITOR(MirrorReference)
REGULAR_VISITOR(UserTag)
REGULAR_VISITOR(SubtypeTestCache)
-REGULAR_VISITOR(LoadingUnit)
-REGULAR_VISITOR(KernelProgramInfo)
-REGULAR_VISITOR(WeakSerializationReference)
+COMPRESSED_VISITOR(LoadingUnit)
VARIABLE_VISITOR(TypeArguments, Smi::Value(raw_obj->untag()->length_))
-VARIABLE_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_)
-VARIABLE_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries_)
+VARIABLE_COMPRESSED_VISITOR(LocalVarDescriptors, raw_obj->untag()->num_entries_)
+VARIABLE_COMPRESSED_VISITOR(ExceptionHandlers, raw_obj->untag()->num_entries_)
VARIABLE_VISITOR(Context, raw_obj->untag()->num_variables_)
VARIABLE_VISITOR(Array, Smi::Value(raw_obj->untag()->length()))
VARIABLE_VISITOR(TypedData,
TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
Smi::Value(raw_obj->untag()->length_))
-VARIABLE_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
+VARIABLE_COMPRESSED_VISITOR(ContextScope, raw_obj->untag()->num_variables_)
NULL_VISITOR(Mint)
NULL_VISITOR(Double)
NULL_VISITOR(Float32x4)
@@ -608,15 +608,16 @@
intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj,
ObjectPointerVisitor* visitor) {
ASSERT(raw_obj->IsHeapObject());
- ASSERT_UNCOMPRESSED(Field);
- visitor->VisitPointers(raw_obj->untag()->from(), raw_obj->untag()->to());
+ ASSERT_COMPRESSED(Field);
+ visitor->VisitCompressedPointers(
+ raw_obj->heap_base(), raw_obj->untag()->from(), raw_obj->untag()->to());
if (visitor->trace_values_through_fields()) {
if (Field::StaticBit::decode(raw_obj->untag()->kind_bits_)) {
visitor->isolate_group()->ForEachIsolate(
[&](Isolate* isolate) {
intptr_t index =
- Smi::Value(raw_obj->untag()->host_offset_or_field_id_);
+ Smi::Value(raw_obj->untag()->host_offset_or_field_id());
visitor->VisitPointer(&isolate->field_table()->table()[index]);
},
/*at_safepoint=*/true);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index adc346f..79fa9df 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -57,12 +57,12 @@
#define VISIT_NOTHING() int NothingToVisit();
#define ASSERT_UNCOMPRESSED(Type) \
- ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) == kWordSize)
+ ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) == \
+ sizeof(ObjectPtr))
-// For now there are no compressed pointers, so this assert is the same as
-// the above.
#define ASSERT_COMPRESSED(Type) \
- ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) == kWordSize)
+ ASSERT(SIZE_OF_DEREFERENCED_RETURNED_VALUE(Untagged##Type, from) == \
+ sizeof(CompressedObjectPtr))
#define ASSERT_NOTHING_TO_VISIT(Type) \
ASSERT(SIZE_OF_RETURNED_VALUE(Untagged##Type, NothingToVisit) == sizeof(int))
@@ -542,6 +542,19 @@
return reinterpret_cast<std::atomic<type>*>(const_cast<type*>(addr))
->load(order);
}
+ template <typename type,
+ typename compressed_type,
+ std::memory_order order = std::memory_order_relaxed>
+ type LoadCompressedPointer(compressed_type const* addr) const {
+ compressed_type v = reinterpret_cast<std::atomic<compressed_type>*>(
+ const_cast<compressed_type*>(addr))
+ ->load(order);
+ return static_cast<type>(v.Decompress(heap_base()));
+ }
+
+ uword heap_base() const {
+ return reinterpret_cast<uword>(this) & kHeapBaseMask;
+ }
template <typename type, std::memory_order order = std::memory_order_relaxed>
void StorePointer(type const* addr, type value) {
@@ -552,6 +565,18 @@
}
}
+ template <typename type,
+ typename compressed_type,
+ std::memory_order order = std::memory_order_relaxed>
+ void StoreCompressedPointer(compressed_type const* addr, type value) {
+ reinterpret_cast<std::atomic<compressed_type>*>(
+ const_cast<compressed_type*>(addr))
+ ->store(static_cast<compressed_type>(value), order);
+ if (value->IsHeapObject()) {
+ CheckHeapPointerStore(value, Thread::Current());
+ }
+ }
+
template <typename type>
void StorePointer(type const* addr, type value, Thread* thread) {
*const_cast<type*>(addr) = value;
@@ -603,11 +628,19 @@
}
}
- template <typename type, std::memory_order order = std::memory_order_relaxed>
- type LoadSmi(type const* addr) const {
- return reinterpret_cast<std::atomic<type>*>(const_cast<type*>(addr))
+ template <std::memory_order order = std::memory_order_relaxed>
+ SmiPtr LoadSmi(SmiPtr const* addr) const {
+ return reinterpret_cast<std::atomic<SmiPtr>*>(const_cast<SmiPtr*>(addr))
->load(order);
}
+ template <std::memory_order order = std::memory_order_relaxed>
+ SmiPtr LoadCompressedSmi(CompressedSmiPtr const* addr) const {
+ return static_cast<SmiPtr>(reinterpret_cast<std::atomic<CompressedSmiPtr>*>(
+ const_cast<CompressedSmiPtr*>(addr))
+ ->load(order)
+ .DecompressSmi());
+ }
+
// Use for storing into an explicitly Smi-typed field of an object
// (i.e., both the previous and new value are Smis).
template <std::memory_order order = std::memory_order_relaxed>
@@ -617,6 +650,14 @@
reinterpret_cast<std::atomic<SmiPtr>*>(const_cast<SmiPtr*>(addr))
->store(value, order);
}
+ template <std::memory_order order = std::memory_order_relaxed>
+ void StoreCompressedSmi(CompressedSmiPtr const* addr, SmiPtr value) {
+ // Can't use Contains, as array length is initialized through this method.
+ ASSERT(reinterpret_cast<uword>(addr) >= UntaggedObject::ToAddr(this));
+ reinterpret_cast<std::atomic<CompressedSmiPtr>*>(
+ const_cast<CompressedSmiPtr*>(addr))
+ ->store(static_cast<CompressedSmiPtr>(value), order);
+ }
private:
DART_FORCE_INLINE
@@ -760,6 +801,20 @@
protected: \
type name##_;
+#define COMPRESSED_POINTER_FIELD(type, name) \
+ public: \
+ template <std::memory_order order = std::memory_order_relaxed> \
+ type name() const { \
+ return LoadCompressedPointer<type, Compressed##type, order>(&name##_); \
+ } \
+ template <std::memory_order order = std::memory_order_relaxed> \
+ void set_##name(type value) { \
+ StoreCompressedPointer<type, Compressed##type, order>(&name##_, value); \
+ } \
+ \
+ protected: \
+ Compressed##type name##_;
+
#define ARRAY_POINTER_FIELD(type, name) \
public: \
template <std::memory_order order = std::memory_order_relaxed> \
@@ -793,7 +848,7 @@
public: \
template <std::memory_order order = std::memory_order_relaxed> \
type name() const { \
- type result = LoadSmi<type, order>(&name##_); \
+ type result = LoadSmi<order>(&name##_); \
ASSERT(!result.IsHeapObject()); \
return result; \
} \
@@ -806,6 +861,23 @@
protected: \
type name##_;
+#define COMPRESSED_SMI_FIELD(type, name) \
+ public: \
+ template <std::memory_order order = std::memory_order_relaxed> \
+ type name() const { \
+ type result = LoadCompressedSmi<order>(&name##_); \
+ ASSERT(!result.IsHeapObject()); \
+ return result; \
+ } \
+ template <std::memory_order order = std::memory_order_relaxed> \
+ void set_##name(type value) { \
+ ASSERT(!value.IsHeapObject()); \
+ StoreCompressedSmi(&name##_, value); \
+ } \
+ \
+ protected: \
+ Compressed##type name##_;
+
class UntaggedClass : public UntaggedObject {
public:
enum ClassFinalizedState {
@@ -831,39 +903,43 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(Class);
- VISIT_FROM(ObjectPtr, name)
- POINTER_FIELD(StringPtr, name)
- POINTER_FIELD(StringPtr, user_name)
- POINTER_FIELD(ArrayPtr, functions)
- POINTER_FIELD(ArrayPtr, functions_hash_table)
- POINTER_FIELD(ArrayPtr, fields)
- POINTER_FIELD(ArrayPtr, offset_in_words_to_field)
- POINTER_FIELD(ArrayPtr, interfaces) // Array of AbstractType.
- POINTER_FIELD(ScriptPtr, script)
- POINTER_FIELD(LibraryPtr, library)
- POINTER_FIELD(TypeArgumentsPtr, type_parameters) // Array of TypeParameter.
- POINTER_FIELD(AbstractTypePtr, super_type)
- POINTER_FIELD(ArrayPtr,
- constants) // Canonicalized const instances of this class.
- POINTER_FIELD(TypePtr, declaration_type) // Declaration type for this class.
- POINTER_FIELD(ArrayPtr,
- invocation_dispatcher_cache) // Cache for dispatcher functions.
- POINTER_FIELD(CodePtr,
- allocation_stub) // Stub code for allocation of instances.
- POINTER_FIELD(GrowableObjectArrayPtr,
- direct_implementors) // Array of Class.
- POINTER_FIELD(GrowableObjectArrayPtr, direct_subclasses) // Array of Class.
- POINTER_FIELD(ArrayPtr, dependent_code) // CHA optimized codes.
- VISIT_TO(ObjectPtr, dependent_code)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(CompressedObjectPtr, name)
+ COMPRESSED_POINTER_FIELD(StringPtr, name)
+ COMPRESSED_POINTER_FIELD(StringPtr, user_name)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, functions)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, functions_hash_table)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, fields)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, offset_in_words_to_field)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, interfaces) // Array of AbstractType.
+ COMPRESSED_POINTER_FIELD(ScriptPtr, script)
+ COMPRESSED_POINTER_FIELD(LibraryPtr, library)
+ // Array of TypeParameter.
+ COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, type_parameters)
+ COMPRESSED_POINTER_FIELD(AbstractTypePtr, super_type)
+ // Canonicalized const instances of this class.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, constants)
+ // Declaration type for this class.
+ COMPRESSED_POINTER_FIELD(TypePtr, declaration_type)
+ // Cache for dispatcher functions.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, invocation_dispatcher_cache)
+ // Stub code for allocation of instances.
+ COMPRESSED_POINTER_FIELD(CodePtr, allocation_stub)
+ // Array of Class.
+ COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, direct_implementors)
+ // Array of Class.
+ COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, direct_subclasses)
+ // CHA optimized codes.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, dependent_code)
+ VISIT_TO(CompressedObjectPtr, dependent_code)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<ObjectPtr*>(&allocation_stub_);
+ return reinterpret_cast<CompressedObjectPtr*>(&allocation_stub_);
case Snapshot::kFull:
case Snapshot::kFullCore:
- return reinterpret_cast<ObjectPtr*>(&direct_subclasses_);
+ return reinterpret_cast<CompressedObjectPtr*>(&direct_subclasses_);
case Snapshot::kFullJIT:
- return reinterpret_cast<ObjectPtr*>(&dependent_code_);
+ return reinterpret_cast<CompressedObjectPtr*>(&dependent_code_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -922,21 +998,21 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(PatchClass);
- VISIT_FROM(ObjectPtr, patched_class)
- POINTER_FIELD(ClassPtr, patched_class)
- POINTER_FIELD(ClassPtr, origin_class)
- POINTER_FIELD(ScriptPtr, script)
- POINTER_FIELD(ExternalTypedDataPtr, library_kernel_data)
- VISIT_TO(ObjectPtr, library_kernel_data)
+ VISIT_FROM(CompressedObjectPtr, patched_class)
+ COMPRESSED_POINTER_FIELD(ClassPtr, patched_class)
+ COMPRESSED_POINTER_FIELD(ClassPtr, origin_class)
+ COMPRESSED_POINTER_FIELD(ScriptPtr, script)
+ COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, library_kernel_data)
+ VISIT_TO(CompressedObjectPtr, library_kernel_data)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<ObjectPtr*>(&script_);
+ return reinterpret_cast<CompressedObjectPtr*>(&script_);
case Snapshot::kFull:
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
- return reinterpret_cast<ObjectPtr*>(&library_kernel_data_);
+ return reinterpret_cast<CompressedObjectPtr*>(&library_kernel_data_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1106,22 +1182,22 @@
uword entry_point_; // Accessed from generated code.
uword unchecked_entry_point_; // Accessed from generated code.
- VISIT_FROM(ObjectPtr, name)
- POINTER_FIELD(StringPtr, name)
- POINTER_FIELD(ObjectPtr, owner) // Class or patch class or mixin class
- // where this function is defined.
- POINTER_FIELD(ArrayPtr, parameter_names)
- POINTER_FIELD(FunctionTypePtr, signature)
- POINTER_FIELD(ObjectPtr,
- data) // Additional data specific to the function kind. See
- // Function::set_data() for details.
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(CompressedObjectPtr, name)
+ COMPRESSED_POINTER_FIELD(StringPtr, name)
+ // Class or patch class or mixin class where this function is defined.
+ COMPRESSED_POINTER_FIELD(ObjectPtr, owner)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, parameter_names)
+ COMPRESSED_POINTER_FIELD(FunctionTypePtr, signature)
+ // Additional data specific to the function kind. See Function::set_data()
+ // for details.
+ COMPRESSED_POINTER_FIELD(ObjectPtr, data)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
case Snapshot::kFull:
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
- return reinterpret_cast<ObjectPtr*>(&data_);
+ return reinterpret_cast<CompressedObjectPtr*>(&data_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1130,19 +1206,16 @@
UNREACHABLE();
return NULL;
}
- POINTER_FIELD(ArrayPtr, ic_data_array); // ICData of unoptimized code.
- ObjectPtr* to_no_code() {
- return reinterpret_cast<ObjectPtr*>(&ic_data_array_);
- }
- POINTER_FIELD(CodePtr,
- code); // Currently active code. Accessed from generated code.
- NOT_IN_PRECOMPILED(
- POINTER_FIELD(CodePtr, unoptimized_code)); // Unoptimized code, keep it
- // after optimization.
+ // ICData of unoptimized code.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, ic_data_array);
+ // Currently active code. Accessed from generated code.
+ COMPRESSED_POINTER_FIELD(CodePtr, code);
+ // Unoptimized code, keep it after optimization.
+ NOT_IN_PRECOMPILED(COMPRESSED_POINTER_FIELD(CodePtr, unoptimized_code));
#if defined(DART_PRECOMPILED_RUNTIME)
- VISIT_TO(ObjectPtr, code);
+ VISIT_TO(CompressedObjectPtr, code);
#else
- VISIT_TO(ObjectPtr, unoptimized_code);
+ VISIT_TO(CompressedObjectPtr, unoptimized_code);
#endif
NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_);
@@ -1208,15 +1281,15 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(ClosureData);
- VISIT_FROM(ObjectPtr, context_scope)
- POINTER_FIELD(ContextScopePtr, context_scope)
- POINTER_FIELD(FunctionPtr,
- parent_function) // Enclosing function of this local function.
- POINTER_FIELD(InstancePtr,
- closure) // Closure object for static implicit closures.
+ VISIT_FROM(CompressedObjectPtr, context_scope)
+ COMPRESSED_POINTER_FIELD(ContextScopePtr, context_scope)
+ // Enclosing function of this local function.
+ COMPRESSED_POINTER_FIELD(FunctionPtr, parent_function)
+ // Closure object for static implicit closures.
+ COMPRESSED_POINTER_FIELD(InstancePtr, closure)
// Instantiate-to-bounds TAV for use when no TAV is provided.
- POINTER_FIELD(TypeArgumentsPtr, default_type_arguments)
- VISIT_TO(ObjectPtr, default_type_arguments)
+ COMPRESSED_POINTER_FIELD(TypeArgumentsPtr, default_type_arguments)
+ VISIT_TO(CompressedObjectPtr, default_type_arguments)
enum class DefaultTypeArgumentsKind : uint8_t {
// Only here to make sure it's explicitly set appropriately.
@@ -1247,18 +1320,18 @@
private:
RAW_HEAP_OBJECT_IMPLEMENTATION(FfiTrampolineData);
- VISIT_FROM(ObjectPtr, signature_type)
- POINTER_FIELD(TypePtr, signature_type)
- POINTER_FIELD(FunctionTypePtr, c_signature)
+ VISIT_FROM(CompressedObjectPtr, signature_type)
+ COMPRESSED_POINTER_FIELD(TypePtr, signature_type)
+ COMPRESSED_POINTER_FIELD(FunctionTypePtr, c_signature)
// Target Dart method for callbacks, otherwise null.
- POINTER_FIELD(FunctionPtr, callback_target)
+ COMPRESSED_POINTER_FIELD(FunctionPtr, callback_target)
// For callbacks, value to return if Dart target throws an exception.
- POINTER_FIELD(InstancePtr, callback_exceptional_return)
+ COMPRESSED_POINTER_FIELD(InstancePtr, callback_exceptional_return)
- VISIT_TO(ObjectPtr, callback_exceptional_return)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_TO(CompressedObjectPtr, callback_exceptional_return)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
// Callback id for callbacks.
//
@@ -1275,26 +1348,26 @@
class UntaggedField : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Field);
- VISIT_FROM(ObjectPtr, name)
- POINTER_FIELD(StringPtr, name)
- POINTER_FIELD(ObjectPtr, owner) // Class or patch class or mixin class
- // where this field is defined or original field.
- POINTER_FIELD(AbstractTypePtr, type)
- POINTER_FIELD(FunctionPtr,
- initializer_function) // Static initializer function.
-
+ VISIT_FROM(CompressedObjectPtr, name)
+ COMPRESSED_POINTER_FIELD(StringPtr, name)
+ // Class or patch class or mixin class where this field is defined or original
+ // field.
+ COMPRESSED_POINTER_FIELD(ObjectPtr, owner)
+ COMPRESSED_POINTER_FIELD(AbstractTypePtr, type)
+ // Static initializer function.
+ COMPRESSED_POINTER_FIELD(FunctionPtr, initializer_function)
// - for instance fields: offset in words to the value in the class instance.
// - for static fields: index into field_table.
- SMI_FIELD(SmiPtr, host_offset_or_field_id)
- SMI_FIELD(SmiPtr, guarded_list_length)
- POINTER_FIELD(ArrayPtr, dependent_code)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ COMPRESSED_POINTER_FIELD(SmiPtr, host_offset_or_field_id)
+ COMPRESSED_POINTER_FIELD(SmiPtr, guarded_list_length)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, dependent_code)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFull:
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
case Snapshot::kFullAOT:
- return reinterpret_cast<ObjectPtr*>(&initializer_function_);
+ return reinterpret_cast<CompressedObjectPtr*>(&initializer_function_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1304,11 +1377,11 @@
return NULL;
}
#if defined(DART_PRECOMPILED_RUNTIME)
- VISIT_TO(ObjectPtr, dependent_code);
+ VISIT_TO(CompressedObjectPtr, dependent_code);
#else
- POINTER_FIELD(SubtypeTestCachePtr,
- type_test_cache); // For type test in implicit setter.
- VISIT_TO(ObjectPtr, type_test_cache);
+ // For type test in implicit setter.
+ COMPRESSED_POINTER_FIELD(SubtypeTestCachePtr, type_test_cache);
+ VISIT_TO(CompressedObjectPtr, type_test_cache);
#endif
TokenPosition token_pos_;
TokenPosition end_token_pos_;
@@ -1346,26 +1419,26 @@
class alignas(8) UntaggedScript : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Script);
- VISIT_FROM(ObjectPtr, url)
- POINTER_FIELD(StringPtr, url)
- POINTER_FIELD(StringPtr, resolved_url)
- POINTER_FIELD(ArrayPtr, compile_time_constants)
- POINTER_FIELD(TypedDataPtr, line_starts)
+ VISIT_FROM(CompressedObjectPtr, url)
+ COMPRESSED_POINTER_FIELD(StringPtr, url)
+ COMPRESSED_POINTER_FIELD(StringPtr, resolved_url)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, compile_time_constants)
+ COMPRESSED_POINTER_FIELD(TypedDataPtr, line_starts)
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- POINTER_FIELD(ExternalTypedDataPtr, constant_coverage)
+ COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, constant_coverage)
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- POINTER_FIELD(ArrayPtr, debug_positions)
- POINTER_FIELD(KernelProgramInfoPtr, kernel_program_info)
- POINTER_FIELD(StringPtr, source)
- VISIT_TO(ObjectPtr, source)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ COMPRESSED_POINTER_FIELD(ArrayPtr, debug_positions)
+ COMPRESSED_POINTER_FIELD(KernelProgramInfoPtr, kernel_program_info)
+ COMPRESSED_POINTER_FIELD(StringPtr, source)
+ VISIT_TO(CompressedObjectPtr, source)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<ObjectPtr*>(&url_);
+ return reinterpret_cast<CompressedObjectPtr*>(&url_);
case Snapshot::kFull:
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
- return reinterpret_cast<ObjectPtr*>(&kernel_program_info_);
+ return reinterpret_cast<CompressedObjectPtr*>(&kernel_program_info_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1434,29 +1507,32 @@
RAW_HEAP_OBJECT_IMPLEMENTATION(Library);
- VISIT_FROM(ObjectPtr, name)
- POINTER_FIELD(StringPtr, name)
- POINTER_FIELD(StringPtr, url)
- POINTER_FIELD(StringPtr, private_key)
- POINTER_FIELD(ArrayPtr, dictionary) // Top-level names in this library.
- POINTER_FIELD(ArrayPtr, metadata) // Metadata on classes, methods etc.
- POINTER_FIELD(ClassPtr,
- toplevel_class) // Class containing top-level elements.
- POINTER_FIELD(GrowableObjectArrayPtr, used_scripts)
- POINTER_FIELD(LoadingUnitPtr, loading_unit)
- POINTER_FIELD(ArrayPtr,
- imports) // List of Namespaces imported without prefix.
- POINTER_FIELD(ArrayPtr, exports) // List of re-exported Namespaces.
- POINTER_FIELD(ArrayPtr, dependencies)
- POINTER_FIELD(ExternalTypedDataPtr, kernel_data)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(CompressedObjectPtr, name)
+ COMPRESSED_POINTER_FIELD(StringPtr, name)
+ COMPRESSED_POINTER_FIELD(StringPtr, url)
+ COMPRESSED_POINTER_FIELD(StringPtr, private_key)
+ // Top-level names in this library.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, dictionary)
+ // Metadata on classes, methods etc.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, metadata)
+ // Class containing top-level elements.
+ COMPRESSED_POINTER_FIELD(ClassPtr, toplevel_class)
+ COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, used_scripts)
+ COMPRESSED_POINTER_FIELD(LoadingUnitPtr, loading_unit)
+ // List of Namespaces imported without prefix.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, imports)
+ // List of re-exported Namespaces.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, exports)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, dependencies)
+ COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, kernel_data)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<ObjectPtr*>(&exports_);
+ return reinterpret_cast<CompressedObjectPtr*>(&exports_);
case Snapshot::kFull:
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
- return reinterpret_cast<ObjectPtr*>(&kernel_data_);
+ return reinterpret_cast<CompressedObjectPtr*>(&kernel_data_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1465,13 +1541,13 @@
UNREACHABLE();
return NULL;
}
- POINTER_FIELD(ArrayPtr,
- resolved_names); // Cache of resolved names in library scope.
- POINTER_FIELD(ArrayPtr,
- exported_names); // Cache of exported names by library.
- POINTER_FIELD(ArrayPtr,
- loaded_scripts); // Array of scripts loaded in this library.
- VISIT_TO(ObjectPtr, loaded_scripts);
+ // Cache of resolved names in library scope.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, resolved_names);
+ // Cache of exported names by library.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, exported_names);
+ // Array of scripts loaded in this library.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, loaded_scripts);
+ VISIT_TO(CompressedObjectPtr, loaded_scripts);
Dart_NativeEntryResolver native_entry_resolver_; // Resolves natives.
Dart_NativeEntrySymbol native_entry_symbol_resolver_;
@@ -1491,20 +1567,23 @@
class UntaggedNamespace : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(Namespace);
- VISIT_FROM(ObjectPtr, target)
- POINTER_FIELD(LibraryPtr, target) // library with name dictionary.
- POINTER_FIELD(ArrayPtr, show_names) // list of names that are exported.
- POINTER_FIELD(ArrayPtr, hide_names) // list of names that are hidden.
- POINTER_FIELD(LibraryPtr, owner)
- VISIT_TO(ObjectPtr, owner)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ VISIT_FROM(CompressedObjectPtr, target)
+ // library with name dictionary.
+ COMPRESSED_POINTER_FIELD(LibraryPtr, target)
+ // list of names that are exported.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, show_names)
+ // list of names that are hidden.
+ COMPRESSED_POINTER_FIELD(ArrayPtr, hide_names)
+ COMPRESSED_POINTER_FIELD(LibraryPtr, owner)
+ VISIT_TO(CompressedObjectPtr, owner)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
switch (kind) {
case Snapshot::kFullAOT:
- return reinterpret_cast<ObjectPtr*>(&target_);
+ return reinterpret_cast<CompressedObjectPtr*>(&target_);
case Snapshot::kFull:
case Snapshot::kFullCore:
case Snapshot::kFullJIT:
- return reinterpret_cast<ObjectPtr*>(&owner_);
+ return reinterpret_cast<CompressedObjectPtr*>(&owner_);
case Snapshot::kMessage:
case Snapshot::kNone:
case Snapshot::kInvalid:
@@ -1518,36 +1597,36 @@
class UntaggedKernelProgramInfo : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(KernelProgramInfo);
- VISIT_FROM(ObjectPtr, string_offsets)
- POINTER_FIELD(TypedDataPtr, string_offsets)
- POINTER_FIELD(ExternalTypedDataPtr, string_data)
- POINTER_FIELD(TypedDataPtr, canonical_names)
- POINTER_FIELD(ExternalTypedDataPtr, metadata_payloads)
- POINTER_FIELD(ExternalTypedDataPtr, metadata_mappings)
- POINTER_FIELD(ArrayPtr, scripts)
- POINTER_FIELD(ArrayPtr, constants)
- POINTER_FIELD(GrowableObjectArrayPtr, potential_natives)
- POINTER_FIELD(GrowableObjectArrayPtr, potential_pragma_functions)
- POINTER_FIELD(ExternalTypedDataPtr, constants_table)
- POINTER_FIELD(ArrayPtr, libraries_cache)
- POINTER_FIELD(ArrayPtr, classes_cache)
- POINTER_FIELD(ObjectPtr, retained_kernel_blob)
- VISIT_TO(ObjectPtr, retained_kernel_blob)
+ VISIT_FROM(CompressedObjectPtr, string_offsets)
+ COMPRESSED_POINTER_FIELD(TypedDataPtr, string_offsets)
+ COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, string_data)
+ COMPRESSED_POINTER_FIELD(TypedDataPtr, canonical_names)
+ COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, metadata_payloads)
+ COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, metadata_mappings)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, scripts)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, constants)
+ COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, potential_natives)
+ COMPRESSED_POINTER_FIELD(GrowableObjectArrayPtr, potential_pragma_functions)
+ COMPRESSED_POINTER_FIELD(ExternalTypedDataPtr, constants_table)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, libraries_cache)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, classes_cache)
+ COMPRESSED_POINTER_FIELD(ObjectPtr, retained_kernel_blob)
+ VISIT_TO(CompressedObjectPtr, retained_kernel_blob)
uint32_t kernel_binary_version_;
- ObjectPtr* to_snapshot(Snapshot::Kind kind) {
- return reinterpret_cast<ObjectPtr*>(&constants_table_);
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) {
+ return reinterpret_cast<CompressedObjectPtr*>(&constants_table_);
}
};
class UntaggedWeakSerializationReference : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(WeakSerializationReference);
- VISIT_FROM(ObjectPtr, target)
- POINTER_FIELD(ObjectPtr, target)
- POINTER_FIELD(ObjectPtr, replacement)
- VISIT_TO(ObjectPtr, replacement)
+ VISIT_FROM(CompressedObjectPtr, target)
+ COMPRESSED_POINTER_FIELD(ObjectPtr, target)
+ COMPRESSED_POINTER_FIELD(ObjectPtr, replacement)
+ VISIT_TO(CompressedObjectPtr, replacement)
};
class UntaggedCode : public UntaggedObject {
@@ -1992,13 +2071,21 @@
// platforms.
uword num_entries_;
- ObjectPtr* from() { return reinterpret_cast<ObjectPtr*>(&names()[0]); }
- StringPtr* names() {
- // Array of [num_entries_] variable names.
- OPEN_ARRAY_START(StringPtr, StringPtr);
+ CompressedObjectPtr* from() {
+ return reinterpret_cast<CompressedObjectPtr*>(&names()[0]);
}
- StringPtr* nameAddrAt(intptr_t i) { return &(names()[i]); }
- VISIT_TO_LENGTH(ObjectPtr, nameAddrAt(length - 1));
+ CompressedStringPtr* names() {
+ // Array of [num_entries_] variable names.
+ OPEN_ARRAY_START(CompressedStringPtr, CompressedStringPtr);
+ }
+ CompressedStringPtr* nameAddrAt(intptr_t i) { return &(names()[i]); }
+ StringPtr name(intptr_t i) {
+ return LoadCompressedPointer<StringPtr>(nameAddrAt(i));
+ }
+ void set_name(intptr_t i, StringPtr value) {
+ StoreCompressedPointer(nameAddrAt(i), value);
+ }
+ VISIT_TO_LENGTH(CompressedObjectPtr, nameAddrAt(length - 1));
// Variable info with [num_entries_] entries.
VarInfo* data() {
@@ -2017,9 +2104,9 @@
// Array with [num_entries_] entries. Each entry is an array of all handled
// exception types.
- VISIT_FROM(ObjectPtr, handled_types_data)
- POINTER_FIELD(ArrayPtr, handled_types_data)
- VISIT_TO_LENGTH(ObjectPtr, &handled_types_data_)
+ VISIT_FROM(CompressedObjectPtr, handled_types_data)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, handled_types_data)
+ VISIT_TO_LENGTH(CompressedObjectPtr, &handled_types_data_)
// Exception handler info of length [num_entries_].
const ExceptionHandlerInfo* data() const {
@@ -2053,42 +2140,64 @@
// TODO(iposva): Switch to conventional enum offset based structure to avoid
// alignment mishaps.
struct VariableDesc {
- SmiPtr declaration_token_pos;
- SmiPtr token_pos;
- StringPtr name;
- SmiPtr flags;
+ CompressedSmiPtr declaration_token_pos;
+ CompressedSmiPtr token_pos;
+ CompressedStringPtr name;
+ CompressedSmiPtr flags;
static constexpr intptr_t kIsFinal = 0x1;
static constexpr intptr_t kIsConst = 0x2;
static constexpr intptr_t kIsLate = 0x4;
- SmiPtr late_init_offset;
+ CompressedSmiPtr late_init_offset;
union {
- AbstractTypePtr type;
- InstancePtr value; // iff is_const is true
+ CompressedAbstractTypePtr type;
+ CompressedInstancePtr value; // iff is_const is true
};
- SmiPtr context_index;
- SmiPtr context_level;
+ CompressedSmiPtr context_index;
+ CompressedSmiPtr context_level;
};
int32_t num_variables_;
bool is_implicit_; // true, if this context scope is for an implicit closure.
- ObjectPtr* from() {
+ CompressedObjectPtr* from() {
VariableDesc* begin = const_cast<VariableDesc*>(VariableDescAddr(0));
- return reinterpret_cast<ObjectPtr*>(begin);
+ return reinterpret_cast<CompressedObjectPtr*>(begin);
}
// Variable length data follows here.
- ObjectPtr const* data() const { OPEN_ARRAY_START(ObjectPtr, ObjectPtr); }
+ CompressedObjectPtr const* data() const {
+ OPEN_ARRAY_START(CompressedObjectPtr, CompressedObjectPtr);
+ }
const VariableDesc* VariableDescAddr(intptr_t index) const {
ASSERT((index >= 0) && (index < num_variables_ + 1));
// data() points to the first component of the first descriptor.
return &(reinterpret_cast<const VariableDesc*>(data())[index]);
}
- ObjectPtr* to(intptr_t num_vars) {
+
+#define DEFINE_ACCESSOR(type, name) \
+ type name##_at(intptr_t index) { \
+ return LoadCompressedPointer<type>(&VariableDescAddr(index)->name); \
+ } \
+ void set_##name##_at(intptr_t index, type value) { \
+ StoreCompressedPointer(&VariableDescAddr(index)->name, value); \
+ }
+ DEFINE_ACCESSOR(SmiPtr, declaration_token_pos)
+ DEFINE_ACCESSOR(SmiPtr, token_pos)
+ DEFINE_ACCESSOR(StringPtr, name)
+ DEFINE_ACCESSOR(SmiPtr, flags)
+ DEFINE_ACCESSOR(SmiPtr, late_init_offset)
+ DEFINE_ACCESSOR(AbstractTypePtr, type)
+ DEFINE_ACCESSOR(InstancePtr, value)
+ DEFINE_ACCESSOR(SmiPtr, context_index)
+ DEFINE_ACCESSOR(SmiPtr, context_level)
+#undef DEFINE_ACCESSOR
+
+ CompressedObjectPtr* to(intptr_t num_vars) {
uword end = reinterpret_cast<uword>(VariableDescAddr(num_vars));
// 'end' is the address just beyond the last descriptor, so step back.
- return reinterpret_cast<ObjectPtr*>(end - kWordSize);
+ return reinterpret_cast<CompressedObjectPtr*>(end -
+ sizeof(CompressedObjectPtr));
}
- ObjectPtr* to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind, intptr_t num_vars) {
return to(num_vars);
}
@@ -2190,10 +2299,10 @@
class UntaggedLoadingUnit : public UntaggedObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(LoadingUnit);
- VISIT_FROM(ObjectPtr, parent)
- POINTER_FIELD(LoadingUnitPtr, parent)
- POINTER_FIELD(ArrayPtr, base_objects)
- VISIT_TO(ObjectPtr, base_objects)
+ VISIT_FROM(CompressedObjectPtr, parent)
+ COMPRESSED_POINTER_FIELD(LoadingUnitPtr, parent)
+ COMPRESSED_POINTER_FIELD(ArrayPtr, base_objects)
+ VISIT_TO(CompressedObjectPtr, base_objects)
int32_t id_;
bool load_outstanding_;
bool loaded_;
@@ -2206,44 +2315,44 @@
class UntaggedApiError : public UntaggedError {
RAW_HEAP_OBJECT_IMPLEMENTATION(ApiError);
- VISIT_FROM(ObjectPtr, message)
- POINTER_FIELD(StringPtr, message)
- VISIT_TO(ObjectPtr, message)
+ VISIT_FROM(CompressedObjectPtr, message)
+ COMPRESSED_POINTER_FIELD(StringPtr, message)
+ VISIT_TO(CompressedObjectPtr, message)
};
class UntaggedLanguageError : public UntaggedError {
RAW_HEAP_OBJECT_IMPLEMENTATION(LanguageError);
- VISIT_FROM(ObjectPtr, previous_error)
- POINTER_FIELD(ErrorPtr, previous_error) // May be null.
- POINTER_FIELD(ScriptPtr, script)
- POINTER_FIELD(StringPtr, message)
- POINTER_FIELD(StringPtr,
- formatted_message) // Incl. previous error's formatted message.
- VISIT_TO(ObjectPtr, formatted_message)
+ VISIT_FROM(CompressedObjectPtr, previous_error)
+ COMPRESSED_POINTER_FIELD(ErrorPtr, previous_error) // May be null.
+ COMPRESSED_POINTER_FIELD(ScriptPtr, script)
+ COMPRESSED_POINTER_FIELD(StringPtr, message)
+ // Incl. previous error's formatted message.
+ COMPRESSED_POINTER_FIELD(StringPtr, formatted_message)
+ VISIT_TO(CompressedObjectPtr, formatted_message)
TokenPosition token_pos_; // Source position in script_.
bool report_after_token_; // Report message at or after the token.
int8_t kind_; // Of type Report::Kind.
- ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
class UntaggedUnhandledException : public UntaggedError {
RAW_HEAP_OBJECT_IMPLEMENTATION(UnhandledException);
- VISIT_FROM(ObjectPtr, exception)
- POINTER_FIELD(InstancePtr, exception)
- POINTER_FIELD(InstancePtr, stacktrace)
- VISIT_TO(ObjectPtr, stacktrace)
- ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
+ VISIT_FROM(CompressedObjectPtr, exception)
+ COMPRESSED_POINTER_FIELD(InstancePtr, exception)
+ COMPRESSED_POINTER_FIELD(InstancePtr, stacktrace)
+ VISIT_TO(CompressedObjectPtr, stacktrace)
+ CompressedObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); }
};
class UntaggedUnwindError : public UntaggedError {
RAW_HEAP_OBJECT_IMPLEMENTATION(UnwindError);
- VISIT_FROM(ObjectPtr, message)
- POINTER_FIELD(StringPtr, message)
- VISIT_TO(ObjectPtr, message)
+ VISIT_FROM(CompressedObjectPtr, message)
+ COMPRESSED_POINTER_FIELD(StringPtr, message)
+ VISIT_TO(CompressedObjectPtr, message)
bool is_user_initiated_;
};
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index f8c40d1..f1470e1 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -33,6 +33,14 @@
object.StorePointer(((from) + i), reader->PassiveObjectHandle()->ptr()); \
}
+#define READ_COMPRESSED_OBJECT_FIELDS(object, from, to, as_reference) \
+ intptr_t num_flds = (to) - (from); \
+ for (intptr_t i = 0; i <= num_flds; i++) { \
+ (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(as_reference); \
+ object.StoreCompressedPointer(((from) + i), \
+ reader->PassiveObjectHandle()->ptr()); \
+ }
+
ClassPtr Class::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
@@ -491,7 +499,8 @@
writer->Write<bool>(true);
// Write out the type of 'this' the variable.
- writer->WriteObjectImpl(var->type, kAsInlinedObject);
+ writer->WriteObjectImpl(var->type.Decompress(heap_base()),
+ kAsInlinedObject);
return;
}
@@ -580,8 +589,8 @@
reader->AddBackRef(object_id, &api_error, kIsDeserialized);
// Set all the object fields.
- READ_OBJECT_FIELDS(api_error, api_error.ptr()->untag()->from(),
- api_error.ptr()->untag()->to(), kAsReference);
+ READ_COMPRESSED_OBJECT_FIELDS(api_error, api_error.ptr()->untag()->from(),
+ api_error.ptr()->untag()->to(), kAsReference);
return api_error.ptr();
}
@@ -601,7 +610,7 @@
// Write out all the object pointer fields.
SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitPointers(from(), to());
+ visitor.VisitCompressedPointers(heap_base(), from(), to());
}
LanguageErrorPtr LanguageError::ReadFrom(SnapshotReader* reader,
@@ -623,8 +632,9 @@
language_error.set_kind(reader->Read<uint8_t>());
// Set all the object fields.
- READ_OBJECT_FIELDS(language_error, language_error.ptr()->untag()->from(),
- language_error.ptr()->untag()->to(), kAsReference);
+ READ_COMPRESSED_OBJECT_FIELDS(
+ language_error, language_error.ptr()->untag()->from(),
+ language_error.ptr()->untag()->to(), kAsReference);
return language_error.ptr();
}
@@ -649,7 +659,7 @@
// Write out all the object pointer fields.
SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitPointers(from(), to());
+ visitor.VisitCompressedPointers(heap_base(), from(), to());
}
UnhandledExceptionPtr UnhandledException::ReadFrom(SnapshotReader* reader,
@@ -662,8 +672,8 @@
reader->AddBackRef(object_id, &result, kIsDeserialized);
// Set all the object fields.
- READ_OBJECT_FIELDS(result, result.ptr()->untag()->from(),
- result.ptr()->untag()->to(), kAsReference);
+ READ_COMPRESSED_OBJECT_FIELDS(result, result.ptr()->untag()->from(),
+ result.ptr()->untag()->to(), kAsReference);
return result.ptr();
}
@@ -680,7 +690,7 @@
writer->WriteTags(writer->GetObjectTags(this));
// Write out all the object pointer fields.
SnapshotWriterVisitor visitor(writer, kAsReference);
- visitor.VisitPointers(from(), to());
+ visitor.VisitCompressedPointers(heap_base(), from(), to());
}
InstancePtr Instance::ReadFrom(SnapshotReader* reader,
@@ -693,7 +703,8 @@
// Create an Instance object or get canonical one if it is a canonical
// constant.
Instance& obj = Instance::ZoneHandle(reader->zone(), Instance::null());
- obj ^= Object::Allocate(kInstanceCid, Instance::InstanceSize(), Heap::kNew);
+ obj ^= Object::Allocate(kInstanceCid, Instance::InstanceSize(), Heap::kNew,
+ /*compressed*/ false);
if (UntaggedObject::IsCanonical(tags)) {
obj = obj.Canonicalize(reader->thread());
}
@@ -1702,7 +1713,7 @@
reader->AddBackRef(object_id, ®ex, kIsDeserialized);
// Read and Set all the other fields.
- regex.StoreSmi(®ex.untag()->num_bracket_expressions_, reader->ReadAsSmi());
+ regex.set_num_bracket_expressions(reader->ReadAsSmi());
*reader->ArrayHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
regex.set_capture_name_map(*reader->ArrayHandle());
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 4f29d72..c700063 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -625,7 +625,8 @@
instance_size = cls_.host_instance_size();
ASSERT(instance_size > 0);
// Allocate the instance and read in all the fields for the object.
- *result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew);
+ *result ^= Object::Allocate(cls_.id(), instance_size, Heap::kNew,
+ /*compressed*/ false);
} else {
cls_ ^= ReadObjectImpl(kAsInlinedObject);
ASSERT(!cls_.IsNull());
@@ -1339,7 +1340,7 @@
// Write out the library url and class name.
LibraryPtr library = cls->library();
ASSERT(library != Library::null());
- WriteObjectImpl(library->untag()->url_, kAsInlinedObject);
+ WriteObjectImpl(library->untag()->url(), kAsInlinedObject);
WriteObjectImpl(cls->name(), kAsInlinedObject);
}
@@ -1443,7 +1444,7 @@
return static_cast<ClassPtr>(owner);
}
ASSERT(class_id == kPatchClassCid);
- return static_cast<PatchClassPtr>(owner)->untag()->patched_class_;
+ return static_cast<PatchClassPtr>(owner)->untag()->patched_class();
}
void SnapshotWriter::CheckForNativeFields(ClassPtr cls) {
diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h
index 6302427..8c11bf8 100644
--- a/runtime/vm/tagged_pointer.h
+++ b/runtime/vm/tagged_pointer.h
@@ -189,6 +189,7 @@
}
ObjectPtr Decompress(uword heap_base) const { return *this; }
+ ObjectPtr DecompressSmi() const { return *this; }
uword heap_base() const {
ASSERT(IsHeapObject());
ASSERT(!IsInstructions());
@@ -222,23 +223,36 @@
public:
explicit CompressedObjectPtr(ObjectPtr uncompressed)
: compressed_pointer_(
- static_cast<int32_t>(static_cast<uword>(uncompressed))) {}
+ static_cast<uint32_t>(static_cast<uword>(uncompressed))) {}
ObjectPtr Decompress(uword heap_base) const {
- return static_cast<ObjectPtr>(
- static_cast<uword>(static_cast<word>(compressed_pointer_)) + heap_base);
+ return static_cast<ObjectPtr>(static_cast<uword>(compressed_pointer_) +
+ heap_base);
+ }
+
+ ObjectPtr DecompressSmi() const {
+ ASSERT((compressed_pointer_ & kSmiTagMask) != kHeapObjectTag);
+ return static_cast<ObjectPtr>(static_cast<uword>(compressed_pointer_));
}
const ObjectPtr& operator=(const ObjectPtr& other) {
- compressed_pointer_ = static_cast<int32_t>(static_cast<uword>(other));
+ compressed_pointer_ = static_cast<uint32_t>(static_cast<uword>(other));
return other;
}
protected:
- int32_t compressed_pointer_;
+ uint32_t compressed_pointer_;
};
#define DEFINE_COMPRESSED_POINTER(klass, base) \
- class Compressed##klass##Ptr : public Compressed##base##Ptr {};
+ class Compressed##klass##Ptr : public Compressed##base##Ptr { \
+ public: \
+ explicit Compressed##klass##Ptr(klass##Ptr uncompressed) \
+ : Compressed##base##Ptr(uncompressed) {} \
+ const klass##Ptr& operator=(const klass##Ptr& other) { \
+ compressed_pointer_ = static_cast<uint32_t>(static_cast<uword>(other)); \
+ return other; \
+ } \
+ };
#endif
#define DEFINE_TAGGED_POINTER(klass, base) \
diff --git a/runtime/vm/utils_test.cc b/runtime/vm/utils_test.cc
index 85ff6d4..ba4e296 100644
--- a/runtime/vm/utils_test.cc
+++ b/runtime/vm/utils_test.cc
@@ -4,10 +4,55 @@
#include "platform/utils.h"
#include "platform/assert.h"
+#include "platform/globals.h"
#include "vm/unit_test.h"
namespace dart {
+VM_UNIT_TEST_CASE(StringHash) {
+ auto hash_created_string = [](intptr_t length,
+ intptr_t misalignment) -> uint32_t {
+ const intptr_t capacity = length + misalignment + kInt32Size;
+ char* str = new char[capacity];
+ const intptr_t alloc_misalignment =
+ reinterpret_cast<intptr_t>(str) % kInt32Size;
+ const intptr_t first_aligned_position =
+ alloc_misalignment > 0 ? kInt32Size - alloc_misalignment : 0;
+ const intptr_t start = first_aligned_position + misalignment;
+ for (intptr_t n = 0; n < start; n++) {
+ str[n] = 0xFF;
+ }
+ for (intptr_t n = 0; n < length; n++) {
+ // Fill the important string positions with uppercase letters.
+ str[start + n] = 0x40 + (n % 26);
+ }
+ for (intptr_t n = start + length; n < capacity; n++) {
+ str[n] = 0xFF;
+ }
+ const uint32_t hash = Utils::StringHash(str + start, length);
+ delete[] str;
+ return hash;
+ };
+
+ const intptr_t kMaxLength = 100;
+ ASSERT(kMaxLength >= kInt64Size);
+ uint32_t last_hash = hash_created_string(0, 0);
+ bool identical_hashes = true;
+ // Check the same string at different (mis)alignments has the same hash.
+ for (intptr_t len = 0; len < kMaxLength; len++) {
+ const uint32_t hash = hash_created_string(len, 0);
+ for (intptr_t misalignment = 1; misalignment < kInt64Size; misalignment++) {
+ EXPECT_EQ(hash, hash_created_string(len, misalignment));
+ }
+ if (hash != last_hash) {
+ identical_hashes = false;
+ }
+ last_hash = hash;
+ }
+ // Make sure at least some of the hashes were different from each other.
+ EXPECT(!identical_hashes);
+}
+
VM_UNIT_TEST_CASE(Minimum) {
EXPECT_EQ(0, Utils::Minimum(0, 1));
EXPECT_EQ(0, Utils::Minimum(1, 0));
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 5a09268..1e0b8f8 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -77,7 +77,7 @@
#if defined(DART_COMPRESSED_POINTERS)
if (VirtualMemoryCompressedHeap::GetRegion() == nullptr) {
void* address = GenericMapAligned(
- PROT_READ | PROT_WRITE, kCompressedHeapSize, kCompressedHeapAlignment,
+ PROT_NONE, kCompressedHeapSize, kCompressedHeapAlignment,
kCompressedHeapSize + kCompressedHeapAlignment,
MAP_PRIVATE | MAP_ANONYMOUS);
if (address == nullptr) {
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index 9c09d3d..3f1f0ad 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -206,8 +206,8 @@
} else {
// TODO(40014): Remove cast when type promotion works.
// This would normally be `as T` but we use `as dynamic` to make the
- // unneeded check be implict to match dart2js unsound optimizations in the
- // user code.
+ // unneeded check be implicit to match dart2js unsound optimizations in
+ // the user code.
_future._completeWithValue(value as dynamic);
}
}
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 5f9117b..e73300f 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -306,7 +306,7 @@
/// Registers a system created result and error continuation.
///
/// Used by the implementation of `await` to listen to a future.
- /// The system created liseners are not registered in the zone,
+ /// The system created listeners are not registered in the zone,
/// and the listener is marked as being from an `await`.
/// This marker is used in [_continuationFunctions].
Future<E> _thenAwait<E>(FutureOr<E> f(T value), Function onError) {
@@ -527,8 +527,8 @@
_FutureListener? listeners = _removeListeners();
// TODO(40014): Remove cast when type promotion works.
// This would normally be `as T` but we use `as dynamic` to make the
- // unneeded check be implict to match dart2js unsound optimizations in the
- // user code.
+ // unneeded check be implicit to match dart2js unsound optimizations in
+ // the user code.
_setValue(value as dynamic); // Value promoted to T.
_propagateToListeners(this, listeners);
}
@@ -569,7 +569,7 @@
}
// TODO(40014): Remove cast when type promotion works.
// This would normally be `as T` but we use `as dynamic` to make the
- // unneeded check be implict to match dart2js unsound optimizations in the
+ // unneeded check be implicit to match dart2js unsound optimizations in the
// user code.
_asyncCompleteWithValue(value as dynamic); // Value promoted to T.
}
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 7338ec4..131b66a 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -2181,7 +2181,7 @@
/// Delivery can be delayed if other previously added events are
/// still pending delivery, if the subscription is paused,
/// or if the subscription isn't listening yet.
- /// If it's necessary to know whether the "done" event has been delievered,
+ /// If it's necessary to know whether the "done" event has been delivered,
/// [done] future will complete when that has happened.
void closeSync();
}
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index cb305fe..7121af8 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -217,7 +217,7 @@
/// even if listeners are paused, so some broadcast events may not have been
/// received yet when the returned future completes.
///
- /// If noone listens to a non-broadcast stream,
+ /// If no one listens to a non-broadcast stream,
/// or the listener pauses and never resumes,
/// the done event will not be sent and this future will never complete.
Future close();
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 02c4504..3de0d58 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -476,7 +476,7 @@
}
// -------------------------------------------------------------------
- /// Create a subscription object. Called by [subcribe].
+ /// Create a subscription object. Called by [subscribe].
StreamSubscription<T> _createSubscription(void onData(T data)?,
Function? onError, void onDone()?, bool cancelOnError) {
return new _BufferingStreamSubscription<T>(
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index a85963b..9301ce3 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -135,7 +135,7 @@
///
/// The function should return either `null` if it doesn't want
/// to replace the original error and stack trace,
-/// or an [AsyncError] containg a replacement error and stack trace
+/// or an [AsyncError] containing a replacement error and stack trace
/// which will be used to replace the originals.
typedef AsyncError? ErrorCallbackHandler(Zone self, ZoneDelegate parent,
Zone zone, Object error, StackTrace? stackTrace);
@@ -285,7 +285,7 @@
/// A zone specification is a parameter object passed to [Zone.fork]
/// and any underlying [ForkHandler] custom implementations.
/// The individual handlers, if set to a non-null value,
-/// will be the implementation of the correpsonding [Zone] methods
+/// will be the implementation of the corresponding [Zone] methods
/// for a forked zone created using this zone specification.
///
/// Handlers have the same signature as the same-named methods on [Zone],
@@ -327,7 +327,7 @@
/// The created zone specification has the handlers of [other]
/// and any individually provided handlers.
/// If a handler is provided both through [other] and individually,
- /// the individually provided handler overries the one from [other].
+ /// the individually provided handler overrides the one from [other].
factory ZoneSpecification.from(ZoneSpecification other,
{HandleUncaughtErrorHandler? handleUncaughtError,
RunHandler? run,
@@ -657,7 +657,7 @@
/// of this zone and updates them with values from [zoneValues], which either
/// adds new values or overrides existing ones.
///
- /// Note that the fork operation is interceptible. A zone can thus change
+ /// Note that the fork operation is interceptable. A zone can thus change
/// the zone specification (or zone values), giving the forking zone full
/// control over the child zone.
Zone fork(
diff --git a/sdk/lib/cli/wait_for.dart b/sdk/lib/cli/wait_for.dart
index 35cb307..58990c8 100644
--- a/sdk/lib/cli/wait_for.dart
+++ b/sdk/lib/cli/wait_for.dart
@@ -129,7 +129,7 @@
if (timeout != null) {
s = new Stopwatch()..start();
}
- Timer.run(() {}); // Enusre there is at least one message.
+ Timer.run(() {}); // Ensure there is at least one message.
while (!futureCompleted && (error == null)) {
Duration? remaining;
if (timeout != null) {
diff --git a/sdk/lib/collection/list.dart b/sdk/lib/collection/list.dart
index 0762f4b..07f1e2b 100644
--- a/sdk/lib/collection/list.dart
+++ b/sdk/lib/collection/list.dart
@@ -12,9 +12,9 @@
/// This class implements all read operations using only the `length` and
/// `operator[]` and members. It implements write operations using those and
/// `add`, `length=` and `operator[]=`
-/// Classes using this base classs should implement those five operations.
+/// Classes using this base class should implement those five operations.
///
-/// **NOTICE**: For backwards compatability reasons,
+/// **NOTICE**: For backwards compatibility reasons,
/// there is a default implementation of `add`
/// which only works for lists with a nullable element type.
/// For list with a non-nullable element type,
@@ -53,7 +53,7 @@
/// `add`, `length=` and `operator[]=`.
/// Classes using this mixin should implement those five operations.
///
-/// **NOTICE**: For backwards compatability reasons,
+/// **NOTICE**: For backwards compatibility reasons,
/// there is a default implementation of `add`
/// which only works for lists with a nullable element type.
/// For lists with a non-nullable element type,
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 33eaab6..a4aeb6a 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -441,7 +441,7 @@
/// Sink returned when starting a chunked conversion from object to bytes.
class _JsonUtf8EncoderSink extends ChunkedConversionSink<Object?> {
- /// The byte sink receiveing the encoded chunks.
+ /// The byte sink receiving the encoded chunks.
final ByteConversionSink _sink;
final List<int>? _indent;
final Object? Function(dynamic)? _toEncodable;
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index dbbcb26..0e130aa 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -20,7 +20,7 @@
/// ```dart
/// var myDir = Directory('myDir');
/// ```
-/// Most intance methods of [Directory] exist in both synchronous
+/// Most instance methods of [Directory] exist in both synchronous
/// and asynchronous variants, for example, [create] and [createSync].
/// Unless you have a specific reason for using the synchronous version
/// of a method, prefer the asynchronous version to avoid blocking your program.
@@ -63,7 +63,7 @@
/// }
/// }
/// ```
-/// ## The use of asynchronnous methods
+/// ## The use of asynchronous methods
///
/// I/O operations can block a program for some period of time while it waits for
/// the operation to complete. To avoid this, all
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 07c3aeb..29b2810 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -262,7 +262,7 @@
/// the file when it has been created.
///
/// If [recursive] is `false`, the default, the file is created only if
- /// all directories in its path alredy exist. If [recursive] is `true`, any
+ /// all directories in its path already exist. If [recursive] is `true`, any
/// non-existing parent paths are created first.
///
/// Existing files are left untouched by [create]. Calling [create] on an
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index e624473..9a858de 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -437,7 +437,7 @@
/// [FileSystemEvent] can be or'ed together to mix events. Default is
/// [FileSystemEvent.ALL].
///
- /// A move event may be reported as seperate delete and create events.
+ /// A move event may be reported as separate delete and create events.
Stream<FileSystemEvent> watch(
{int events = FileSystemEvent.all, bool recursive = false}) {
// FIXME(bkonyi): find a way to do this using the raw path.
@@ -494,7 +494,7 @@
/// the current working directory.
///
/// On Windows, a path is absolute if it starts with `\\`
- /// (two backslashesor representing a UNC path) or with a drive letter
+ /// (two backslashes or representing a UNC path) or with a drive letter
/// between `a` and `z` (upper or lower case) followed by `:\` or `:/`.
/// The makes, for example, `\file.ext` a non-absolute path
/// because it depends on the current drive letter.
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index bfe34af..927883d 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -51,7 +51,7 @@
/// was received, the result will be null.
///
/// [supportedProtocols] is an optional list of protocols (in decreasing
- /// order of preference) to use during the ALPN protocol negogiation with
+ /// order of preference) to use during the ALPN protocol negotiation with
/// clients. Example values are "http/1.1" or "h2". The selected protocol
/// can be obtained via [SecureSocket.selectedProtocol].
///
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index 22d57dd..0e918db 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -936,7 +936,7 @@
/// Leaves a multicast group.
///
- /// If an error occur when trying to join the multicase group, an
+ /// If an error occur when trying to join the multicast group, an
/// exception is thrown.
void leaveMulticast(InternetAddress group, [NetworkInterface? interface]);
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index 137b4e0..0ea8448 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -248,7 +248,7 @@
/// Message describing cause of the exception.
final String message;
- /// The underlying OS error, if avaialble.
+ /// The underlying OS error, if available.
final OSError? osError;
const StdoutException(this.message, [this.osError]);
@@ -263,7 +263,7 @@
/// Message describing cause of the exception.
final String message;
- /// The underlying OS error, if avaialble.
+ /// The underlying OS error, if available.
final OSError? osError;
const StdinException(this.message, [this.osError]);
diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
index 7a15d7b..3e7a592 100644
--- a/sdk/lib/isolate/isolate.dart
+++ b/sdk/lib/isolate/isolate.dart
@@ -659,7 +659,7 @@
/// The [handler] will always be invoked in the [Zone.root] zone.
///
/// The port cannot be paused. The data-handler must be set before the first
-/// messsage is received, otherwise the message is lost.
+/// message is received, otherwise the message is lost.
///
/// Messages can be sent to this port using [sendPort].
abstract class RawReceivePort {
@@ -667,7 +667,7 @@
///
/// A [RawReceivePort] is low level and does not work with [Zone]s. It
/// cannot be paused. The data-handler must be set before the first
- /// messsage is received, otherwise the message is lost.
+ /// message is received, otherwise the message is lost.
///
/// If [handler] is provided, it's set as the [RawReceivePort.handler].
///
diff --git a/sdk/lib/math/point.dart b/sdk/lib/math/point.dart
index b3e9432..df26e9a 100644
--- a/sdk/lib/math/point.dart
+++ b/sdk/lib/math/point.dart
@@ -19,7 +19,7 @@
/// Whether [other] is a point with the same coordinates as this point.
///
/// Returns `true` if [other] is a [Point] with [x] and [y]
- /// coordinates equal to the corresponding coordiantes of this point,
+ /// coordinates equal to the corresponding coordinates of this point,
/// and `false` otherwise.
bool operator ==(Object other) =>
other is Point && x == other.x && y == other.y;
diff --git a/sdk/lib/vmservice/named_lookup.dart b/sdk/lib/vmservice/named_lookup.dart
index d611c3d..0c0a5a8 100644
--- a/sdk/lib/vmservice/named_lookup.dart
+++ b/sdk/lib/vmservice/named_lookup.dart
@@ -4,7 +4,7 @@
part of dart._vmservice;
-/// Set like containes which automatically generated String ids for its items
+/// Set like contains which automatically generated String ids for its items
class NamedLookup<E extends Object> extends Object with IterableMixin<E> {
final IdGenerator _generator;
final _elements = <String, E>{};
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 96a4ef6..1f9cd40 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -2,32 +2,9 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: Skip # Triple shift is not implemented yet
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: Skip # Triple shift is not implemented yet
-Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: Skip # Triple shift is not implemented yet
-Language/Expressions/Bitwise_Expressions/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Constants/bitwise_operators_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Equality/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Lists/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Expressions/Maps/syntax_t01: Skip # Triple shift is not implemented yet
-Language/Reference/Operator_Precedence/precedence_01_assignment_t14: Skip # Triple shift is not implemented yet
-Language/Reference/Operator_Precedence/precedence_12_Shift_t04: Skip # Triple shift is not implemented yet
-Language/Reference/Operator_Precedence/precedence_t05: Skip # Triple shift is not implemented yet
-Language/Statements/Expression_Statements/syntax_t06: Skip # Triple shift is not implemented for integers yet
-Language/Types/Type_Aliases/built-in_types_t11: Skip # Triple shift is not implemented yet
-LanguageFeatures/Extension-methods/explicit_extension_member_invocation_A15_t09: Skip # Triple shift is not implemented yet
-LanguageFeatures/Triple-Shift/*: Skip # Triple shift is not implemented yet
-LanguageFeatures/nnbd/local_variable_read_A01_t03: Skip # Triple shift is not implemented yet
-LanguageFeatures/nnbd/local_variable_read_A02_t03: Skip # Triple shift is not implemented yet
-LanguageFeatures/nnbd/local_variable_read_A03_t03: Skip # Triple shift is not implemented yet
LibTest/ffi/Array/PointerArray_A01_t01: Skip # https://github.com/dart-lang/co19/issues/1018
LibTest/io/RawDatagramSocket/*: Skip # https://github.com/dart-lang/co19/issues/195
-[ $compiler == dart2analyzer ]
-Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # Triple shift is not fully implemented
-Language/Classes/Instance_Methods/Operators/arity_1_t19: Skip # Triple shift is not fully implemented (https://github.com/dart-lang/sdk/issues/42353)
-Language/Functions/syntax_t03: Skip # Triple shift is not implemented yet
-
[ $compiler != fasta ]
Language/Classes/Abstract_Instance_Members/inherited_t13: Skip # github.com/dart-lang/language/issues/115
Language/Classes/Abstract_Instance_Members/inherited_t14: Skip # github.com/dart-lang/language/issues/115
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index d8b00ce..98075c7 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -30,28 +30,7 @@
LibTest/io/RawDatagramSocket/*: Skip # RawDatagramSocket are flacky. Skip them all until rewritten
[ $fasta ]
-Language/Classes/Instance_Methods/Operators/allowed_names_t01: Skip # triple-shift flag
-Language/Classes/Instance_Methods/Operators/allowed_names_t23: Skip # triple-shift flag
-Language/Classes/Instance_Methods/Operators/arity_1_t19: Skip # triple-shift flag
Language/Enums/restrictions_t10: Crash
-Language/Expressions/Assignment/Compound_Assignment/expression_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/indexed_expression_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/setter_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: Skip # triple-shift flag
-Language/Expressions/Bitwise_Expressions/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t01: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t07: Skip # triple-shift flag
-Language/Expressions/Constants/bitwise_operators_t08: Skip # triple-shift flag
-Language/Expressions/Equality/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Lists/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Maps/syntax_t01: Skip # triple-shift flag
-Language/Expressions/Relational_Expressions/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Shift/allowed_characters_t02: Skip # triple-shift flag
-Language/Expressions/Shift/equivalent_super_t02: Skip # triple-shift flag
-Language/Expressions/Shift/equivalent_t02: Skip # triple-shift flag
-Language/Expressions/Shift/integer_t03: Skip # triple-shift flag
Language/Expressions/Shift/integer_t04/01: Crash
Language/Expressions/Shift/integer_t04/02: Crash
Language/Expressions/Shift/integer_t04/03: Crash
@@ -60,22 +39,6 @@
Language/Expressions/Shift/integer_t04/06: Crash
Language/Expressions/Shift/integer_t04/07: Crash
Language/Expressions/Shift/integer_t04/none: Crash
-Language/Expressions/Shift/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t15: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t17: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t18: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t19: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t21: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t22: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t23: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t24: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t25: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t26: Skip # triple-shift experiment flag
-Language/Expressions/Shift/syntax_t27: Skip # triple-shift experiment flag
-Language/Expressions/Strings/String_Interpolation/syntax_t01: Skip # triple-shift experiment flag
-Language/Expressions/Symbols/syntax_t02: Skip # triple-shift experiment flag
-Language/Expressions/parentheses_t01: Skip # triple-shift experiment flag
-Language/Functions/syntax_t03: Skip # triple-shift experiment flag
Language/Mixins/Mixin_Application/abstract_t09: Crash
Language/Mixins/Mixin_Application/abstract_t10: Crash
Language/Mixins/Mixin_Application/abstract_t11: Crash
@@ -100,10 +63,6 @@
Language/Mixins/Mixin_Application/wrong_mixin_type_t09: Crash
Language/Mixins/Mixin_Composition/order_t02: Crash
Language/Mixins/declaring_constructor_t11: Crash
-Language/Reference/Operator_Precedence/precedence_01_assignment_t14: Skip # triple-shift experimental flag
-Language/Reference/Operator_Precedence/precedence_12_Shift_t04: Skip # triple-shift experimental flag
-Language/Reference/Operator_Precedence/precedence_t05: Skip # triple-shift experimental flag
-Language/Statements/Expression_Statements/syntax_t06: Skip # triple-shift experimental flag
LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: Crash
LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: Crash
LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/01: Crash
diff --git a/tests/language/const_functions/const_functions_for_statements_test.dart b/tests/language/const_functions/const_functions_for_statements_test.dart
index 4575070..781b76b 100644
--- a/tests/language/const_functions/const_functions_for_statements_test.dart
+++ b/tests/language/const_functions/const_functions_for_statements_test.dart
@@ -47,10 +47,68 @@
}
}
+const var6 = fnContinue();
+// ^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnContinue() {
+ int a = 0;
+ for (int i = 0; i < 5; i++) {
+ if (i % 2 == 1) continue;
+ a += i;
+ }
+ return a;
+}
+
+const var7 = fnBreak(2);
+// ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var8 = fnBreak(3);
+// ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreak(int a) {
+ int b = a;
+ for (int i = 0; i < 2; i++) {
+ if (b == 2) break;
+ b += a;
+ }
+ return b;
+}
+
+const var9 = fnNestedFor();
+// ^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnNestedFor() {
+ int a = 0;
+ for (;;) {
+ for (;;) {
+ break;
+ }
+ return 1;
+ }
+}
+
+const var10 = fnBreakLabel();
+// ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreakLabel() {
+ foo:
+ for (;;) {
+ for (;;) {
+ break foo;
+ }
+ }
+ return 3;
+}
+
void main() {
Expect.equals(var1, 6);
Expect.equals(var2, 9);
Expect.equals(var3, 18);
Expect.equals(var4, 27);
Expect.equals(var5, 11);
+ Expect.equals(var6, 6);
+ Expect.equals(var7, 2);
+ Expect.equals(var8, 9);
+ Expect.equals(var9, 1);
+ Expect.equals(var10, 3);
}
diff --git a/tests/language/const_functions/const_functions_while_statements_test.dart b/tests/language/const_functions/const_functions_while_statements_test.dart
index 59ea40c..40e68f5 100644
--- a/tests/language/const_functions/const_functions_while_statements_test.dart
+++ b/tests/language/const_functions/const_functions_while_statements_test.dart
@@ -38,9 +38,74 @@
}
}
+const var5 = fnContinue();
+// ^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnContinue() {
+ int a = 0;
+ int i = 0;
+ while (i < 5) {
+ if (i % 2 == 1) {
+ i++;
+ continue;
+ }
+ a += i;
+ i++;
+ }
+ return a;
+}
+
+const var6 = fnBreak(2);
+// ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+const var7 = fnBreak(3);
+// ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreak(int a) {
+ int b = a;
+ int i = 0;
+ while (i < 2) {
+ if (b == 2) break;
+ b += a;
+ i++;
+ }
+ return b;
+}
+
+const var8 = fnNestedWhile();
+// ^^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnNestedWhile() {
+ int a = 0;
+ while (true) {
+ while (true) {
+ break;
+ }
+ return 1;
+ }
+}
+
+const var9 = fnBreakLabel();
+// ^^^^^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
+int fnBreakLabel() {
+ foo:
+ while (true) {
+ while (true) {
+ break foo;
+ }
+ }
+ return 3;
+}
+
void main() {
Expect.equals(var1, 6);
Expect.equals(var2, 9);
Expect.equals(var3, 18);
Expect.equals(var4, 27);
+ Expect.equals(var5, 6);
+ Expect.equals(var6, 2);
+ Expect.equals(var7, 9);
+ Expect.equals(var8, 1);
+ Expect.equals(var9, 3);
}
diff --git a/tests/language/language_dartdevc.status b/tests/language/language_dartdevc.status
index 0c012d1..5ab9a1e 100644
--- a/tests/language/language_dartdevc.status
+++ b/tests/language/language_dartdevc.status
@@ -5,10 +5,6 @@
# Sections in this file should contain "$compiler == dartdevc" or dartdevk.
[ $compiler == dartdevc ]
class/large_class_declaration_test: Slow, Pass
-const/double_in_int_op_test/dd6: Skip # Triple shift
-const/double_in_int_op_test/di6: Skip # Triple shift
-const/double_in_int_op_test/id6: Skip # Triple shift
-const/double_in_int_op_test/ii6: Skip # Triple shift
extension_methods/*: SkipByDesign # Analyzer DDC is expected to be turned down before releasing extension methods.
nnbd/*: Skip
variance/*: SkipByDesign # Analyzer DDC is expected to be turned down before releasing variance.
diff --git a/tools/VERSION b/tools/VERSION
index cb8bd38..ec78be6 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 13
PATCH 0
-PRERELEASE 150
+PRERELEASE 151
PRERELEASE_PATCH 0
\ No newline at end of file