Version 2.16.0-106.0.dev
Merge commit 'ecdf148428934522b8a3a0f0f7d8729ddde81584' into 'dev'
diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json
index 0d8297b..284ed91 100644
--- a/.dart_tool/package_config.json
+++ b/.dart_tool/package_config.json
@@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
- "generated": "2021-12-09T13:52:42.287379",
+ "generated": "2021-12-10T17:31:54.553345",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@@ -262,7 +262,7 @@
"name": "dev_compiler",
"rootUri": "../pkg/dev_compiler",
"packageUri": "lib/",
- "languageVersion": "2.12"
+ "languageVersion": "2.15"
},
{
"name": "devtools_server",
@@ -381,7 +381,7 @@
"name": "js",
"rootUri": "../pkg/js",
"packageUri": "lib/",
- "languageVersion": "2.12"
+ "languageVersion": "2.16"
},
{
"name": "js_ast",
@@ -817,4 +817,4 @@
"languageVersion": "2.12"
}
]
-}
+}
\ No newline at end of file
diff --git a/pkg/_fe_analyzer_shared/pubspec.yaml b/pkg/_fe_analyzer_shared/pubspec.yaml
index 445f314..9b35add 100644
--- a/pkg/_fe_analyzer_shared/pubspec.yaml
+++ b/pkg/_fe_analyzer_shared/pubspec.yaml
@@ -1,5 +1,5 @@
name: _fe_analyzer_shared
-version: 31.0.0
+version: 32.0.0
description: Logic that is shared between the front_end and analyzer packages.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/_fe_analyzer_shared
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
index 4ffbedf..327a6e6 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
@@ -22,11 +22,11 @@
/// The workspace in which the fix contributor operates.
ChangeWorkspace get workspace;
- /// Return top-level declarations with the [name] in libraries that are
- /// available to this context.
- Future<Map<LibraryElement, List<Element>>> getTopLevelDeclarations(
- String name,
- );
+ /// Return the mapping from a library (that is available to this context) to
+ /// a top-level declaration that is exported (not necessary declared) by this
+ /// library, and has the requested base name. For getters and setters the
+ /// corresponding top-level variable is returned.
+ Future<Map<LibraryElement, Element>> getTopLevelDeclarations(String name);
/// Return libraries with extensions that declare non-static public
/// extension members with the [memberName].
diff --git a/pkg/analysis_server/lib/protocol/protocol.dart b/pkg/analysis_server/lib/protocol/protocol.dart
index 4899638..3481a4c 100644
--- a/pkg/analysis_server/lib/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/protocol/protocol.dart
@@ -29,7 +29,7 @@
/// A table mapping the names of notification parameters to their values, or
/// `null` if there are no notification parameters.
- final Map<String, Object>? params;
+ final Map<String, Object?>? params;
/// Initialize a newly created [Notification] to have the given [event] name.
/// If [params] is provided, it will be used as the params; otherwise no
@@ -39,7 +39,7 @@
/// Initialize a newly created instance based on the given JSON data.
factory Notification.fromJson(Map json) {
return Notification(json[Notification.EVENT] as String,
- json[Notification.PARAMS] as Map<String, Object>?);
+ json[Notification.PARAMS] as Map<String, Object?>?);
}
/// Return a table representing the structure of the Json object that will be
diff --git a/pkg/analysis_server/lib/src/cider/fixes.dart b/pkg/analysis_server/lib/src/cider/fixes.dart
index 560a849..6b65f24 100644
--- a/pkg/analysis_server/lib/src/cider/fixes.dart
+++ b/pkg/analysis_server/lib/src/cider/fixes.dart
@@ -82,10 +82,10 @@
error);
@override
- Future<Map<LibraryElement, List<Element>>> getTopLevelDeclarations(
+ Future<Map<LibraryElement, Element>> getTopLevelDeclarations(
String name,
) async {
- var result = <LibraryElement, List<Element>>{};
+ var result = <LibraryElement, Element>{};
var files = _fileResolver.getFilesWithTopLevelDeclarations(name);
for (var file in files) {
if (file.partOfLibrary == null) {
diff --git a/pkg/analysis_server/lib/src/cider/signature_help.dart b/pkg/analysis_server/lib/src/cider/signature_help.dart
new file mode 100644
index 0000000..6b3616a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/cider/signature_help.dart
@@ -0,0 +1,56 @@
+// 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:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/src/computer/computer_signature.dart';
+import 'package:analysis_server/src/computer/computer_type_arguments_signature.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/micro/resolve_file.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
+
+class CiderSignatureHelpComputer {
+ final FileResolver _fileResolver;
+
+ CiderSignatureHelpComputer(this._fileResolver);
+
+ SignatureHelpResponse? compute(String filePath, int line, int column) {
+ var resolvedUnit = _fileResolver.resolve(path: filePath);
+ var lineInfo = resolvedUnit.lineInfo;
+ var offset = lineInfo.getOffsetOfLine(line) + column;
+ final formats = <MarkupKind>{MarkupKind.Markdown};
+
+ var dartDocInfo = DartdocDirectiveInfo();
+ final typeArgsComputer = DartTypeArgumentsSignatureComputer(
+ dartDocInfo, resolvedUnit.unit, offset, formats);
+ if (typeArgsComputer.offsetIsValid) {
+ final typeSignature = typeArgsComputer.compute();
+
+ if (typeSignature != null) {
+ return SignatureHelpResponse(typeSignature,
+ lineInfo.getLocation(typeArgsComputer.argumentList.offset + 1));
+ }
+ }
+
+ final computer =
+ DartUnitSignatureComputer(dartDocInfo, resolvedUnit.unit, offset);
+ if (computer.offsetIsValid) {
+ final signature = computer.compute();
+ if (signature != null) {
+ return SignatureHelpResponse(toSignatureHelp(formats, signature),
+ lineInfo.getLocation(computer.argumentList.offset + 1));
+ }
+ }
+ return null;
+ }
+}
+
+class SignatureHelpResponse {
+ final SignatureHelp signatureHelp;
+
+ /// The location of the left parenthesis.
+ final CharacterLocation callStart;
+
+ SignatureHelpResponse(this.signatureHelp, this.callStart);
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index cdfb928..79f8ef3 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -486,12 +486,14 @@
return utils.getRangeText(range);
}
- /// Return the top-level declarations with the [name] in libraries that are
- /// available to this context.
- Future<Map<LibraryElement, List<Element>>> getTopLevelDeclarations(
- String name,
+ /// Return the mapping from a library (that is available to this context) to
+ /// a top-level declaration that is exported (not necessary declared) by this
+ /// library, and has the requested base name. For getters and setters the
+ /// corresponding top-level variable is returned.
+ Future<Map<LibraryElement, Element>> getTopLevelDeclarations(
+ String baseName,
) {
- return _context.dartFixContext!.getTopLevelDeclarations(name);
+ return _context.dartFixContext!.getTopLevelDeclarations(baseName);
}
/// Return `true` the lint with the given [name] is enabled.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
index 27f0488..12c65d0 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/import_library.dart
@@ -13,11 +13,11 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer/src/dart/resolver/applicable_extensions.dart';
import 'package:analyzer_plugin/src/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/src/utilities/library.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
-import 'package:analyzer_plugin/utilities/range_factory.dart';
class ImportLibrary extends MultiCorrectionProducer {
final _ImportKind _importKind;
@@ -153,8 +153,12 @@
continue;
}
foundImport = true;
- for (var extension in importedLibrary.matchingExtensionsWithMember(
- libraryElement, targetType, memberName)) {
+ var instantiatedExtensions = ApplicableExtensions(
+ targetLibrary: libraryElement,
+ targetType: targetType,
+ memberName: memberName,
+ ).instantiate(importedLibrary.exportedExtensions);
+ for (var instantiatedExtension in instantiatedExtensions) {
// If the import has a combinator that needs to be updated, then offer
// to update it.
var combinators = imp.combinators;
@@ -165,7 +169,7 @@
// hide combinator.
} else if (combinator is ShowElementCombinator) {
yield _ImportLibraryShow(libraryToImport.source.uri.toString(),
- combinator, extension.name!);
+ combinator, instantiatedExtension.extension.name!);
}
}
}
@@ -267,42 +271,41 @@
var librariesWithElements = await getTopLevelDeclarations(name);
for (var libraryEntry in librariesWithElements.entries) {
var libraryElement = libraryEntry.key;
- for (var declaration in libraryEntry.value) {
- var librarySource = libraryElement.source;
- // Check the kind.
- if (!kinds.contains(declaration.kind)) {
- continue;
- }
- // Check the source.
- if (alreadyImportedWithPrefix.contains(libraryElement)) {
- continue;
- }
- // Check that the import doesn't end with '.template.dart'
- if (librarySource.uri.path.endsWith('.template.dart')) {
- continue;
- }
- // Compute the fix kind.
- FixKind fixKind;
- if (librarySource.uri.isScheme('dart')) {
- fixKind = DartFixKind.IMPORT_LIBRARY_SDK;
- } else if (_isLibSrcPath(librarySource.fullName)) {
- // Bad: non-API.
- fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT3;
- } else if (declaration.library != libraryElement) {
- // Ugly: exports.
- fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT2;
- } else {
- // Good: direct declaration.
- fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
- }
- // If both files are in the same package's lib folder, also include a
- // relative import.
- var includeRelativeUri = canBeRelativeImport(
- librarySource.uri, this.libraryElement.librarySource.uri);
- // Add the fix(es).
- yield* _importLibrary(fixKind, librarySource.uri,
- includeRelativeFix: includeRelativeUri);
+ var declaration = libraryEntry.value;
+ var librarySource = libraryElement.source;
+ // Check the kind.
+ if (!kinds.contains(declaration.kind)) {
+ continue;
}
+ // Check the source.
+ if (alreadyImportedWithPrefix.contains(libraryElement)) {
+ continue;
+ }
+ // Check that the import doesn't end with '.template.dart'
+ if (librarySource.uri.path.endsWith('.template.dart')) {
+ continue;
+ }
+ // Compute the fix kind.
+ FixKind fixKind;
+ if (librarySource.uri.isScheme('dart')) {
+ fixKind = DartFixKind.IMPORT_LIBRARY_SDK;
+ } else if (_isLibSrcPath(librarySource.fullName)) {
+ // Bad: non-API.
+ fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT3;
+ } else if (declaration.library != libraryElement) {
+ // Ugly: exports.
+ fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT2;
+ } else {
+ // Good: direct declaration.
+ fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
+ }
+ // If both files are in the same package's lib folder, also include a
+ // relative import.
+ var includeRelativeUri = canBeRelativeImport(
+ librarySource.uri, this.libraryElement.librarySource.uri);
+ // Add the fix(es).
+ yield* _importLibrary(fixKind, librarySource.uri,
+ includeRelativeFix: includeRelativeUri);
}
}
@@ -451,9 +454,12 @@
@override
Future<void> compute(ChangeBuilder builder) async {
- if (library
- .matchingExtensionsWithMember(libraryElement, targetType, memberName)
- .isNotEmpty) {
+ var instantiatedExtensions = ApplicableExtensions(
+ targetLibrary: libraryElement,
+ targetType: targetType,
+ memberName: memberName,
+ ).instantiate(library.exportedExtensions);
+ if (instantiatedExtensions.isNotEmpty) {
await builder.addDartFileEdit(file, (builder) {
_uriText = builder.importLibrary(library.source.uri);
});
@@ -467,24 +473,23 @@
final LibraryElement _importedLibrary;
final PrefixElement _importPrefix;
- String _libraryName = '';
-
- String _prefixName = '';
-
_ImportLibraryPrefix(this._importedLibrary, this._importPrefix);
@override
- List<Object> get fixArguments => [_libraryName, _prefixName];
+ List<Object> get fixArguments {
+ var uriStr = _importedLibrary.source.uri.toString();
+ return [uriStr, _prefixName];
+ }
@override
FixKind get fixKind => DartFixKind.IMPORT_LIBRARY_PREFIX;
+ String get _prefixName => _importPrefix.name;
+
@override
Future<void> compute(ChangeBuilder builder) async {
- _libraryName = _importedLibrary.displayName;
- _prefixName = _importPrefix.displayName;
await builder.addDartFileEdit(file, (builder) {
- builder.addSimpleReplacement(range.startLength(node, 0), '$_prefixName.');
+ builder.addSimpleInsertion(node.offset, '$_prefixName.');
});
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 5c02856..e802922 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -60,7 +60,7 @@
this.resolveResult, this.error);
@override
- Future<Map<LibraryElement, List<Element>>> getTopLevelDeclarations(
+ Future<Map<LibraryElement, Element>> getTopLevelDeclarations(
String name) async {
return TopLevelDeclarations(resolveResult).withName(name);
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart b/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
index 2fab4c2..0106ff1 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/dart/top_level_declarations.dart
@@ -19,7 +19,11 @@
return analysisContext as DriverBasedAnalysisContext;
}
- Future<Map<LibraryElement, List<Element>>> withName(String name) async {
+ /// Return the mapping from a library (that is available to this context) to
+ /// a top-level declaration that is exported (not necessary declared) by this
+ /// library, and has the requested base name. For getters and setters the
+ /// corresponding top-level variable is returned.
+ Future<Map<LibraryElement, Element>> withName(String baseName) async {
var analysisDriver = _analysisContext.driver;
await analysisDriver.discoverAvailableFiles();
@@ -28,7 +32,7 @@
fsState.getFileForPath(resolvedUnit.path),
);
- var result = <LibraryElement, List<Element>>{};
+ var result = <LibraryElement, Element>{};
for (var file in fsState.knownFiles.toList()) {
if (!filter.shouldInclude(file)) {
@@ -40,25 +44,28 @@
continue;
}
- addElement(result, libraryElement, name);
+ addElement(result, libraryElement, baseName);
}
return result;
}
static void addElement(
- Map<LibraryElement, List<Element>> result,
+ Map<LibraryElement, Element> result,
LibraryElement libraryElement,
- String name,
+ String baseName,
) {
- var exportNamespace = libraryElement.exportNamespace;
- var element = exportNamespace.get(name);
- if (element != null) {
- // TODO(scheglov) Separate getters and setters.
+ void addSingle(String name) {
+ var element = libraryElement.exportNamespace.get(name);
if (element is PropertyAccessorElement) {
element = element.variable;
}
- (result[libraryElement] ??= []).add(element);
+ if (element != null) {
+ result[libraryElement] = element;
+ }
}
+
+ addSingle(baseName);
+ addSingle('$baseName=');
}
}
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/element.dart b/pkg/analysis_server/lib/src/utilities/extensions/element.dart
index 3c2b11d..33e7498 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/element.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/element.dart
@@ -2,7 +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 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/generic_inferrer.dart';
@@ -64,6 +63,7 @@
/// Use the [type] of the object being extended in the [library] to compute
/// the actual type extended by this [extension]. Return the computed type,
/// or `null` if the type can't be computed.
+ /// TODO(scheglov) share with analyzer
DartType? resolvedExtendedType(LibraryElement library, DartType type) {
final typeParameters = this.typeParameters;
var inferrer =
@@ -89,31 +89,9 @@
}
extension LibraryElementExtensions on LibraryElement {
- /// Return the extensions in this library that can be applied, within the
- /// [containingLibrary], to the [targetType] and that define a member with the
- /// given [memberName].
- Iterable<ExtensionElement> matchingExtensionsWithMember(
- LibraryElement containingLibrary,
- DartType targetType,
- String memberName) sync* {
- for (var extension in exportNamespace.definedNames.values) {
- if (extension is ExtensionElement) {
- var extensionName = extension.name;
- if (extensionName != null && !Identifier.isPrivateName(extensionName)) {
- var extendedType =
- extension.resolvedExtendedType(containingLibrary, targetType);
- if (extendedType != null &&
- typeSystem.isSubtypeOf(targetType, extendedType)) {
- // TODO(scheglov) share with analyzer
- if (extension.getMethod(memberName) != null ||
- extension.getGetter(memberName) != null ||
- extension.getSetter(memberName) != null) {
- yield extension;
- }
- }
- }
- }
- }
+ /// Return all extensions exported from this library.
+ Iterable<ExtensionElement> get exportedExtensions {
+ return exportNamespace.definedNames.values.whereType();
}
}
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
index edaeefd..a9de8f5 100644
--- a/pkg/analysis_server/test/lsp/signature_help_test.dart
+++ b/pkg/analysis_server/test/lsp/signature_help_test.dart
@@ -305,6 +305,33 @@
);
}
+ Future<void> test_params_multipleNamed_retrigger() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, {bool b = true, bool a}) {
+ foo('s',^);
+ }
+ ''';
+
+ final expectedLabel = 'foo(String s, {bool b = true, bool a})';
+ final expectedDoc = 'Does foo.';
+
+ await initialize(
+ textDocumentCapabilities: withSignatureHelpContentFormat(
+ emptyTextDocumentClientCapabilities, [MarkupKind.Markdown]));
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ ParameterInformation(label: 'String s'),
+ ParameterInformation(label: 'bool b = true'),
+ ParameterInformation(label: 'bool a'),
+ ],
+ );
+ }
+
Future<void> test_params_multipleOptional() async {
final content = '''
/// Does foo.
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index af8c5b5..27a8207 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -738,7 +738,7 @@
}
Future<void> test_createChange_MethodElement_potential_inPubCache() async {
- var externalPath = '/.pub-cache/aaa/lib/lib.dart';
+ var externalPath = '$packagesRootPath/aaa/lib/lib.dart';
newFile(externalPath, content: r'''
processObj(p) {
p.test();
@@ -747,7 +747,7 @@
writeTestPackageConfig(
config: PackageConfigFileBuilder()
- ..add(name: 'aaa', rootPath: '/.pub-cache/aaa/'),
+ ..add(name: 'aaa', rootPath: '$packagesRootPath/aaa'),
);
await indexTestUnit('''
diff --git a/pkg/analysis_server/test/src/cider/signature_help_test.dart b/pkg/analysis_server/test/src/cider/signature_help_test.dart
new file mode 100644
index 0000000..2b99d72
--- /dev/null
+++ b/pkg/analysis_server/test/src/cider/signature_help_test.dart
@@ -0,0 +1,253 @@
+// 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:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/src/cider/signature_help.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:collection/collection.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'cider_service.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CiderSignatureHelpComputerTest);
+ });
+}
+
+@reflectiveTest
+class CiderSignatureHelpComputerTest extends CiderServiceTest {
+ late _CorrectionContext _correctionContext;
+
+ void test_noDefaultConstructor() {
+ var result = _compute('''
+class A {
+ A._();
+}
+
+final a = A(^);
+''');
+
+ expect(result, null);
+ }
+
+ void test_params_multipleNamed() {
+ final content = '''
+/// Does foo.
+foo(String s, {bool b = true, bool a}) {
+ foo(^);
+}
+''';
+ final expectedLabel = 'foo(String s, {bool b = true, bool a})';
+
+ testSignature(
+ content,
+ expectedLabel,
+ 'Does foo.',
+ [
+ ParameterInformation(label: 'String s'),
+ ParameterInformation(label: 'bool b = true'),
+ ParameterInformation(label: 'bool a'),
+ ],
+ CharacterLocation(3, 7));
+ }
+
+ void test_params_multipleOptional() {
+ final content = '''
+/// Does foo.
+foo(String s, [bool b = true, bool a]) {
+ foo(^);
+}
+''';
+
+ final expectedLabel = 'foo(String s, [bool b = true, bool a])';
+ testSignature(
+ content,
+ expectedLabel,
+ 'Does foo.',
+ [
+ ParameterInformation(label: 'String s'),
+ ParameterInformation(label: 'bool b = true'),
+ ParameterInformation(label: 'bool a'),
+ ],
+ CharacterLocation(3, 7));
+ }
+
+ void test_retrigger_validLocation() {
+ final content = '''
+/// Does foo.
+foo(String s, {bool b = true, bool a}) {
+ foo('ssss',^);
+}
+''';
+ final expectedLabel = 'foo(String s, {bool b = true, bool a})';
+
+ testSignature(
+ content,
+ expectedLabel,
+ 'Does foo.',
+ [
+ ParameterInformation(label: 'String s'),
+ ParameterInformation(label: 'bool b = true'),
+ ParameterInformation(label: 'bool a'),
+ ],
+ CharacterLocation(3, 7));
+ }
+
+ void test_simple() {
+ final content = '''
+/// Does foo.
+foo(String s, int i) {
+ foo(^);
+}
+''';
+ final expectedLabel = 'foo(String s, int i)';
+ testSignature(
+ content,
+ expectedLabel,
+ 'Does foo.',
+ [
+ ParameterInformation(label: 'String s'),
+ ParameterInformation(label: 'int i'),
+ ],
+ CharacterLocation(3, 7));
+ }
+
+ void test_triggerCharacter_validLocation() {
+ final content = '''
+/// Does foo.
+foo(String s, int i) {
+ foo(^
+}
+''';
+
+ final expectedLabel = 'foo(String s, int i)';
+ testSignature(
+ content,
+ expectedLabel,
+ 'Does foo.',
+ [
+ ParameterInformation(label: 'String s'),
+ ParameterInformation(label: 'int i'),
+ ],
+ CharacterLocation(3, 7));
+ }
+
+ void test_typeParams_class() {
+ final content = '''
+/// My Foo.
+class Foo<T1, T2 extends String> {}
+
+class Bar extends Foo<^> {}
+''';
+
+ testSignature(
+ content,
+ 'class Foo<T1, T2 extends String>',
+ 'My Foo.',
+ [
+ ParameterInformation(label: 'T1'),
+ ParameterInformation(label: 'T2 extends String')
+ ],
+ CharacterLocation(4, 23));
+ }
+
+ void test_typeParams_function() {
+ final content = '''
+/// My Foo.
+void foo<T1, T2 extends String>() {
+ foo<^>();
+}
+''';
+
+ testSignature(
+ content,
+ 'void foo<T1, T2 extends String>()',
+ 'My Foo.',
+ [
+ ParameterInformation(label: 'T1'),
+ ParameterInformation(label: 'T2 extends String')
+ ],
+ CharacterLocation(3, 7));
+ }
+
+ void test_typeParams_method() {
+ final content = '''
+class Foo {
+ /// My Foo.
+ void foo<T1, T2 extends String>() {
+ foo<^>();
+ }
+}
+''';
+
+ testSignature(
+ content,
+ 'void foo<T1, T2 extends String>()',
+ 'My Foo.',
+ [
+ ParameterInformation(label: 'T1'),
+ ParameterInformation(label: 'T2 extends String')
+ ],
+ CharacterLocation(4, 9));
+ }
+
+ void testSignature(
+ String content,
+ String expectedLabel,
+ String expectedDoc,
+ List<ParameterInformation> expectedParameters,
+ CharacterLocation leftParenLocation) {
+ var result = _compute(content);
+ var signature = result!.signatureHelp.signatures.first;
+ final expected =
+ MarkupContent(kind: MarkupKind.Markdown, value: expectedDoc);
+ expect(signature.label, expectedLabel);
+ expect(signature.documentation!.valueEquals(expected), isTrue);
+ expect(ListEquality().equals(expectedParameters, signature.parameters),
+ isTrue);
+ expect(result.callStart == leftParenLocation, isTrue);
+ }
+
+ SignatureHelpResponse? _compute(String content) {
+ _updateFile(content);
+
+ return CiderSignatureHelpComputer(
+ fileResolver,
+ ).compute(
+ convertPath(testPath),
+ _correctionContext.line,
+ _correctionContext.character,
+ );
+ }
+
+ void _updateFile(String content) {
+ var offset = content.indexOf('^');
+ expect(offset, isPositive, reason: 'Expected to find ^');
+ expect(content.indexOf('^', offset + 1), -1, reason: 'Expected only one ^');
+
+ var lineInfo = LineInfo.fromContent(content);
+ var location = lineInfo.getLocation(offset);
+
+ content = content.substring(0, offset) + content.substring(offset + 1);
+ newFile(testPath, content: content);
+
+ _correctionContext = _CorrectionContext(
+ content,
+ offset,
+ location.lineNumber - 1,
+ location.columnNumber - 1,
+ );
+ }
+}
+
+class _CorrectionContext {
+ final String content;
+ final int offset;
+ final int line;
+ final int character;
+
+ _CorrectionContext(this.content, this.offset, this.line, this.character);
+}
diff --git a/pkg/analysis_server/test/src/cider/test_all.dart b/pkg/analysis_server/test/src/cider/test_all.dart
index 95c39ca..2220710 100644
--- a/pkg/analysis_server/test/src/cider/test_all.dart
+++ b/pkg/analysis_server/test/src/cider/test_all.dart
@@ -8,6 +8,7 @@
import 'completion_test.dart' as completion;
import 'fixes_test.dart' as fixes;
import 'rename_test.dart' as rename;
+import 'signature_help_test.dart' as signature;
void main() {
defineReflectiveSuite(() {
@@ -15,5 +16,6 @@
completion.main();
fixes.main();
rename.main();
+ signature.main();
});
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
index 8779367..3219e6e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
@@ -21,57 +21,56 @@
Future<void> test_withClass() async {
await resolveTestCode('''
-import 'dart:collection' as pref;
-main() {
- pref.HashMap? s = null;
- LinkedHashMap? f = null;
- print('\$s \$f');
-}
+import 'dart:collection' as prefix;
+
+void f(prefix.HashMap a, HashMap b) {}
''');
await assertHasFix('''
-import 'dart:collection' as pref;
-main() {
- pref.HashMap? s = null;
- pref.LinkedHashMap? f = null;
- print('\$s \$f');
-}
+import 'dart:collection' as prefix;
+
+void f(prefix.HashMap a, prefix.HashMap b) {}
''');
}
Future<void> test_withExtension() async {
- addSource('$testPackageLibPath/lib.dart', '''
-class C {}
+ addSource('$testPackageLibPath/a.dart', '''
extension E on int {
- static String m() => '';
+ static int foo() => 0;
}
''');
await resolveTestCode('''
-import 'lib.dart' as p;
-void f(p.C c) {
- print(E.m());
+import 'a.dart' as prefix;
+
+void f() {
+ prefix.E.foo();
+ E.foo();
}
''');
await assertHasFix('''
-import 'lib.dart' as p;
-void f(p.C c) {
- print(p.E.m());
+import 'a.dart' as prefix;
+
+void f() {
+ prefix.E.foo();
+ prefix.E.foo();
}
''');
}
Future<void> test_withTopLevelVariable() async {
await resolveTestCode('''
-import 'dart:math' as pref;
-main() {
- print(pref.e);
- print(pi);
+import 'dart:math' as prefix;
+
+void f() {
+ prefix.e;
+ pi;
}
''');
await assertHasFix('''
-import 'dart:math' as pref;
-main() {
- print(pref.e);
- print(pref.pi);
+import 'dart:math' as prefix;
+
+void f() {
+ prefix.e;
+ prefix.pi;
}
''');
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index 9151d48..75e8a94 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -235,7 +235,7 @@
}
Future<void> test_extension_otherPackage_exported_fromSrc() async {
- var pkgRootPath = '/.pub-cache/aaa';
+ var pkgRootPath = '$packagesRootPath/aaa';
newFile('$pkgRootPath/lib/a.dart', content: r'''
export 'src/b.dart';
@@ -299,11 +299,13 @@
}
Future<void> test_lib() async {
- newFile('/.pub-cache/my_pkg/lib/a.dart', content: 'class Test {}');
+ newFile('$packagesRootPath/my_pkg/lib/a.dart', content: '''
+class Test {}
+''');
writeTestPackageConfig(
config: PackageConfigFileBuilder()
- ..add(name: 'my_pkg', rootPath: '/.pub-cache/my_pkg'),
+ ..add(name: 'my_pkg', rootPath: '$packagesRootPath/my_pkg'),
);
newPubspecYamlFile('/home/test', r'''
@@ -329,7 +331,7 @@
}
Future<void> test_lib_extension() async {
- newFile('/.pub-cache/my_pkg/lib/a.dart', content: '''
+ newFile('$packagesRootPath/my_pkg/lib/a.dart', content: '''
extension E on int {
static String m() => '';
}
@@ -337,7 +339,7 @@
writeTestPackageConfig(
config: PackageConfigFileBuilder()
- ..add(name: 'my_pkg', rootPath: '/.pub-cache/my_pkg'),
+ ..add(name: 'my_pkg', rootPath: '$packagesRootPath/my_pkg'),
);
newPubspecYamlFile('/home/test', r'''
@@ -361,11 +363,13 @@
}
Future<void> test_lib_src() async {
- newFile('/.pub-cache/my_pkg/lib/src/a.dart', content: 'class Test {}');
+ newFile('$packagesRootPath/my_pkg/lib/src/a.dart', content: '''
+class Test {}
+''');
writeTestPackageConfig(
config: PackageConfigFileBuilder()
- ..add(name: 'my_pkg', rootPath: '/.pub-cache/my_pkg'),
+ ..add(name: 'my_pkg', rootPath: '$packagesRootPath/my_pkg'),
);
newPubspecYamlFile('/home/test', r'''
@@ -382,7 +386,9 @@
}
Future<void> test_notInLib() async {
- addSource('/home/other/test/lib.dart', 'class Test {}');
+ addSource('/home/other/test/lib.dart', '''
+class Test {}
+''');
await resolveTestCode('''
main() {
Test t;
@@ -948,7 +954,9 @@
}
Future<void> test_withFunction_functionTopLevelVariable() async {
- addSource('$testPackageLibPath/lib.dart', 'var myFunction = () {};');
+ addSource('$testPackageLibPath/lib.dart', '''
+var myFunction = () {};
+''');
await resolveTestCode('''
main() {
myFunction();
@@ -964,7 +972,9 @@
}
Future<void> test_withFunction_functionTopLevelVariableIdentifier() async {
- addSource('$testPackageLibPath/lib.dart', 'var myFunction = () {};');
+ addSource('$testPackageLibPath/lib.dart', '''
+var myFunction = () {};
+''');
await resolveTestCode('''
main() {
myFunction;
@@ -1000,7 +1010,9 @@
@failingTest
Future<void> test_withFunction_nonFunctionType() async {
- addSource('$testPackageLibPath/lib.dart', 'int zero = 0;');
+ addSource('$testPackageLibPath/lib.dart', '''
+int zero = 0;
+''');
await resolveTestCode('''
main() {
zero();
@@ -1053,6 +1065,67 @@
''');
}
+ Future<void> test_withGetter_read() async {
+ addSource('$testPackageLibPath/a.dart', '''
+int get foo => 0;
+''');
+
+ await resolveTestCode('''
+void f() {
+ foo;
+}
+''');
+
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+ foo;
+}
+''');
+ }
+
+ Future<void> test_withGetter_readWrite() async {
+ addSource('$testPackageLibPath/a.dart', '''
+int get foo => 0;
+''');
+
+ await resolveTestCode('''
+void f() {
+ foo++;
+}
+''');
+
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+ foo++;
+}
+''');
+ }
+
+ /// Not really useful, but shows what we have.
+ Future<void> test_withGetter_write() async {
+ addSource('$testPackageLibPath/a.dart', '''
+int get foo => 0;
+''');
+
+ await resolveTestCode('''
+void f() {
+ foo = 0;
+}
+''');
+
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+ foo = 0;
+}
+''');
+ }
+
Future<void> test_withMixin() async {
addSource('$testPackageLibPath/lib.dart', '''
mixin Test {}
@@ -1067,21 +1140,80 @@
''');
}
- Future<void> test_withTopLevelVariable() async {
- addSource('$testPackageLibPath/lib.dart', '''
-library lib;
-int MY_VAR = 42;
+ Future<void> test_withSetter_assignment() async {
+ addSource('$testPackageLibPath/a.dart', '''
+set foo(int _) {}
''');
+
await resolveTestCode('''
-main() {
- print(MY_VAR);
+void f() {
+ foo = 0;
}
''');
- await assertHasFix('''
-import 'package:test/lib.dart';
-main() {
- print(MY_VAR);
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+ foo = 0;
+}
+''');
+ }
+
+ Future<void> test_withTopLevelVariable_annotation() async {
+ addSource('$testPackageLibPath/a.dart', '''
+const foo = 0;
+''');
+
+ await resolveTestCode('''
+@foo
+void f() {}
+''');
+
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+@foo
+void f() {}
+''');
+ }
+
+ Future<void> test_withTopLevelVariable_read() async {
+ addSource('$testPackageLibPath/a.dart', '''
+var foo = 0;
+''');
+
+ await resolveTestCode('''
+void f() {
+ foo;
+}
+''');
+
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+ foo;
+}
+''');
+ }
+
+ Future<void> test_withTopLevelVariable_write() async {
+ addSource('$testPackageLibPath/a.dart', '''
+var foo = 0;
+''');
+
+ await resolveTestCode('''
+void f() {
+ foo = 0;
+}
+''');
+
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+void f() {
+ foo = 0;
}
''');
}
@@ -1093,12 +1225,16 @@
FixKind get kind => DartFixKind.IMPORT_LIBRARY_PROJECT2;
Future<void> test_lib() async {
- newFile('/.pub-cache/my_pkg/lib/a.dart', content: "export 'b.dart';");
- newFile('/.pub-cache/my_pkg/lib/b.dart', content: 'class Test {}');
+ newFile('$packagesRootPath/my_pkg/lib/a.dart', content: '''
+export 'b.dart';
+''');
+ newFile('$packagesRootPath/my_pkg/lib/b.dart', content: '''
+class Test {}
+''');
writeTestPackageConfig(
config: PackageConfigFileBuilder()
- ..add(name: 'my_pkg', rootPath: '/.pub-cache/my_pkg'),
+ ..add(name: 'my_pkg', rootPath: '$packagesRootPath/my_pkg'),
);
newPubspecYamlFile('/home/test', r'''
@@ -1122,12 +1258,16 @@
}
Future<void> test_lib_src() async {
- newFile('/.pub-cache/my_pkg/lib/a.dart', content: "export 'src/b.dart';");
- newFile('/.pub-cache/my_pkg/lib/src/b.dart', content: 'class Test {}');
+ newFile('$packagesRootPath/my_pkg/lib/a.dart', content: '''
+export 'src/b.dart';
+''');
+ newFile('$packagesRootPath/my_pkg/lib/src/b.dart', content: '''
+class Test {}
+''');
writeTestPackageConfig(
config: PackageConfigFileBuilder()
- ..add(name: 'my_pkg', rootPath: '/.pub-cache/my_pkg'),
+ ..add(name: 'my_pkg', rootPath: '$packagesRootPath/my_pkg'),
);
newPubspecYamlFile('/home/test', r'''
@@ -1151,8 +1291,10 @@
}
Future<void> test_lib_src_extension() async {
- newFile('/.pub-cache/my_pkg/lib/a.dart', content: "export 'src/b.dart';");
- newFile('/.pub-cache/my_pkg/lib/src/b.dart', content: '''
+ newFile('$packagesRootPath/my_pkg/lib/a.dart', content: '''
+export 'src/b.dart';
+''');
+ newFile('$packagesRootPath/my_pkg/lib/src/b.dart', content: '''
extension E on int {
static String m() => '';
}
@@ -1160,7 +1302,7 @@
writeTestPackageConfig(
config: PackageConfigFileBuilder()
- ..add(name: 'my_pkg', rootPath: '/.pub-cache/my_pkg'),
+ ..add(name: 'my_pkg', rootPath: '$packagesRootPath/my_pkg'),
);
newPubspecYamlFile('/home/test', r'''
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 36944a5..f5e2631 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,4 +1,4 @@
-## 3.0.0 (Not yet released - breaking changes)
+## 3.0.0
* Removed deprecated `DartType.aliasElement/aliasArguments`.
* Removed deprecated constructors from `FeatureSet`.
* Removed `UnitElementResult.signature` - unused by clients.
diff --git a/pkg/analyzer/lib/src/dart/resolver/applicable_extensions.dart b/pkg/analyzer/lib/src/dart/resolver/applicable_extensions.dart
new file mode 100644
index 0000000..95d2c81
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/applicable_extensions.dart
@@ -0,0 +1,177 @@
+// 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/analysis/features.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/generic_inferrer.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/resolution_result.dart';
+
+/// Extensions that can be applied, within the [targetLibrary], to the
+/// [targetType], and that define a member with the base [memberName].
+class ApplicableExtensions {
+ final LibraryElementImpl targetLibrary;
+ final DartType targetType;
+ final String memberName;
+
+ ApplicableExtensions({
+ required LibraryElement targetLibrary,
+ required this.targetType,
+ required this.memberName,
+ }) : targetLibrary = targetLibrary as LibraryElementImpl;
+
+ bool get _genericMetadataIsEnabled {
+ return targetLibrary.featureSet.isEnabled(
+ Feature.generic_metadata,
+ );
+ }
+
+ TypeSystemImpl get _typeSystem {
+ return targetLibrary.typeSystem;
+ }
+
+ /// Return [extensions] that match the configuration.
+ List<InstantiatedExtension> instantiate(
+ Iterable<ExtensionElement> extensions,
+ ) {
+ if (identical(targetType, NeverTypeImpl.instance)) {
+ return const <InstantiatedExtension>[];
+ }
+
+ var instantiatedExtensions = <InstantiatedExtension>[];
+
+ var candidates = _withMember(extensions);
+ for (var candidate in candidates) {
+ var extension = candidate.extension;
+
+ var freshTypes = getFreshTypeParameters(extension.typeParameters);
+ var freshTypeParameters = freshTypes.freshTypeParameters;
+ var rawExtendedType = freshTypes.substitute(extension.extendedType);
+
+ var inferrer = GenericInferrer(_typeSystem, freshTypeParameters);
+ inferrer.constrainArgument(
+ targetType,
+ rawExtendedType,
+ 'extendedType',
+ );
+ var typeArguments = inferrer.infer(
+ freshTypeParameters,
+ failAtError: true,
+ genericMetadataIsEnabled: _genericMetadataIsEnabled,
+ );
+ if (typeArguments == null) {
+ continue;
+ }
+
+ var substitution = Substitution.fromPairs(
+ extension.typeParameters,
+ typeArguments,
+ );
+ var extendedType = substitution.substituteType(
+ extension.extendedType,
+ );
+
+ if (!_typeSystem.isSubtypeOf(targetType, extendedType)) {
+ continue;
+ }
+
+ instantiatedExtensions.add(
+ InstantiatedExtension(candidate, substitution, extendedType),
+ );
+ }
+
+ return instantiatedExtensions;
+ }
+
+ /// Return [extensions] that define a member with the [memberName].
+ List<_CandidateExtension> _withMember(
+ Iterable<ExtensionElement> extensions,
+ ) {
+ var result = <_CandidateExtension>[];
+ for (var extension in extensions) {
+ for (var field in extension.fields) {
+ if (field.name == memberName) {
+ result.add(
+ _CandidateExtension(
+ extension,
+ getter: field.getter,
+ setter: field.setter,
+ ),
+ );
+ break;
+ }
+ }
+ if (memberName == '[]') {
+ ExecutableElement? getter;
+ ExecutableElement? setter;
+ for (var method in extension.methods) {
+ if (method.name == '[]') {
+ getter = method;
+ } else if (method.name == '[]=') {
+ setter = method;
+ }
+ }
+ if (getter != null || setter != null) {
+ result.add(
+ _CandidateExtension(extension, getter: getter, setter: setter),
+ );
+ }
+ } else {
+ for (var method in extension.methods) {
+ if (method.name == memberName) {
+ result.add(
+ _CandidateExtension(extension, getter: method),
+ );
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+}
+
+class InstantiatedExtension {
+ final _CandidateExtension candidate;
+ final MapSubstitution substitution;
+ final DartType extendedType;
+
+ InstantiatedExtension(this.candidate, this.substitution, this.extendedType);
+
+ ResolutionResult get asResolutionResult {
+ return ResolutionResult(getter: getter, setter: setter);
+ }
+
+ ExtensionElement get extension => candidate.extension;
+
+ ExecutableElement? get getter {
+ var getter = candidate.getter;
+ if (getter == null) {
+ return null;
+ }
+ return ExecutableMember.from2(getter, substitution);
+ }
+
+ ExecutableElement? get setter {
+ var setter = candidate.setter;
+ if (setter == null) {
+ return null;
+ }
+ return ExecutableMember.from2(setter, substitution);
+ }
+}
+
+class _CandidateExtension {
+ final ExtensionElement extension;
+ final ExecutableElement? getter;
+ final ExecutableElement? setter;
+
+ _CandidateExtension(this.extension, {this.getter, this.setter})
+ : assert(getter != null || setter != null);
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
index c7afae0..a166ff7 100644
--- a/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/extension_member_resolver.dart
@@ -13,10 +13,10 @@
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/generic_inferrer.dart';
import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/dart/element/type_schema.dart';
import 'package:analyzer/src/dart/element/type_system.dart';
+import 'package:analyzer/src/dart/resolver/applicable_extensions.dart';
import 'package:analyzer/src/dart/resolver/resolution_result.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -54,7 +54,11 @@
SyntacticEntity nameEntity,
String name,
) {
- var extensions = _getApplicable(type, name);
+ var extensions = ApplicableExtensions(
+ targetLibrary: _resolver.definingLibrary,
+ targetType: type,
+ memberName: name,
+ ).instantiate(_resolver.definingLibrary.accessibleExtensions);
if (extensions.isEmpty) {
return ResolutionResult.none;
@@ -263,10 +267,10 @@
/// Return either the most specific extension, or a list of the extensions
/// that are ambiguous.
- Either2<_InstantiatedExtension, List<_InstantiatedExtension>>
- _chooseMostSpecific(List<_InstantiatedExtension> extensions) {
- _InstantiatedExtension? bestSoFar;
- var noneMoreSpecific = <_InstantiatedExtension>[];
+ Either2<InstantiatedExtension, List<InstantiatedExtension>>
+ _chooseMostSpecific(List<InstantiatedExtension> extensions) {
+ InstantiatedExtension? bestSoFar;
+ var noneMoreSpecific = <InstantiatedExtension>[];
for (var candidate in extensions) {
if (noneMoreSpecific.isNotEmpty) {
var isMostSpecific = true;
@@ -305,110 +309,6 @@
}
}
- /// Return extensions for the [type] that match the given [name] in the
- /// current scope.
- List<_InstantiatedExtension> _getApplicable(DartType type, String name) {
- if (identical(type, NeverTypeImpl.instance)) {
- return const <_InstantiatedExtension>[];
- }
-
- var candidates = _getExtensionsWithMember(name);
-
- var instantiatedExtensions = <_InstantiatedExtension>[];
- for (var candidate in candidates) {
- var extension = candidate.extension;
-
- var freshTypes = getFreshTypeParameters(extension.typeParameters);
- var freshTypeParameters = freshTypes.freshTypeParameters;
- var rawExtendedType = freshTypes.substitute(extension.extendedType);
-
- var inferrer = GenericInferrer(_typeSystem, freshTypeParameters);
- inferrer.constrainArgument(
- type,
- rawExtendedType,
- 'extendedType',
- );
- var typeArguments = inferrer.infer(
- freshTypeParameters,
- failAtError: true,
- genericMetadataIsEnabled: _genericMetadataIsEnabled,
- );
- if (typeArguments == null) {
- continue;
- }
-
- var substitution = Substitution.fromPairs(
- extension.typeParameters,
- typeArguments,
- );
- var extendedType = substitution.substituteType(
- extension.extendedType,
- );
- if (!_isSubtypeOf(type, extendedType)) {
- continue;
- }
-
- instantiatedExtensions.add(
- _InstantiatedExtension(candidate, substitution, extendedType),
- );
- }
-
- return instantiatedExtensions;
- }
-
- /// Return extensions from the current scope, that define a member with the
- /// given [name].
- List<_CandidateExtension> _getExtensionsWithMember(String name) {
- var candidates = <_CandidateExtension>[];
-
- /// Add the given [extension] to the list of [candidates] if it defined a
- /// member whose name matches the target [name].
- void checkExtension(ExtensionElement extension) {
- for (var field in extension.fields) {
- if (field.name == name) {
- candidates.add(
- _CandidateExtension(
- extension,
- getter: field.getter,
- setter: field.setter,
- ),
- );
- return;
- }
- }
- if (name == '[]') {
- ExecutableElement? getter;
- ExecutableElement? setter;
- for (var method in extension.methods) {
- if (method.name == '[]') {
- getter = method;
- } else if (method.name == '[]=') {
- setter = method;
- }
- }
- if (getter != null || setter != null) {
- candidates.add(
- _CandidateExtension(extension, getter: getter, setter: setter),
- );
- }
- } else {
- for (var method in extension.methods) {
- if (method.name == name) {
- candidates.add(
- _CandidateExtension(extension, getter: method),
- );
- return;
- }
- }
- }
- }
-
- for (var extension in _resolver.definingLibrary.accessibleExtensions) {
- checkExtension(extension);
- }
- return candidates;
- }
-
/// Given the generic [element] element, either return types specified
/// explicitly in [typeArguments], or infer type arguments from the given
/// [receiverType].
@@ -469,7 +369,7 @@
}
/// Return `true` is [e1] is more specific than [e2].
- bool _isMoreSpecific(_InstantiatedExtension e1, _InstantiatedExtension e2) {
+ bool _isMoreSpecific(InstantiatedExtension e1, InstantiatedExtension e2) {
// 1. The latter extension is declared in a platform library, and the
// former extension is not.
// 2. They are both declared in platform libraries, or both declared in
@@ -531,42 +431,3 @@
parent is PropertyAccess && parent.target == node;
}
}
-
-class _CandidateExtension {
- final ExtensionElement extension;
- final ExecutableElement? getter;
- final ExecutableElement? setter;
-
- _CandidateExtension(this.extension, {this.getter, this.setter})
- : assert(getter != null || setter != null);
-}
-
-class _InstantiatedExtension {
- final _CandidateExtension candidate;
- final MapSubstitution substitution;
- final DartType extendedType;
-
- _InstantiatedExtension(this.candidate, this.substitution, this.extendedType);
-
- ResolutionResult get asResolutionResult {
- return ResolutionResult(getter: getter, setter: setter);
- }
-
- ExtensionElement get extension => candidate.extension;
-
- ExecutableElement? get getter {
- var getter = candidate.getter;
- if (getter == null) {
- return null;
- }
- return ExecutableMember.from2(getter, substitution);
- }
-
- ExecutableElement? get setter {
- var setter = candidate.setter;
- if (setter == null) {
- return null;
- }
- return ExecutableMember.from2(setter, substitution);
- }
-}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index ab9503d..9261ded 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 3.0.0-dev
+version: 3.0.0
description: This package provides a library that performs static analysis of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer
@@ -7,7 +7,7 @@
sdk: '>=2.14.0 <3.0.0'
dependencies:
- _fe_analyzer_shared: ^31.0.0
+ _fe_analyzer_shared: ^32.0.0
cli_util: ^0.3.0
collection: ^1.15.0
convert: ^3.0.0
diff --git a/pkg/dev_compiler/lib/src/kernel/module_symbols.dart b/pkg/dev_compiler/lib/src/kernel/module_symbols.dart
index 6b9f782..8e90b06 100644
--- a/pkg/dev_compiler/lib/src/kernel/module_symbols.dart
+++ b/pkg/dev_compiler/lib/src/kernel/module_symbols.dart
@@ -142,20 +142,17 @@
ModuleSymbols.fromJson(Map<String, dynamic> json)
: version = _readAndValidateVersionFromJson(json['version']),
moduleName = _createValue(json['moduleName']),
- libraries = _createObjectList(
- json['libraries'], (json) => LibrarySymbol.fromJson(json)),
- scripts =
- _createObjectList(json['scripts'], (json) => Script.fromJson(json)),
- classes = _createObjectList(
- json['classes'], (json) => ClassSymbol.fromJson(json)),
+ libraries =
+ _createObjectList(json['libraries'], LibrarySymbol.fromJson),
+ scripts = _createObjectList(json['scripts'], Script.fromJson),
+ classes = _createObjectList(json['classes'], ClassSymbol.fromJson),
functionTypes = _createObjectList(
- json['functionTypes'], (json) => FunctionTypeSymbol.fromJson(json)),
- functions = _createObjectList(
- json['functions'], (json) => FunctionSymbol.fromJson(json)),
- scopes = _createObjectList(
- json['scopes'], (json) => ScopeSymbol.fromJson(json)),
- variables = _createObjectList(
- json['variables'], (json) => VariableSymbol.fromJson(json));
+ json['functionTypes'], FunctionTypeSymbol.fromJson),
+ functions =
+ _createObjectList(json['functions'], FunctionSymbol.fromJson),
+ scopes = _createObjectList(json['scopes'], ScopeSymbol.fromJson),
+ variables =
+ _createObjectList(json['variables'], VariableSymbol.fromJson);
@override
Map<String, dynamic> toJson() {
@@ -208,8 +205,8 @@
Symbol.fromJson(Map<String, dynamic> json)
: localId = _createValue(json['localId']),
scopeId = _createValue(json['scopeId']),
- location = _createNullableObject(
- json['location'], (json) => SourceLocation.fromJson(json));
+ location =
+ _createNullableObject(json['location'], SourceLocation.fromJson);
@override
Map<String, dynamic> toJson() {
@@ -527,8 +524,8 @@
: name = _createValue(json['name'], ifNull: ''),
uri = _createValue(json['uri']),
scriptIds = _createValueList(json['scriptIds']),
- dependencies = _createObjectList(json['dependencies'],
- (json) => LibrarySymbolDependency.fromJson(json)),
+ dependencies = _createObjectList(
+ json['dependencies'], LibrarySymbolDependency.fromJson),
super.fromJson(json);
@override
diff --git a/pkg/dev_compiler/pubspec.yaml b/pkg/dev_compiler/pubspec.yaml
index f8e49e9..0d15516 100644
--- a/pkg/dev_compiler/pubspec.yaml
+++ b/pkg/dev_compiler/pubspec.yaml
@@ -3,7 +3,7 @@
publish_to: none
environment:
- sdk: '>=2.12.0 <3.0.0'
+ sdk: '>=2.15.0 <3.0.0'
dependencies:
_fe_analyzer_shared: any
diff --git a/pkg/front_end/testcases/general/invalid_operator.dart.weak.expect b/pkg/front_end/testcases/general/invalid_operator.dart.weak.expect
index c3f1e06..1bababf 100644
--- a/pkg/front_end/testcases/general/invalid_operator.dart.weak.expect
+++ b/pkg/front_end/testcases/general/invalid_operator.dart.weak.expect
@@ -564,35 +564,35 @@
// Try adding explicit types.
// operator ==<T>(a) => true;
// ^^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is one of the overridden members.
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is one of the overridden members.
// external bool operator ==(Object other);
// ^^
//
// pkg/front_end/testcases/general/invalid_operator.dart:6:12: Error: The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==() => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:27:12: Error: The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
// operator ==(a, b) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:71:12: Error: The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==({a}) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
// operator ==<T>(a) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
diff --git a/pkg/front_end/testcases/general/invalid_operator.dart.weak.modular.expect b/pkg/front_end/testcases/general/invalid_operator.dart.weak.modular.expect
index c3f1e06..1bababf 100644
--- a/pkg/front_end/testcases/general/invalid_operator.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/invalid_operator.dart.weak.modular.expect
@@ -564,35 +564,35 @@
// Try adding explicit types.
// operator ==<T>(a) => true;
// ^^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is one of the overridden members.
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is one of the overridden members.
// external bool operator ==(Object other);
// ^^
//
// pkg/front_end/testcases/general/invalid_operator.dart:6:12: Error: The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==() => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:27:12: Error: The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
// operator ==(a, b) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:71:12: Error: The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==({a}) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
// operator ==<T>(a) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
diff --git a/pkg/front_end/testcases/general/invalid_operator.dart.weak.outline.expect b/pkg/front_end/testcases/general/invalid_operator.dart.weak.outline.expect
index c1ee228..c9f7e40 100644
--- a/pkg/front_end/testcases/general/invalid_operator.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/invalid_operator.dart.weak.outline.expect
@@ -564,35 +564,35 @@
// Try adding explicit types.
// operator ==<T>(a) => true;
// ^^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is one of the overridden members.
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is one of the overridden members.
// external bool operator ==(Object other);
// ^^
//
// pkg/front_end/testcases/general/invalid_operator.dart:6:12: Error: The method 'Operators1.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==() => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:27:12: Error: The method 'Operators2.==' has more required arguments than those of overridden method 'Object.=='.
// operator ==(a, b) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:71:12: Error: The method 'Operators4.==' has fewer positional arguments than those of overridden method 'Object.=='.
// operator ==({a}) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
// pkg/front_end/testcases/general/invalid_operator.dart:137:12: Error: Declared type variables of 'Operators7.==' doesn't match those on overridden method 'Object.=='.
// operator ==<T>(a) => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
diff --git a/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect
index 1717f29..7d802ac 100644
--- a/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42603.dart.strong.expect
@@ -9,7 +9,7 @@
// pkg/front_end/testcases/nnbd/issue42603.dart:18:17: Error: The method 'E.==' has fewer positional arguments than those of overridden method 'Object.=='.
// bool operator ==() => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
diff --git a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect
index 1717f29..7d802ac 100644
--- a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.expect
@@ -9,7 +9,7 @@
// pkg/front_end/testcases/nnbd/issue42603.dart:18:17: Error: The method 'E.==' has fewer positional arguments than those of overridden method 'Object.=='.
// bool operator ==() => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
diff --git a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.modular.expect
index 1717f29..7d802ac 100644
--- a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.modular.expect
@@ -9,7 +9,7 @@
// pkg/front_end/testcases/nnbd/issue42603.dart:18:17: Error: The method 'E.==' has fewer positional arguments than those of overridden method 'Object.=='.
// bool operator ==() => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
diff --git a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.outline.expect
index f1a33e9..390818a 100644
--- a/pkg/front_end/testcases/nnbd/issue42603.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42603.dart.weak.outline.expect
@@ -9,7 +9,7 @@
// pkg/front_end/testcases/nnbd/issue42603.dart:18:17: Error: The method 'E.==' has fewer positional arguments than those of overridden method 'Object.=='.
// bool operator ==() => true;
// ^
-// sdk/lib/_internal/vm/lib/object_patch.dart:29:26: Context: This is the overridden method ('==').
+// sdk/lib/_internal/vm/lib/object_patch.dart:21:26: Context: This is the overridden method ('==').
// external bool operator ==(Object other);
// ^
//
diff --git a/pkg/js/pubspec.yaml b/pkg/js/pubspec.yaml
index 44b80a9..40fde9c 100644
--- a/pkg/js/pubspec.yaml
+++ b/pkg/js/pubspec.yaml
@@ -1,10 +1,10 @@
name: js
-version: 0.6.3
+version: 0.6.4
description: Annotations to create static Dart interfaces for JavaScript APIs.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/js
environment:
- sdk: ">=2.12.0-0 <3.0.0"
+ sdk: ">=2.16.0-100.0.dev <3.0.0"
dev_dependencies:
pedantic: ^1.9.0
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
index 8964972..ebc13da 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/enum_from_lib_used_as_type.dart.expect
@@ -22,6 +22,6 @@
synthetic constructor •() → self::Class
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3305,getterSelectorId:3306] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3303,getterSelectorId:3304] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::Enum e) → core::int
return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
index 7251a55..d0ed61e 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tree_shake_enum_from_lib.dart.expect
@@ -51,6 +51,6 @@
synthetic constructor •() → self::ConstClass
: super core::Object::•()
;
-[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3309,getterSelectorId:3310] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
+[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3307,getterSelectorId:3308] method method([@vm.inferred-type.metadata=dart.core::Null? (value: null)] self::ConstEnum e) → core::int
return [@vm.inferred-type.metadata=!] e.{core::_Enum::index}{core::int};
}
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index f8e903e..2b7a470 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -48,20 +48,14 @@
// Please note that no handle is created for the argument.
// This is safe since the argument is only used in a tail call.
// The performance benefit is more than 5% when using hashCode.
- return Smi::New(GetHash(isolate, arguments->NativeArgAt(0)));
-}
+ intptr_t hash = GetHash(isolate, arguments->NativeArgAt(0));
+ if (LIKELY(hash != 0)) {
+ return Smi::New(hash);
+ }
-DEFINE_NATIVE_ENTRY(Object_setHashIfNotSetYet, 0, 2) {
- GET_NON_NULL_NATIVE_ARGUMENT(Smi, hash, arguments->NativeArgAt(1));
-#if defined(HASH_IN_OBJECT_HEADER)
- return Smi::New(
- Object::SetCachedHashIfNotSet(arguments->NativeArgAt(0), hash.Value()));
-#else
const Instance& instance =
Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
- Heap* heap = thread->heap();
- return Smi::New(heap->SetHashIfNotSet(instance.ptr(), hash.Value()));
-#endif
+ return instance.IdentityHashCode(arguments->thread());
}
DEFINE_NATIVE_ENTRY(Object_toString, 0, 1) {
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index adade03..50e587f 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -18,7 +18,6 @@
V(DartAsync_fatal, 1) \
V(Object_equals, 2) \
V(Object_getHash, 1) \
- V(Object_setHashIfNotSetYet, 2) \
V(Object_toString, 1) \
V(Object_runtimeType, 1) \
V(Object_haveSameRuntimeType, 2) \
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index b61046d..e811039 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -1548,11 +1548,6 @@
UNREACHABLE();
}
-void AsmIntrinsifier::Object_setHashIfNotSetYet(Assembler* assembler,
- Label* normal_ir_body) {
- UNREACHABLE();
-}
-
void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
Label* normal_ir_body) {
Label try_two_byte_string;
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index b6796b5..f9c178a 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -1578,21 +1578,37 @@
__ Bind(normal_ir_body);
}
+// Keep in sync with Instance::IdentityHashCode.
+// Note int and double never reach here because they override _identityHashCode.
+// Special cases are also not needed for null or bool because they were pre-set
+// during VM isolate finalization.
void AsmIntrinsifier::Object_getHash(Assembler* assembler,
Label* normal_ir_body) {
- __ ldr(R0, Address(SP, 0 * target::kWordSize));
- __ ldr(R0, FieldAddress(R0, target::String::hash_offset(), kFourBytes),
+ Label not_yet_computed;
+ __ ldr(R0, Address(SP, 0 * target::kWordSize)); // Object.
+ __ ldr(R0,
+ FieldAddress(R0,
+ target::Object::tags_offset() +
+ target::UntaggedObject::kHashTagPos / kBitsPerByte,
+ kFourBytes),
kUnsignedFourBytes);
+ __ cbz(¬_yet_computed, R0);
__ SmiTag(R0);
__ ret();
-}
-void AsmIntrinsifier::Object_setHashIfNotSetYet(Assembler* assembler,
- Label* normal_ir_body) {
- __ ldp(/*Value=*/R1, /*Object=*/R0, Address(SP, 0, Address::PairOffset));
- // R0: Untagged address of header word (ldxr/stxr do not support offsets).
+ __ Bind(¬_yet_computed);
+ __ LoadFromOffset(R1, THR, target::Thread::random_offset());
+ __ AndImmediate(R2, R1, 0xffffffff); // state_lo
+ __ LsrImmediate(R3, R1, 32); // state_hi
+ __ LoadImmediate(R1, 0xffffda61); // A
+ __ mul(R1, R1, R2);
+ __ add(R1, R1, Operand(R3)); // new_state = (A * state_lo) + state_hi
+ __ StoreToOffset(R1, THR, target::Thread::random_offset());
+ __ AndImmediate(R1, R1, 0x3fffffff);
+ __ cbz(¬_yet_computed, R1);
+
+ __ ldr(R0, Address(SP, 0 * target::kWordSize)); // Object.
__ sub(R0, R0, Operand(kHeapObjectTag));
- __ SmiUntag(R1);
__ LslImmediate(R3, R1, target::UntaggedObject::kHashTagPos);
Label retry, already_set_in_r4;
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 0c58ca7..341c285 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -1555,11 +1555,6 @@
UNREACHABLE();
}
-void AsmIntrinsifier::Object_setHashIfNotSetYet(Assembler* assembler,
- Label* normal_ir_body) {
- UNREACHABLE();
-}
-
void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
Label* normal_ir_body) {
Label try_two_byte_string;
diff --git a/runtime/vm/compiler/asm_intrinsifier_test.cc b/runtime/vm/compiler/asm_intrinsifier_test.cc
index e5678ee..fb112f1 100644
--- a/runtime/vm/compiler/asm_intrinsifier_test.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_test.cc
@@ -10,78 +10,4 @@
namespace dart {
-static intptr_t GetHash(Isolate* isolate, const ObjectPtr obj) {
-#if defined(HASH_IN_OBJECT_HEADER)
- return Object::GetCachedHash(obj);
-#else
- Heap* heap = isolate->group()->heap();
- ASSERT(obj->IsDartInstance());
- return heap->GetHash(obj);
-#endif
-}
-
-ISOLATE_UNIT_TEST_CASE(AsmIntrinsifier_SetHashIfNotSetYet) {
- auto I = Isolate::Current();
- const auto& corelib = Library::Handle(Library::CoreLibrary());
- const auto& name = String::Handle(String::New("_setHashIfNotSetYet"));
- const auto& symbol = String::Handle(Symbols::New(thread, name));
-
- const auto& function =
- Function::Handle(corelib.LookupFunctionAllowPrivate(symbol));
- const auto& object_class =
- Class::Handle(corelib.LookupClass(Symbols::Object()));
-
- auto& smi0 = Smi::Handle(Smi::New(0));
- auto& smi21 = Smi::Handle(Smi::New(21));
- auto& smi42 = Smi::Handle(Smi::New(42));
- const auto& obj = Object::Handle(Instance::New(object_class));
- const auto& args = Array::Handle(Array::New(2));
-
- const auto& args_descriptor_array =
- Array::Handle(ArgumentsDescriptor::NewBoxed(0, 2, Array::empty_array()));
-
- // Initialized to 0
- EXPECT_EQ(smi0.ptr(), Smi::New(GetHash(I, obj.ptr())));
-
- // Lazily set to 42 on first call.
- args.SetAt(0, obj);
- args.SetAt(1, smi42);
- EXPECT_EQ(smi42.ptr(),
- DartEntry::InvokeFunction(function, args, args_descriptor_array));
- EXPECT_EQ(smi42.ptr(), Smi::New(GetHash(I, obj.ptr())));
-
- // Stays at 42 on subsequent calls.
- args.SetAt(0, obj);
- args.SetAt(1, smi21);
- EXPECT_EQ(smi42.ptr(),
- DartEntry::InvokeFunction(function, args, args_descriptor_array));
- EXPECT_EQ(smi42.ptr(), Smi::New(GetHash(I, obj.ptr())));
-
- // We test setting the maximum value our core libraries would use when
- // installing an identity hash code (see
- // sdk/lib/_internal/vm/lib/object_patch.dart:Object._objectHashCode)
- //
- // This value is representable as a positive Smi on all architectures (even
- // compressed pointers).
- const auto& smiMax = Smi::Handle(Smi::New(0x40000000 - 1));
- const auto& obj2 = Object::Handle(Instance::New(object_class));
-
- // Initialized to 0
- EXPECT_EQ(smi0.ptr(), Smi::New(GetHash(I, obj2.ptr())));
-
- // Lazily set to smiMax first call.
- args.SetAt(0, obj2);
- args.SetAt(1, smiMax);
- EXPECT_EQ(smiMax.ptr(),
- DartEntry::InvokeFunction(function, args, args_descriptor_array));
- EXPECT_EQ(smiMax.ptr(), Smi::New(GetHash(I, obj2.ptr())));
-
- // Stays at smiMax on subsequent calls.
- args.SetAt(0, obj2);
- args.SetAt(1, smi21);
- EXPECT_EQ(smiMax.ptr(),
- DartEntry::InvokeFunction(function, args, args_descriptor_array));
- EXPECT_EQ(smiMax.ptr(), Smi::New(GetHash(I, obj2.ptr())));
-}
-
} // namespace dart
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index c4e02a9..e2f7b24 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -1452,21 +1452,35 @@
__ Bind(normal_ir_body);
}
+// Keep in sync with Instance::IdentityHashCode.
+// Note int and double never reach here because they override _identityHashCode.
+// Special cases are also not needed for null or bool because they were pre-set
+// during VM isolate finalization.
void AsmIntrinsifier::Object_getHash(Assembler* assembler,
Label* normal_ir_body) {
+ Label not_yet_computed;
__ movq(RAX, Address(RSP, +1 * target::kWordSize)); // Object.
- __ movl(RAX, FieldAddress(RAX, target::String::hash_offset()));
+ __ movl(RAX, FieldAddress(RAX, target::Object::tags_offset() +
+ target::UntaggedObject::kHashTagPos /
+ kBitsPerByte));
+ __ cmpl(RAX, Immediate(0));
+ __ j(EQUAL, ¬_yet_computed, Assembler::kNearJump);
__ SmiTag(RAX);
__ ret();
-}
-void AsmIntrinsifier::Object_setHashIfNotSetYet(Assembler* assembler,
- Label* normal_ir_body) {
- ASSERT(target::String::hash_offset() == 4);
+ __ Bind(¬_yet_computed);
+ __ movq(RCX, Address(THR, target::Thread::random_offset()));
+ __ movq(RBX, RCX);
+ __ andq(RCX, Immediate(0xffffffff)); // state_lo
+ __ shrq(RBX, Immediate(32)); // state_hi
+ __ imulq(RCX, Immediate(0xffffda61)); // A
+ __ addq(RCX, RBX); // new_state = (A* state_lo) + state_hi
+ __ movq(Address(THR, target::Thread::random_offset()), RCX);
+ __ andq(RCX, Immediate(0x3fffffff));
+ __ cmpl(RCX, Immediate(0));
+ __ j(EQUAL, ¬_yet_computed);
- __ movq(RBX, Address(RSP, +2 * target::kWordSize)); // Object.
- __ movq(RCX, Address(RSP, +1 * target::kWordSize)); // Value.
- __ SmiUntag(RCX);
+ __ movq(RBX, Address(RSP, +1 * target::kWordSize)); // Object.
__ MoveRegister(RDX, RCX);
__ shlq(RDX, Immediate(32));
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 4ba80d9f..072e8ca 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -275,9 +275,7 @@
// identity hash is not stored in the header of the object. We
// therefore don't intrinsify them, falling back on the native C++
// implementations.
- if (function.recognized_kind() == MethodRecognizer::kObject_getHash ||
- function.recognized_kind() ==
- MethodRecognizer::kObject_setHashIfNotSetYet) {
+ if (function.recognized_kind() == MethodRecognizer::kObject_getHash) {
return false;
}
#endif
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 2d60271..e2f2083 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -290,7 +290,6 @@
V(_FunctionType, get:hashCode, FunctionType_getHashCode, 0x75e0d454) \
V(_FunctionType, ==, FunctionType_equality, 0x465868ae) \
V(::, _getHash, Object_getHash, 0xc60ff758) \
- V(::, _setHashIfNotSetYet, Object_setHashIfNotSetYet, 0x4e17c2f5) \
#define CORE_INTEGER_LIB_INTRINSIC_LIST(V) \
V(_IntegerImplementation, >, Integer_greaterThan, 0xf741693b) \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index abb824d..bc2daf8 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -99,7 +99,7 @@
intptr_t ObjectHash(const Object& obj) {
if (obj.IsNull()) {
- return 2011;
+ return kNullIdentityHash;
}
if (obj.IsInstance()) {
return Instance::Cast(obj).CanonicalizeHash();
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 8d9a7a1..1cdca3d 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -1192,6 +1192,8 @@
THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
#undef DECLARE_CONSTANT_OFFSET_GETTER
+ static word random_offset();
+
static word OffsetFromThread(const dart::Object& object);
static intptr_t OffsetFromThread(const dart::RuntimeEntry* runtime_entry);
};
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 2a33ea5..5c98bc9 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -286,7 +286,7 @@
Thread_call_to_runtime_entry_point_offset = 276;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 808;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 816;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 44;
static constexpr dart::compiler::target::word
@@ -332,7 +332,7 @@
static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
788;
static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 812;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 820;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
64;
static constexpr dart::compiler::target::word
@@ -417,9 +417,10 @@
static constexpr dart::compiler::target::word Thread_callback_code_offset = 780;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 784;
+static constexpr dart::compiler::target::word Thread_random_offset = 800;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 800;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 808;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -851,7 +852,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1616;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1624;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -898,7 +899,7 @@
1576;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -984,9 +985,10 @@
1560;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1600;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1608;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -1416,7 +1418,7 @@
Thread_call_to_runtime_entry_point_offset = 276;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 776;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 784;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 44;
static constexpr dart::compiler::target::word
@@ -1462,7 +1464,7 @@
static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
756;
static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 780;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 788;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
64;
static constexpr dart::compiler::target::word
@@ -1547,9 +1549,10 @@
static constexpr dart::compiler::target::word Thread_callback_code_offset = 748;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 752;
+static constexpr dart::compiler::target::word Thread_random_offset = 768;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 768;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 776;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -1978,7 +1981,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1688;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -2025,7 +2028,7 @@
1640;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -2111,9 +2114,10 @@
1624;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1672;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -2547,7 +2551,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1616;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1624;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -2594,7 +2598,7 @@
1576;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -2680,9 +2684,10 @@
1560;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1600;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1608;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -3115,7 +3120,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1688;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -3162,7 +3167,7 @@
1640;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -3248,9 +3253,10 @@
1624;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1672;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -3677,7 +3683,7 @@
Thread_call_to_runtime_entry_point_offset = 276;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 808;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 816;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 44;
static constexpr dart::compiler::target::word
@@ -3723,7 +3729,7 @@
static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
788;
static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 812;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 820;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
64;
static constexpr dart::compiler::target::word
@@ -3808,9 +3814,10 @@
static constexpr dart::compiler::target::word Thread_callback_code_offset = 780;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 784;
+static constexpr dart::compiler::target::word Thread_random_offset = 800;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 800;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 808;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -4236,7 +4243,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1616;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1624;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -4283,7 +4290,7 @@
1576;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -4369,9 +4376,10 @@
1560;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1600;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1608;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -4795,7 +4803,7 @@
Thread_call_to_runtime_entry_point_offset = 276;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 144;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 776;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 784;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 44;
static constexpr dart::compiler::target::word
@@ -4841,7 +4849,7 @@
static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
756;
static constexpr dart::compiler::target::word Thread_isolate_offset = 40;
-static constexpr dart::compiler::target::word Thread_isolate_group_offset = 780;
+static constexpr dart::compiler::target::word Thread_isolate_group_offset = 788;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
64;
static constexpr dart::compiler::target::word
@@ -4926,9 +4934,10 @@
static constexpr dart::compiler::target::word Thread_callback_code_offset = 748;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 752;
+static constexpr dart::compiler::target::word Thread_random_offset = 768;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 328;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 768;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 776;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -5351,7 +5360,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1688;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -5398,7 +5407,7 @@
1640;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -5484,9 +5493,10 @@
1624;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1672;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -5914,7 +5924,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1616;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1624;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -5961,7 +5971,7 @@
1576;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -6047,9 +6057,10 @@
1560;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1600;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1608;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -6476,7 +6487,7 @@
Thread_call_to_runtime_entry_point_offset = 528;
static constexpr dart::compiler::target::word
Thread_call_to_runtime_stub_offset = 264;
-static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1680;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1688;
static constexpr dart::compiler::target::word
Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -6523,7 +6534,7 @@
1640;
static constexpr dart::compiler::target::word Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word Thread_field_table_values_offset =
128;
static constexpr dart::compiler::target::word
@@ -6609,9 +6620,10 @@
1624;
static constexpr dart::compiler::target::word
Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
Thread_jump_to_frame_entry_point_offset = 632;
-static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1664;
+static constexpr dart::compiler::target::word Thread_tsan_utils_offset = 1672;
static constexpr dart::compiler::target::word TsanUtils_setjmp_function_offset =
0;
static constexpr dart::compiler::target::word TsanUtils_setjmp_buffer_offset =
@@ -7078,7 +7090,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 144;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 808;
+ 816;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 44;
static constexpr dart::compiler::target::word
@@ -7126,7 +7138,7 @@
AOT_Thread_exit_through_ffi_offset = 788;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 812;
+ 820;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 64;
static constexpr dart::compiler::target::word
@@ -7216,10 +7228,11 @@
780;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 784;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 800;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 328;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 800;
+ 808;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -7707,7 +7720,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1616;
+ 1624;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -7755,7 +7768,7 @@
AOT_Thread_exit_through_ffi_offset = 1576;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -7846,10 +7859,11 @@
1560;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1600;
+ 1608;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -8342,7 +8356,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1680;
+ 1688;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -8390,7 +8404,7 @@
AOT_Thread_exit_through_ffi_offset = 1640;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -8481,10 +8495,11 @@
1624;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1664;
+ 1672;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -8974,7 +8989,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1616;
+ 1624;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -9022,7 +9037,7 @@
AOT_Thread_exit_through_ffi_offset = 1576;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -9113,10 +9128,11 @@
1560;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1600;
+ 1608;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -9605,7 +9621,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1680;
+ 1688;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -9653,7 +9669,7 @@
AOT_Thread_exit_through_ffi_offset = 1640;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -9744,10 +9760,11 @@
1624;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1664;
+ 1672;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -10232,7 +10249,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 144;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 808;
+ 816;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 44;
static constexpr dart::compiler::target::word
@@ -10280,7 +10297,7 @@
AOT_Thread_exit_through_ffi_offset = 788;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 812;
+ 820;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 64;
static constexpr dart::compiler::target::word
@@ -10370,10 +10387,11 @@
780;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 784;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 800;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 328;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 800;
+ 808;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -10854,7 +10872,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1616;
+ 1624;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -10902,7 +10920,7 @@
AOT_Thread_exit_through_ffi_offset = 1576;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -10993,10 +11011,11 @@
1560;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1600;
+ 1608;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -11482,7 +11501,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1680;
+ 1688;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -11530,7 +11549,7 @@
AOT_Thread_exit_through_ffi_offset = 1640;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -11621,10 +11640,11 @@
1624;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1664;
+ 1672;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -12107,7 +12127,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1616;
+ 1624;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -12155,7 +12175,7 @@
AOT_Thread_exit_through_ffi_offset = 1576;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1624;
+ 1632;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -12246,10 +12266,11 @@
1560;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1568;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1600;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1600;
+ 1608;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
@@ -12731,7 +12752,7 @@
static constexpr dart::compiler::target::word
AOT_Thread_call_to_runtime_stub_offset = 264;
static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset =
- 1680;
+ 1688;
static constexpr dart::compiler::target::word
AOT_Thread_dispatch_table_array_offset = 88;
static constexpr dart::compiler::target::word
@@ -12779,7 +12800,7 @@
AOT_Thread_exit_through_ffi_offset = 1640;
static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80;
static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset =
- 1688;
+ 1696;
static constexpr dart::compiler::target::word
AOT_Thread_field_table_values_offset = 128;
static constexpr dart::compiler::target::word
@@ -12870,10 +12891,11 @@
1624;
static constexpr dart::compiler::target::word
AOT_Thread_callback_stack_return_offset = 1632;
+static constexpr dart::compiler::target::word AOT_Thread_random_offset = 1664;
static constexpr dart::compiler::target::word
AOT_Thread_jump_to_frame_entry_point_offset = 632;
static constexpr dart::compiler::target::word AOT_Thread_tsan_utils_offset =
- 1664;
+ 1672;
static constexpr dart::compiler::target::word
AOT_TsanUtils_setjmp_function_offset = 0;
static constexpr dart::compiler::target::word
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index d0264eb..71cc428 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -286,6 +286,7 @@
FIELD(Thread, heap_base_offset) \
FIELD(Thread, callback_code_offset) \
FIELD(Thread, callback_stack_return_offset) \
+ FIELD(Thread, random_offset) \
FIELD(Thread, jump_to_frame_entry_point_offset) \
FIELD(Thread, tsan_utils_offset) \
FIELD(TsanUtils, setjmp_function_offset) \
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 5a9050a..426bb94 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -7854,7 +7854,8 @@
"'foo1:///.dart_tool");
}
-void NewNativePort_send123(Dart_Port dest_port_id, Dart_CObject* message) {
+static void NewNativePort_send123(Dart_Port dest_port_id,
+ Dart_CObject* message) {
// Gets a send port message.
EXPECT_NOTNULL(message);
EXPECT_EQ(Dart_CObject_kArray, message->type);
@@ -7869,7 +7870,8 @@
response);
}
-void NewNativePort_send321(Dart_Port dest_port_id, Dart_CObject* message) {
+static void NewNativePort_send321(Dart_Port dest_port_id,
+ Dart_CObject* message) {
// Gets a null message.
EXPECT_NOTNULL(message);
EXPECT_EQ(Dart_CObject_kArray, message->type);
@@ -7978,8 +7980,8 @@
EXPECT(Dart_CloseNativePort(port_id2));
}
-void NewNativePort_sendInteger123(Dart_Port dest_port_id,
- Dart_CObject* message) {
+static void NewNativePort_sendInteger123(Dart_Port dest_port_id,
+ Dart_CObject* message) {
// Gets a send port message.
EXPECT_NOTNULL(message);
EXPECT_EQ(Dart_CObject_kArray, message->type);
@@ -7990,8 +7992,8 @@
123);
}
-void NewNativePort_sendInteger321(Dart_Port dest_port_id,
- Dart_CObject* message) {
+static void NewNativePort_sendInteger321(Dart_Port dest_port_id,
+ Dart_CObject* message) {
// Gets a null message.
EXPECT_NOTNULL(message);
EXPECT_EQ(Dart_CObject_kArray, message->type);
@@ -8053,8 +8055,74 @@
EXPECT(Dart_CloseNativePort(port_id2));
}
-void NewNativePort_nativeReceiveNull(Dart_Port dest_port_id,
- Dart_CObject* message) {
+static void NewNativePort_Transferrable1(Dart_Port dest_port_id,
+ Dart_CObject* message) {
+ // Gets a send port message.
+ EXPECT_NOTNULL(message);
+ EXPECT_EQ(Dart_CObject_kTypedData, message->type);
+ EXPECT_EQ(Dart_TypedData_kUint8, message->value.as_typed_data.type);
+ EXPECT_EQ(10, message->value.as_typed_data.length);
+ EXPECT_EQ(42, message->value.as_typed_data.values[0]);
+ free(message->value.as_typed_data.values);
+}
+
+static void NewNativePort_Transferrable2(Dart_Port dest_port_id,
+ Dart_CObject* message) {
+ // Gets a send port message.
+ EXPECT_NOTNULL(message);
+ EXPECT_EQ(Dart_CObject_kArray, message->type);
+ EXPECT_EQ(1, message->value.as_array.length);
+ Dart_CObject* cobj = message->value.as_array.values[0];
+ EXPECT_EQ(Dart_CObject_kTypedData, cobj->type);
+ EXPECT_EQ(Dart_TypedData_kUint8, cobj->value.as_typed_data.type);
+ EXPECT_EQ(10, cobj->value.as_typed_data.length);
+ EXPECT_EQ(42, cobj->value.as_typed_data.values[0]);
+ free(cobj->value.as_typed_data.values);
+}
+
+TEST_CASE(DartAPI_NativePortPostTransferrableTypedData) {
+ const char* kScriptChars =
+ "import 'dart:typed_data';\n"
+ "import 'dart:isolate';\n"
+ "void callPort(SendPort port1, SendPort port2) {\n"
+ " final td1 ="
+ " TransferableTypedData.fromList([Uint8List(10)..[0] = 42]);\n"
+ " final td2 ="
+ " TransferableTypedData.fromList([Uint8List(10)..[0] = 42]);\n"
+ " port1.send(td1);\n"
+ " port2.send([td2]);\n"
+ "}\n";
+ Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+ Dart_EnterScope();
+
+ Dart_Port port_id1 =
+ Dart_NewNativePort("Port123", NewNativePort_Transferrable1, true);
+ Dart_Port port_id2 =
+ Dart_NewNativePort("Port321", NewNativePort_Transferrable2, true);
+
+ Dart_Handle send_port1 = Dart_NewSendPort(port_id1);
+ EXPECT_VALID(send_port1);
+ Dart_Handle send_port2 = Dart_NewSendPort(port_id2);
+ EXPECT_VALID(send_port2);
+
+ // Test first port.
+ Dart_Handle dart_args[2];
+ dart_args[0] = send_port1;
+ dart_args[1] = send_port2;
+ Dart_Handle result = Dart_Invoke(lib, NewString("callPort"), 2, dart_args);
+ EXPECT_VALID(result);
+ result = Dart_RunLoop();
+ EXPECT_VALID(result);
+
+ Dart_ExitScope();
+
+ // Delete the native ports.
+ EXPECT(Dart_CloseNativePort(port_id1));
+ EXPECT(Dart_CloseNativePort(port_id2));
+}
+
+static void NewNativePort_nativeReceiveNull(Dart_Port dest_port_id,
+ Dart_CObject* message) {
EXPECT_NOTNULL(message);
if ((message->type == Dart_CObject_kArray) &&
@@ -8104,8 +8172,8 @@
EXPECT(Dart_CloseNativePort(port_id1));
}
-void NewNativePort_nativeReceiveInteger(Dart_Port dest_port_id,
- Dart_CObject* message) {
+static void NewNativePort_nativeReceiveInteger(Dart_Port dest_port_id,
+ Dart_CObject* message) {
EXPECT_NOTNULL(message);
if ((message->type == Dart_CObject_kArray) &&
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 7041084..46df59f 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -676,24 +676,6 @@
return result.ptr();
}
-// On success, returns an InstancePtr. On failure, an ErrorPtr.
-ObjectPtr DartLibraryCalls::IdentityHashCode(const Instance& object) {
- const int kNumArguments = 1;
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- const Library& libcore = Library::Handle(zone, Library::CoreLibrary());
- ASSERT(!libcore.IsNull());
- const Function& function = Function::Handle(
- zone, libcore.LookupFunctionAllowPrivate(Symbols::identityHashCode()));
- ASSERT(!function.IsNull());
- const Array& args = Array::Handle(zone, Array::New(kNumArguments));
- args.SetAt(0, object);
- const Object& result =
- Object::Handle(zone, DartEntry::InvokeFunction(function, args));
- ASSERT(result.IsInstance() || result.IsError());
- return result.ptr();
-}
-
ObjectPtr DartLibraryCalls::LookupHandler(Dart_Port port_id) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 6ec9067..4f650a8 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -285,9 +285,6 @@
// On success, returns an InstancePtr. On failure, an ErrorPtr.
static ObjectPtr Equals(const Instance& left, const Instance& right);
- // On success, returns an InstancePtr. On failure, an ErrorPtr.
- static ObjectPtr IdentityHashCode(const Instance& object);
-
// Returns the handler if one has been registered for this port id.
static ObjectPtr LookupHandler(Dart_Port port_id);
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 6236cf3..30188c2 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1952,6 +1952,7 @@
}
function.set_kernel_offset(procedure_offset);
function.set_is_extension_member(is_extension_member);
+ function.set_is_redirecting_factory(procedure_helper.IsRedirectingFactory());
if ((library.is_dart_scheme() &&
H.IsPrivate(procedure_helper.canonical_name_)) ||
(function.is_static() && (library.ptr() == Library::InternalLibrary()))) {
diff --git a/runtime/vm/message_snapshot.cc b/runtime/vm/message_snapshot.cc
index 4733db0..afc2bc3 100644
--- a/runtime/vm/message_snapshot.cc
+++ b/runtime/vm/message_snapshot.cc
@@ -2133,6 +2133,19 @@
reinterpret_cast<uint8_t*>(finalizable_data.data), length));
}
}
+
+ void ReadNodesApi(ApiMessageDeserializer* d) {
+ intptr_t count = d->ReadUnsigned();
+ for (intptr_t i = 0; i < count; i++) {
+ Dart_CObject* data = d->Allocate(Dart_CObject_kTypedData);
+ data->value.as_typed_data.length = d->ReadUnsigned();
+ data->value.as_typed_data.type = Dart_TypedData_kUint8;
+ FinalizableData finalizable_data = d->finalizable_data()->Get();
+ data->value.as_typed_data.values =
+ reinterpret_cast<uint8_t*>(finalizable_data.data);
+ d->AssignRef(data);
+ }
+ }
};
class Simd128MessageSerializationCluster : public MessageSerializationCluster {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index df10c58..b37de90 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1344,8 +1344,13 @@
// Some classes have identity hash codes that depend on their contents,
// not per object.
ASSERT(!obj->IsStringInstance());
- if (!obj->IsMint() && !obj->IsDouble() && !obj->IsRawNull() &&
- !obj->IsBool()) {
+ if (obj == Object::null()) {
+ Object::SetCachedHashIfNotSet(obj, kNullIdentityHash);
+ } else if (obj == Object::bool_true().ptr()) {
+ Object::SetCachedHashIfNotSet(obj, kTrueIdentityHash);
+ } else if (obj == Object::bool_false().ptr()) {
+ Object::SetCachedHashIfNotSet(obj, kFalseIdentityHash);
+ } else if (!obj->IsMint() && !obj->IsDouble()) {
counter_ += 2011; // The year Dart was announced and a prime.
counter_ &= 0x3fffffff;
if (counter_ == 0) counter_++;
@@ -9522,15 +9527,6 @@
return target.ptr();
}
-intptr_t Function::ComputeClosureHash() const {
- ASSERT(IsClosureFunction());
- const Class& cls = Class::Handle(Owner());
- uintptr_t result = String::Handle(name()).Hash();
- result += String::Handle(InternalSignature()).Hash();
- result += String::Handle(cls.Name()).Hash();
- return result;
-}
-
void FunctionType::Print(NameVisibility name_visibility,
BaseTextBuffer* printer) const {
if (IsNull()) {
@@ -18995,8 +18991,45 @@
return DartLibraryCalls::HashCode(*this);
}
-ObjectPtr Instance::IdentityHashCode() const {
- return DartLibraryCalls::IdentityHashCode(*this);
+// Keep in sync with AsmIntrinsifier::Object_getHash.
+IntegerPtr Instance::IdentityHashCode(Thread* thread) const {
+ if (IsInteger()) return Integer::Cast(*this).ptr();
+
+#if defined(HASH_IN_OBJECT_HEADER)
+ intptr_t hash = Object::GetCachedHash(ptr());
+#else
+ intptr_t hash = thread->heap()->GetHash(ptr());
+#endif
+ if (hash == 0) {
+ if (IsNull()) {
+ hash = kNullIdentityHash;
+ } else if (IsBool()) {
+ hash = Bool::Cast(*this).value() ? kTrueIdentityHash : kFalseIdentityHash;
+ } else if (IsDouble()) {
+ double val = Double::Cast(*this).value();
+ if ((val >= kMinInt64RepresentableAsDouble) &&
+ (val <= kMaxInt64RepresentableAsDouble)) {
+ int64_t ival = static_cast<int64_t>(val);
+ if (static_cast<double>(ival) == val) {
+ return Integer::New(ival);
+ }
+ }
+
+ uint64_t uval = bit_cast<uint64_t>(val);
+ hash = ((uval >> 32) ^ (uval)) & kSmiMax;
+ } else {
+ do {
+ hash = thread->random()->NextUInt32() & 0x3FFFFFFF;
+ } while (hash == 0);
+ }
+
+#if defined(HASH_IN_OBJECT_HEADER)
+ hash = Object::SetCachedHashIfNotSet(ptr(), hash);
+#else
+ hash = thread->heap()->SetHashIfNotSet(ptr(), hash);
+#endif
+ }
+ return Smi::New(hash);
}
bool Instance::CanonicalizeEquals(const Instance& other) const {
@@ -19058,7 +19091,7 @@
uint32_t Instance::CanonicalizeHash() const {
if (GetClassId() == kNullCid) {
- return 2011; // Matches null_patch.dart.
+ return kNullIdentityHash;
}
Thread* thread = Thread::Current();
uint32_t hash = thread->heap()->GetCanonicalHash(ptr());
@@ -25457,7 +25490,7 @@
// Implicit instance closures are not unique, so combine function's hash
// code, delayed type arguments hash code (if generic), and identityHashCode
// of cached receiver.
- result = static_cast<uint32_t>(func.ComputeClosureHash());
+ result = static_cast<uint32_t>(func.Hash());
if (func.IsGeneric()) {
const TypeArguments& delayed_type_args =
TypeArguments::Handle(zone, delayed_type_arguments());
@@ -25466,23 +25499,15 @@
const Context& context = Context::Handle(zone, this->context());
const Instance& receiver =
Instance::Handle(zone, Instance::RawCast(context.At(0)));
- const Object& receiverHash =
- Object::Handle(zone, receiver.IdentityHashCode());
- if (receiverHash.IsError()) {
- Exceptions::PropagateError(Error::Cast(receiverHash));
- UNREACHABLE();
- }
- result = CombineHashes(
- result, Integer::Cast(receiverHash).AsTruncatedUint32Value());
+ const Integer& receiverHash =
+ Integer::Handle(zone, receiver.IdentityHashCode(thread));
+ result = CombineHashes(result, receiverHash.AsTruncatedUint32Value());
} else {
// Explicit closures and implicit static closures are unique,
// so identityHashCode of closure object is good enough.
- const Object& identityHash = Object::Handle(zone, this->IdentityHashCode());
- if (identityHash.IsError()) {
- Exceptions::PropagateError(Error::Cast(identityHash));
- UNREACHABLE();
- }
- result = Integer::Cast(identityHash).AsTruncatedUint32Value();
+ const Integer& identityHash =
+ Integer::Handle(zone, this->IdentityHashCode(thread));
+ result = identityHash.AsTruncatedUint32Value();
}
return FinalizeHash(result, String::kHashBits);
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index d1fe844..591c5a1 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2947,8 +2947,6 @@
// invalid (e.g., mismatched argument shapes after a reload).
FunctionPtr ImplicitClosureTarget(Zone* zone) const;
- intptr_t ComputeClosureHash() const;
-
FunctionPtr ForwardingTarget() const;
void SetForwardingTarget(const Function& target) const;
@@ -3800,7 +3798,8 @@
V(PolymorphicTarget, is_polymorphic_target) \
V(HasPragma, has_pragma) \
V(IsSynthetic, is_synthetic) \
- V(IsExtensionMember, is_extension_member)
+ V(IsExtensionMember, is_extension_member) \
+ V(IsRedirectingFactory, is_redirecting_factory)
// Bit that is updated after function is constructed, has to be updated in
// concurrent-safe manner.
#define FOR_EACH_FUNCTION_VOLATILE_KIND_BIT(V) V(Inlinable, is_inlinable)
@@ -7516,7 +7515,7 @@
virtual ObjectPtr HashCode() const;
// Equivalent to invoking identityHashCode with this instance.
- ObjectPtr IdentityHashCode() const;
+ IntegerPtr IdentityHashCode(Thread* thread) const;
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(UntaggedInstance));
@@ -10064,6 +10063,11 @@
friend class Symbols;
};
+// Matches null_patch.dart / bool_patch.dart.
+static constexpr intptr_t kNullIdentityHash = 2011;
+static constexpr intptr_t kTrueIdentityHash = 1231;
+static constexpr intptr_t kFalseIdentityHash = 1237;
+
// Class Bool implements Dart core class bool.
class Bool : public Instance {
public:
@@ -10082,7 +10086,7 @@
}
virtual uint32_t CanonicalizeHash() const {
- return ptr() == True().ptr() ? 1231 : 1237;
+ return ptr() == True().ptr() ? kTrueIdentityHash : kFalseIdentityHash;
}
private:
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index ebb4788..12f6096 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -105,7 +105,7 @@
return true;
}
if (func.is_abstract() || func.IsImplicitConstructor() ||
- func.is_synthetic()) {
+ func.is_synthetic() || func.is_redirecting_factory()) {
return true;
}
if (func.IsNonImplicitClosureFunction() &&
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index b21c588..2670ac66 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -1065,6 +1065,60 @@
buffer);
}
+ISOLATE_UNIT_TEST_CASE(SourceReport_Regress95008_RedirectingFactory) {
+ // WARNING: This MUST be big enough for the serialised JSON string.
+ const int kBufferSize = 1024;
+ char buffer[kBufferSize];
+ const char* kScript = R"(
+class A {
+ A();
+ factory A.foo(int i) = B; // LINE_A
+}
+
+class B extends A {
+ int i;
+ B(this.i); // LINE_B
+}
+
+main() {
+ A.foo(42);
+}
+)";
+
+ Library& lib = Library::Handle();
+ lib ^= ExecuteScript(kScript);
+ ASSERT(!lib.IsNull());
+ const Script& script =
+ Script::Handle(lib.LookupScript(String::Handle(String::New("test-lib"))));
+
+ SourceReport report(SourceReport::kCoverage);
+ JSONStream js;
+ report.PrintJSON(&js, script);
+ const char* json_str = js.ToCString();
+ ASSERT(strlen(json_str) < kBufferSize);
+ ElideJSONSubstring("classes", json_str, buffer);
+ ElideJSONSubstring("libraries", buffer, buffer);
+ EXPECT_STREQ(
+ "{\"type\":\"SourceReport\",\"ranges\":["
+
+ // A()
+ "{\"scriptIndex\":0,\"startPos\":13,\"endPos\":16,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[13],\"misses\":[]}},"
+
+ // B()
+ "{\"scriptIndex\":0,\"startPos\":90,\"endPos\":99,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[90],\"misses\":[]}},"
+
+ // main
+ "{\"scriptIndex\":0,\"startPos\":114,\"endPos\":136,\"compiled\":true,"
+ "\"coverage\":{\"hits\":[114,127],\"misses\":[]}}],"
+
+ // Only one script in the script table.
+ "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+ "\"uri\":\"file:\\/\\/\\/test-lib\",\"_kind\":\"kernel\"}]}",
+ buffer);
+}
+
#endif // !PRODUCT
} // namespace dart
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 50640ad..880bdde 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -441,7 +441,6 @@
V(current_position, ":current_position") \
V(dynamic_assert_assignable_stc_check, \
":dynamic_assert_assignable_stc_check") \
- V(identityHashCode, "identityHashCode") \
V(index_temp, ":index_temp") \
V(is_sync, ":is_sync") \
V(isPaused, "isPaused") \
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 66faed4..ed9e9b7 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -1030,6 +1030,7 @@
void InitVMConstants();
Random* random() { return &thread_random_; }
+ static intptr_t random_offset() { return OFFSET_OF(Thread, thread_random_); }
uint64_t* GetFfiMarshalledArguments(intptr_t size) {
if (ffi_marshalled_arguments_size_ < size) {
@@ -1138,6 +1139,7 @@
uword exit_through_ffi_ = 0;
ApiLocalScope* api_top_scope_;
uint8_t double_truncate_round_supported_;
+ ALIGN8 Random thread_random_;
TsanUtils* tsan_utils_ = nullptr;
@@ -1177,8 +1179,6 @@
ErrorPtr sticky_error_;
- Random thread_random_;
-
intptr_t ffi_marshalled_arguments_size_ = 0;
uint64_t* ffi_marshalled_arguments_;
diff --git a/sdk/lib/_internal/vm/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart
index 3118350..0d1d4a8 100644
--- a/sdk/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk/lib/_internal/vm/lib/core_patch.dart
@@ -53,8 +53,6 @@
import "dart:isolate" show Isolate;
-import "dart:math" show Random;
-
import "dart:typed_data"
show Endian, Uint8List, Int64List, Uint16List, Uint32List;
diff --git a/sdk/lib/_internal/vm/lib/object_patch.dart b/sdk/lib/_internal/vm/lib/object_patch.dart
index 3a7b6bb..d0398a2 100644
--- a/sdk/lib/_internal/vm/lib/object_patch.dart
+++ b/sdk/lib/_internal/vm/lib/object_patch.dart
@@ -9,14 +9,6 @@
@pragma("vm:external-name", "Object_getHash")
external int _getHash(obj);
-/// Set hash code associated with the object if it is not set yet
-/// and return the current hash code. See [Object._objectHashCode]
-/// for why this function needs to check for already set hash code.
-@pragma("vm:recognized", "asm-intrinsic")
-@pragma("vm:exact-result-type", "dart:core#_Smi")
-@pragma("vm:external-name", "Object_setHashIfNotSetYet")
-external int _setHashIfNotSetYet(obj, int hash);
-
@patch
@pragma("vm:entry-point")
class Object {
@@ -28,31 +20,9 @@
@pragma("vm:external-name", "Object_equals")
external bool operator ==(Object other);
- // Helpers used to implement hashCode. If a hashCode is used, we remember it
- // in a weak table in the VM (32 bit) or in the header of the object (64
- // bit). A new hashCode value is calculated using a random number generator.
- static final _hashCodeRnd = new Random();
-
- static int _objectHashCode(obj) {
- var result = _getHash(obj);
- if (result == 0) {
- // We want the hash to be a Smi value greater than 0.
- do {
- result = _hashCodeRnd.nextInt(0x40000000);
- } while (result == 0);
-
- // Caveat: we might be interrupted by vm-service which then
- // can initialize [this] object's hash code, that is why we need to
- // return the return value of [_setHashIfNotSetYet] rather than
- // returning [result] itself.
- return _setHashIfNotSetYet(obj, result);
- }
- return result;
- }
-
@patch
- int get hashCode => _objectHashCode(this);
- int get _identityHashCode => _objectHashCode(this);
+ int get hashCode => _getHash(this);
+ int get _identityHashCode => _getHash(this);
@patch
@pragma("vm:external-name", "Object_toString")
diff --git a/tools/VERSION b/tools/VERSION
index 51977ba..35dc237 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 105
+PRERELEASE 106
PRERELEASE_PATCH 0
\ No newline at end of file