Version 2.18.0-147.0.dev
Merge commit '1c27154f41827e1155d948c9dda67ecc39e79655' into 'dev'
diff --git a/pkg/analysis_server/lib/src/cider/rename.dart b/pkg/analysis_server/lib/src/cider/rename.dart
index a7ce3f3..02902f3 100644
--- a/pkg/analysis_server/lib/src/cider/rename.dart
+++ b/pkg/analysis_server/lib/src/cider/rename.dart
@@ -53,6 +53,8 @@
} else if (element is ConstructorElement) {
status = validateConstructorName(name);
_analyzePossibleConflicts(element, status, name);
+ } else if (element is ImportElement) {
+ status = validateImportPrefixName(name);
}
if (status == null) {
@@ -125,34 +127,9 @@
for (var element in elements) {
matches.addAll(await fileResolver.findReferences2(element));
}
-
FlutterWidgetRename? flutterRename;
- var flutterState = canRename._flutterWidgetState;
- if (flutterState != null) {
- var stateClass = flutterState.state;
- var stateName = flutterState.newName;
- var match = await fileResolver.findReferences2(stateClass);
- var sourcePath = stateClass.source.fullName;
- var location = stateClass.enclosingElement.lineInfo
- .getLocation(stateClass.nameOffset);
- CiderSearchMatch ciderMatch;
- var searchInfo = CiderSearchInfo(
- location, stateClass.nameLength, MatchKind.DECLARATION);
- try {
- ciderMatch = match.firstWhere((m) => m.path == sourcePath);
- ciderMatch.references.add(searchInfo);
- } catch (_) {
- match.add(CiderSearchMatch(sourcePath, [], [searchInfo]));
- }
- var replacements = match
- .map((m) => CiderReplaceMatch(
- m.path,
- m.references
- .map((p) => ReplaceInfo(
- stateName, p.startPosition, stateClass.nameLength))
- .toList()))
- .toList();
- flutterRename = FlutterWidgetRename(stateName, match, replacements);
+ if (canRename._flutterWidgetState != null) {
+ flutterRename = await _computeFlutterStateName();
}
var replaceMatches = <CiderReplaceMatch>[];
if (element is ConstructorElement) {
@@ -179,6 +156,30 @@
replaceMatches.addMatch(result.path, result.matches.toList());
}
}
+ } else if (element is ImportElement) {
+ var replaceInfo = <ReplaceInfo>[];
+ for (var match in matches) {
+ for (var ref in match.references) {
+ if (newName.isEmpty) {
+ replaceInfo.add(ReplaceInfo('', ref.startPosition, ref.length));
+ } else {
+ var identifier = await _getInterpolationIdentifier(
+ match.path, ref.startPosition);
+ if (identifier != null) {
+ var lineInfo = canRename.lineInfo;
+ replaceInfo.add(ReplaceInfo('{$newName.${identifier.name}}',
+ lineInfo.getLocation(identifier.offset), identifier.length));
+ } else {
+ replaceInfo
+ .add(ReplaceInfo('$newName.', ref.startPosition, ref.length));
+ }
+ }
+ }
+ replaceMatches.addMatch(match.path, replaceInfo);
+ var sourcePath = element.source.fullName;
+ var infos = await _addElementDeclaration(element, sourcePath);
+ replaceMatches.addMatch(sourcePath, infos);
+ }
} else {
for (var match in matches) {
replaceMatches.addMatch(
@@ -213,6 +214,32 @@
lineInfo.getLocation(element.setter!.nameOffset),
element.setter!.nameLength));
}
+ } else if (element is ImportElement) {
+ var prefix = element.prefix;
+ var unit =
+ (await canRename._fileResolver.resolve2(path: sourcePath)).unit;
+ var index = element.library.imports.indexOf(element);
+ var node = unit.directives.whereType<ImportDirective>().elementAt(index);
+ if (newName.isEmpty) {
+ // We should not get `prefix == null` because we check in
+ // `checkNewName` that the new name is different.
+ if (prefix == null) {
+ return infos;
+ }
+ var prefixEnd = prefix.nameOffset + prefix.nameLength;
+ infos.add(ReplaceInfo(newName, lineInfo.getLocation(node.uri.end),
+ prefixEnd - node.uri.end));
+ } else {
+ if (prefix == null) {
+ var uriEnd = node.uri.end;
+ infos.add(
+ ReplaceInfo(' as $newName', lineInfo.getLocation(uriEnd), 0));
+ } else {
+ var offset = prefix.nameOffset;
+ var length = prefix.nameLength;
+ infos.add(ReplaceInfo(newName, lineInfo.getLocation(offset), length));
+ }
+ }
} else {
var location = (await canRename._fileResolver.resolve2(path: sourcePath))
.lineInfo
@@ -222,6 +249,53 @@
return infos;
}
+ Future<FlutterWidgetRename?> _computeFlutterStateName() async {
+ var flutterState = canRename._flutterWidgetState;
+ var stateClass = flutterState!.state;
+ var stateName = flutterState.newName;
+ var match = await canRename._fileResolver.findReferences2(stateClass);
+ var sourcePath = stateClass.source.fullName;
+ var location =
+ stateClass.enclosingElement.lineInfo.getLocation(stateClass.nameOffset);
+ CiderSearchMatch ciderMatch;
+ var searchInfo =
+ CiderSearchInfo(location, stateClass.nameLength, MatchKind.DECLARATION);
+ try {
+ ciderMatch = match.firstWhere((m) => m.path == sourcePath);
+ ciderMatch.references.add(searchInfo);
+ } catch (_) {
+ match.add(CiderSearchMatch(sourcePath, [searchInfo]));
+ }
+ var replacements = match
+ .map((m) => CiderReplaceMatch(
+ m.path,
+ m.references
+ .map((p) => ReplaceInfo(
+ stateName, p.startPosition, stateClass.nameLength))
+ .toList()))
+ .toList();
+ return FlutterWidgetRename(stateName, match, replacements);
+ }
+
+ /// If the given [reference] is before an interpolated [SimpleIdentifier] in
+ /// an [InterpolationExpression] without surrounding curly brackets, return
+ /// it. Otherwise return `null`.
+ Future<SimpleIdentifier?> _getInterpolationIdentifier(
+ String path, CharacterLocation loc) async {
+ var resolvedUnit = await canRename._fileResolver.resolve2(path: path);
+ var lineInfo = resolvedUnit.lineInfo;
+ var node = NodeLocator(
+ lineInfo.getOffsetOfLine(loc.lineNumber - 1) + loc.columnNumber)
+ .searchWithin(resolvedUnit.unit);
+ if (node is SimpleIdentifier) {
+ var parent = node.parent;
+ if (parent is InterpolationExpression && parent.rightBracket == null) {
+ return node;
+ }
+ }
+ return null;
+ }
+
Future<CiderReplaceMatch?> _replaceSyntheticConstructor() async {
var element = canRename.refactoringElement.element;
var classElement = element.enclosingElement;
@@ -313,6 +387,9 @@
if (element is ConstructorElement) {
return true;
}
+ if (element is ImportElement) {
+ return true;
+ }
if (element is LabelElement || element is LocalElement) {
return true;
}
diff --git a/pkg/analysis_server/test/src/cider/rename_test.dart b/pkg/analysis_server/test/src/cider/rename_test.dart
index 86347e6..270b014 100644
--- a/pkg/analysis_server/test/src/cider/rename_test.dart
+++ b/pkg/analysis_server/test/src/cider/rename_test.dart
@@ -651,6 +651,131 @@
[ReplaceInfo('bar', CharacterLocation(1, 1), 3)]);
}
+ void test_rename_import() async {
+ var testCode = '''
+import 'dart:async';
+^import 'dart:math' show Random, min hide max;
+void f() {
+ Future f;
+ Random r;
+ min(1, 2);
+}
+''';
+
+ var result = await _rename(testCode, 'newName');
+ _assertTestChangeResult('''
+import 'dart:async';
+import 'dart:math' as newName show Random, min hide max;
+void f() {
+ Future f;
+ newName.Random r;
+ newName.min(1, 2);
+}
+''', result!.replaceMatches.first.matches);
+ }
+
+ void test_rename_import_hasCurlyBrackets() async {
+ var testCode = r'''
+// test
+^import 'dart:async';
+void f() {
+ Future f;
+ print('Future type: ${Future}');
+}
+''';
+
+ var result = await _rename(testCode, 'newName');
+ _assertTestChangeResult(r'''
+// test
+import 'dart:async' as newName;
+void f() {
+ newName.Future f;
+ print('Future type: ${newName.Future}');
+}
+''', result!.replaceMatches.first.matches);
+ }
+
+ void test_rename_import_noCurlyBrackets() async {
+ var testCode = r'''
+// test
+^import 'dart:async';
+void f() {
+ Future f;
+ print('Future type: $Future');
+}
+''';
+ var result = await _rename(testCode, 'newName');
+ _assertTestChangeResult(r'''
+// test
+import 'dart:async' as newName;
+void f() {
+ newName.Future f;
+ print('Future type: ${newName.Future}');
+}
+''', result!.replaceMatches.first.matches);
+ }
+
+ void test_rename_import_onPrefixElement() async {
+ var testCode = '''
+import 'dart:async' as test;
+import 'dart:math' as test;
+void f() {
+ test.Future f;
+ ^test.pi;
+ test.e;
+}
+''';
+ var result = await _rename(testCode, 'newName');
+ _assertTestChangeResult('''
+import 'dart:async' as test;
+import 'dart:math' as newName;
+void f() {
+ test.Future f;
+ newName.pi;
+ newName.e;
+}
+''', result!.replaceMatches.first.matches);
+ }
+
+ void test_rename_import_prefix() async {
+ var testCode = '''
+import 'dart:math' as test;
+^import 'dart:async' as test;
+void f() {
+ test.max(1, 2);
+ test.Future f;
+}
+''';
+ var result = await _rename(testCode, 'newName');
+ _assertTestChangeResult('''
+import 'dart:math' as test;
+import 'dart:async' as newName;
+void f() {
+ test.max(1, 2);
+ newName.Future f;
+}
+''', result!.replaceMatches.first.matches);
+ }
+
+ void test_rename_import_remove_prefix() async {
+ var testCode = '''
+import 'dart:math' as test;
+^import 'dart:async' as test;
+void f() {
+ test.Future f;
+}
+''';
+
+ var result = await _rename(testCode, '');
+ _assertTestChangeResult('''
+import 'dart:math' as test;
+import 'dart:async';
+void f() {
+ Future f;
+}
+''', result!.replaceMatches.first.matches);
+ }
+
void test_rename_local() async {
var testCode = '''
void foo() {
diff --git a/pkg/analysis_server/tool/code_completion/corpus.dart b/pkg/analysis_server/tool/code_completion/corpus.dart
index 26cae4f..db20d1b 100644
--- a/pkg/analysis_server/tool/code_completion/corpus.dart
+++ b/pkg/analysis_server/tool/code_completion/corpus.dart
@@ -6,8 +6,6 @@
import 'dart:io';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
-import 'package:html/parser.dart' show parse;
-import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
/// Generate or update corpus data.
@@ -63,7 +61,6 @@
final _appDir =
path.join(_homeDir, 'completion_metrics', 'third_party', 'apps');
-final _client = http.Client();
final _homeDir = Platform.isWindows
? Platform.environment['LOCALAPPDATA']!
@@ -90,12 +87,6 @@
return CloneResult(result.exitCode, cloneDir, msg: result.stderr as String);
}
-Future<String> _getBody(String url) async => (await _getResponse(url)).body;
-
-Future<http.Response> _getResponse(String url) async =>
- _client.get(Uri.parse(url),
- headers: const {'User-Agent': 'dart.pkg.completion_metrics'});
-
bool _hasPubspec(FileSystemEntity f) =>
f is Directory &&
File(path.join(f.path, file_paths.pubspecYaml)).existsSync();
@@ -130,38 +121,3 @@
final String msg;
CloneResult(this.exitCode, this.directory, {this.msg = ''});
}
-
-class RepoList {
- static const itsallwidgetsRssFeed = 'https://itsallwidgets.com/app/feed';
-
- // (Re) generate the list of github repos on itsallwidgets.com
- static Future<List<String>> fromItsAllWidgetsRssFeed() async {
- final repos = <String>{};
-
- final body = await _getBody(itsallwidgetsRssFeed);
- final doc = parse(body);
- final entries = doc.querySelectorAll('entry');
- for (var entry in entries) {
- final link = entry.querySelector('link');
- if (link == null) {
- continue;
- }
- final href = link.attributes['href'];
- if (href == null) {
- continue;
- }
- final body = await _getBody(href);
- final doc = parse(body);
- final links = doc.querySelectorAll('a');
- for (var link in links) {
- final href = link.attributes['href'];
- if (href != null && href.startsWith('https://github.com/')) {
- print(href);
- repos.add(href);
- continue;
- }
- }
- }
- return repos.toList();
- }
-}
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 044b599..c27bf2a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -126,6 +126,69 @@
VARIABLE
}
+/// Visitor that adds [SearchResult]s for references to the [importElement].
+class ImportElementReferencesVisitor extends RecursiveAstVisitor<void> {
+ final List<SearchResult> results = <SearchResult>[];
+
+ final ImportElement importElement;
+ final CompilationUnitElement enclosingUnitElement;
+
+ late final Set<Element> importedElements;
+
+ ImportElementReferencesVisitor(
+ ImportElement element, this.enclosingUnitElement)
+ : importElement = element {
+ importedElements = element.namespace.definedNames.values.toSet();
+ }
+
+ @override
+ void visitExportDirective(ExportDirective node) {}
+
+ @override
+ void visitImportDirective(ImportDirective node) {}
+
+ @override
+ void visitSimpleIdentifier(SimpleIdentifier node) {
+ if (node.inDeclarationContext()) {
+ return;
+ }
+ if (importElement.prefix != null) {
+ if (node.staticElement == importElement.prefix) {
+ var parent = node.parent;
+ if (parent is PrefixedIdentifier && parent.prefix == node) {
+ var element = parent.writeOrReadElement?.declaration;
+ if (importedElements.contains(element)) {
+ _addResultForPrefix(node, parent.identifier);
+ }
+ }
+ if (parent is MethodInvocation && parent.target == node) {
+ var element = parent.methodName.staticElement?.declaration;
+ if (importedElements.contains(element)) {
+ _addResultForPrefix(node, parent.methodName);
+ }
+ }
+ }
+ } else {
+ var element = node.writeOrReadElement?.declaration;
+ if (importedElements.contains(element)) {
+ _addResult(node.offset, 0);
+ }
+ }
+ }
+
+ void _addResult(int offset, int length) {
+ Element enclosingElement =
+ _getEnclosingElement(enclosingUnitElement, offset);
+ results.add(SearchResult._(enclosingElement, SearchResultKind.REFERENCE,
+ offset, length, true, false));
+ }
+
+ void _addResultForPrefix(SimpleIdentifier prefixNode, AstNode nextNode) {
+ int prefixOffset = prefixNode.offset;
+ _addResult(prefixOffset, nextNode.offset - prefixOffset);
+ }
+}
+
/// Search support for an [AnalysisDriver].
class Search {
final AnalysisDriver _driver;
@@ -503,7 +566,7 @@
String unitPath = unitElement.source.fullName;
var unitResult = await _driver.getResult(unitPath);
if (unitResult is ResolvedUnitResult) {
- var visitor = _ImportElementReferencesVisitor(element, unitElement);
+ var visitor = ImportElementReferencesVisitor(element, unitElement);
unitResult.unit.accept(visitor);
results.addAll(visitor.results);
}
@@ -966,69 +1029,6 @@
}
}
-/// Visitor that adds [SearchResult]s for references to the [importElement].
-class _ImportElementReferencesVisitor extends RecursiveAstVisitor<void> {
- final List<SearchResult> results = <SearchResult>[];
-
- final ImportElement importElement;
- final CompilationUnitElement enclosingUnitElement;
-
- late final Set<Element> importedElements;
-
- _ImportElementReferencesVisitor(
- ImportElement element, this.enclosingUnitElement)
- : importElement = element {
- importedElements = element.namespace.definedNames.values.toSet();
- }
-
- @override
- void visitExportDirective(ExportDirective node) {}
-
- @override
- void visitImportDirective(ImportDirective node) {}
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- if (node.inDeclarationContext()) {
- return;
- }
- if (importElement.prefix != null) {
- if (node.staticElement == importElement.prefix) {
- var parent = node.parent;
- if (parent is PrefixedIdentifier && parent.prefix == node) {
- var element = parent.writeOrReadElement?.declaration;
- if (importedElements.contains(element)) {
- _addResultForPrefix(node, parent.identifier);
- }
- }
- if (parent is MethodInvocation && parent.target == node) {
- var element = parent.methodName.staticElement?.declaration;
- if (importedElements.contains(element)) {
- _addResultForPrefix(node, parent.methodName);
- }
- }
- }
- } else {
- var element = node.writeOrReadElement?.declaration;
- if (importedElements.contains(element)) {
- _addResult(node.offset, 0);
- }
- }
- }
-
- void _addResult(int offset, int length) {
- Element enclosingElement =
- _getEnclosingElement(enclosingUnitElement, offset);
- results.add(SearchResult._(enclosingElement, SearchResultKind.REFERENCE,
- offset, length, true, false));
- }
-
- void _addResultForPrefix(SimpleIdentifier prefixNode, AstNode nextNode) {
- int prefixOffset = prefixNode.offset;
- _addResult(prefixOffset, nextNode.offset - prefixOffset);
- }
-}
-
class _IndexRequest {
final AnalysisDriverUnitIndex index;
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 592bb38..198bb5b 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -18,6 +18,7 @@
import 'package:analyzer/src/dart/analysis/feature_set_provider.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
+import 'package:analyzer/src/dart/analysis/search.dart';
import 'package:analyzer/src/dart/micro/analysis_context.dart';
import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
import 'package:analyzer/src/dart/micro/library_analyzer.dart';
@@ -61,26 +62,20 @@
class CiderSearchMatch {
final String path;
- @deprecated
- final List<CharacterLocation?> startPositions;
final List<CiderSearchInfo> references;
- CiderSearchMatch(this.path, this.startPositions, this.references);
+ CiderSearchMatch(this.path, this.references);
@override
bool operator ==(Object other) =>
other is CiderSearchMatch &&
path == other.path &&
- const ListEquality<CharacterLocation?>()
- // ignore: deprecated_member_use_from_same_package
- .equals(startPositions, other.startPositions) &&
const ListEquality<CiderSearchInfo>()
.equals(references, other.references);
@override
String toString() {
- // ignore: deprecated_member_use_from_same_package
- return '($path, $startPositions)';
+ return '($path, $references)';
}
}
@@ -218,9 +213,6 @@
references.add(CiderSearchMatch(
path,
matches
- .map((match) => lineInfo.getLocation(match.offset))
- .toList(),
- matches
.map((match) => CiderSearchInfo(
lineInfo.getLocation(match.offset),
match.length,
@@ -235,6 +227,8 @@
if (element is LocalVariableElement ||
(element is ParameterElement && !element.isNamed)) {
await collectReferences2(element.source!.fullName, performance!);
+ } else if (element is ImportElement) {
+ return await _searchReferences_Import(element);
} else {
var result = performance!.run('getFilesContaining', (performance) {
return fsState!.getFilesContaining(element.displayName);
@@ -769,6 +763,27 @@
}
}
+ Future<List<CiderSearchMatch>> _searchReferences_Import(
+ ImportElement element) async {
+ var results = <CiderSearchMatch>[];
+ LibraryElement libraryElement = element.library;
+ for (CompilationUnitElement unitElement in libraryElement.units) {
+ String unitPath = unitElement.source.fullName;
+ var unitResult = await resolve2(path: unitPath);
+ var visitor = ImportElementReferencesVisitor(element, unitElement);
+ unitResult.unit.accept(visitor);
+ var lineInfo = unitResult.lineInfo;
+ var infos = visitor.results
+ .map((searchResult) => CiderSearchInfo(
+ lineInfo.getLocation(searchResult.offset),
+ searchResult.length,
+ MatchKind.REFERENCE))
+ .toList();
+ results.add(CiderSearchMatch(unitPath, infos));
+ }
+ return results;
+ }
+
void _throwIfNotAbsoluteNormalizedPath(String path) {
var pathContext = resourceProvider.pathContext;
if (pathContext.normalize(path) != path) {
diff --git a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
index 934b7bd..ffc3b74 100644
--- a/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
+++ b/pkg/analyzer/test/src/dart/micro/simple_file_resolver_test.dart
@@ -396,7 +396,7 @@
var element = await _findElement(6, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(bPath, [CharacterLocation(4, 11)],
+ CiderSearchMatch(bPath,
[CiderSearchInfo(CharacterLocation(4, 11), 1, MatchKind.REFERENCE)])
];
expect(result, unorderedEquals(expected));
@@ -418,8 +418,8 @@
var element = await _findElement(16, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(aPath, [CharacterLocation(5, 5)],
- [CiderSearchInfo(CharacterLocation(5, 5), 3, MatchKind.WRITE)])
+ CiderSearchMatch(
+ aPath, [CiderSearchInfo(CharacterLocation(5, 5), 3, MatchKind.WRITE)])
];
expect(result, expected);
}
@@ -438,7 +438,7 @@
var element = await _findElement(11, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(aPath, [CharacterLocation(2, 3)],
+ CiderSearchMatch(aPath,
[CiderSearchInfo(CharacterLocation(2, 3), 3, MatchKind.REFERENCE)])
];
expect(result, unorderedEquals(expected));
@@ -465,7 +465,7 @@
var element = await _findElement(20, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(bPath, [CharacterLocation(5, 15)],
+ CiderSearchMatch(bPath,
[CiderSearchInfo(CharacterLocation(5, 15), 3, MatchKind.REFERENCE)])
];
expect(result, unorderedEquals(expected));
@@ -485,7 +485,7 @@
var element = await _findElement(39, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(aPath, [CharacterLocation(4, 11)],
+ CiderSearchMatch(aPath,
[CiderSearchInfo(CharacterLocation(4, 11), 3, MatchKind.REFERENCE)])
];
expect(result, unorderedEquals(expected));
@@ -519,9 +519,9 @@
var element = await _findElement(17, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(bPath, [CharacterLocation(5, 5)],
+ CiderSearchMatch(bPath,
[CiderSearchInfo(CharacterLocation(5, 5), 4, MatchKind.REFERENCE)]),
- CiderSearchMatch(aPath, [CharacterLocation(7, 4)],
+ CiderSearchMatch(aPath,
[CiderSearchInfo(CharacterLocation(7, 4), 4, MatchKind.REFERENCE)])
];
expect(result, unorderedEquals(expected));
@@ -548,8 +548,8 @@
var element = await _findElement(21, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(bPath, [CharacterLocation(5, 5)],
- [CiderSearchInfo(CharacterLocation(5, 5), 5, MatchKind.WRITE)])
+ CiderSearchMatch(
+ bPath, [CiderSearchInfo(CharacterLocation(5, 5), 5, MatchKind.WRITE)])
];
expect(result, unorderedEquals(expected));
}
@@ -576,7 +576,7 @@
var element = await _findElement(19, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(bPath, [CharacterLocation(4, 13)],
+ CiderSearchMatch(bPath,
[CiderSearchInfo(CharacterLocation(4, 13), 3, MatchKind.REFERENCE)])
];
expect(result, unorderedEquals(expected));
@@ -604,7 +604,7 @@
var element = await _findElement(20, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(bPath, [CharacterLocation(4, 3)],
+ CiderSearchMatch(bPath,
[CiderSearchInfo(CharacterLocation(4, 3), 3, MatchKind.WRITE)]),
];
expect(result, unorderedEquals(expected));
@@ -625,8 +625,8 @@
var element = await _findElement(10, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(aPath, [CharacterLocation(4, 11)],
- [CiderSearchInfo(CharacterLocation(4, 11), 1, MatchKind.READ)])
+ CiderSearchMatch(
+ aPath, [CiderSearchInfo(CharacterLocation(4, 11), 1, MatchKind.READ)])
];
expect(result, unorderedEquals(expected));
}
@@ -645,21 +645,11 @@
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
CiderSearchMatch(aPath, [
- CharacterLocation(2, 8),
- CharacterLocation(4, 12)
- ], [
- CiderSearchInfo(CharacterLocation(2, 8), 5, MatchKind.WRITE),
- CiderSearchInfo(CharacterLocation(4, 12), 5, MatchKind.WRITE)
+ CiderSearchInfo(CharacterLocation(2, 8), 1, MatchKind.REFERENCE),
+ CiderSearchInfo(CharacterLocation(4, 12), 1, MatchKind.REFERENCE)
])
];
- expect(result.map((e) => e.path),
- unorderedEquals(expected.map((e) => e.path)));
- // ignore: deprecated_member_use_from_same_package
- expect(
- // ignore: deprecated_member_use_from_same_package
- result.map((e) => e.startPositions),
- // ignore: deprecated_member_use_from_same_package
- unorderedEquals(expected.map((e) => e.startPositions)));
+ expect(result, expected);
}
test_findReferences_typedef() async {
@@ -679,7 +669,7 @@
var element = await _findElement(8, aPath);
var result = await fileResolver.findReferences2(element);
var expected = <CiderSearchMatch>[
- CiderSearchMatch(bPath, [CharacterLocation(3, 8)],
+ CiderSearchMatch(bPath,
[CiderSearchInfo(CharacterLocation(3, 8), 4, MatchKind.REFERENCE)])
];
expect(result, unorderedEquals(expected));
diff --git a/pkg/compiler/lib/src/common/elements.dart b/pkg/compiler/lib/src/common/elements.dart
index a66fe73..47d4930 100644
--- a/pkg/compiler/lib/src/common/elements.dart
+++ b/pkg/compiler/lib/src/common/elements.dart
@@ -915,7 +915,7 @@
// From dart:_js_embedded_names
late final ClassEntity jsGetNameEnum = _findClass(
- _env.lookupLibrary(Uris.dart__js_embedded_names, required: true),
+ _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true),
'JsGetName')!;
/// Returns `true` if [member] is a "foreign helper", that is, a member whose
@@ -1185,7 +1185,7 @@
'NativeTypedArrayOfDouble')!;
late final ClassEntity jsBuiltinEnum = _findClass(
- _env.lookupLibrary(Uris.dart__js_embedded_names, required: true),
+ _env.lookupLibrary(Uris.dart__js_shared_embedded_names, required: true),
'JsBuiltin')!;
bool isForeign(MemberEntity element) => element.library == foreignLibrary;
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 024be8a..3058b11 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -249,6 +249,10 @@
static final Uri dart__js_embedded_names =
Uri(scheme: 'dart', path: '_js_embedded_names');
+ /// The URI for 'dart:_js_shared_embedded_names'.
+ static final Uri dart__js_shared_embedded_names =
+ Uri(scheme: 'dart', path: '_js_shared_embedded_names');
+
/// The URI for 'dart:js'.
static final Uri dart_js = Uri(scheme: 'dart', path: 'js');
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index e84fc46..a1b132b 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -24,6 +24,7 @@
import 'deferred_load/output_unit.dart' show OutputUnit, deferredPartFileName;
import 'dump_info_javascript_monitor.dart';
import 'elements/entities.dart';
+import 'elements/entity_utils.dart' as entity_utils;
import 'inferrer/abstract_value_domain.dart';
import 'inferrer/types.dart'
show GlobalTypeInferenceMemberResult, GlobalTypeInferenceResults;
@@ -663,14 +664,16 @@
List<ClosureInfo> nestedClosures = <ClosureInfo>[];
localFunctionInfoCollector.localFunctions.forEach((key, value) {
FunctionEntity closureEntity;
+ int closureOrder = value.order;
environment.forEachNestedClosure(memberEntity, (closure) {
- if (closure.enclosingClass.name == value.name) {
+ if (closure.enclosingClass.name == value.name &&
+ (closureOrder-- == 0)) {
closureEntity = closure;
}
});
final closureClassEntity = closureEntity.enclosingClass;
- final closureInfo =
- ClosureInfo(name: value.name, outputUnit: null, size: null);
+ final closureInfo = ClosureInfo(
+ name: value.disambiguatedName, outputUnit: null, size: null);
state.entityToInfo[closureClassEntity] = closureInfo;
FunctionEntity callMethod = closedWorld.elementEnvironment
@@ -691,6 +694,32 @@
}
}
+/// Maps JWorld Entity objects to disambiguated names in order to map them
+/// to/from Kernel.
+///
+/// This is primarily used for naming closure objects, which rely on Entity
+/// object identity to determine uniqueness.
+///
+/// Note: this relies on the Kernel traversal order to determine order, which
+/// may change in the future.
+class EntityDisambiguator {
+ final nameFrequencies = <String, int>{};
+ final entityNames = <Entity, String>{};
+
+ String name(Entity entity) {
+ final disambiguatedName = entityNames[entity];
+ if (disambiguatedName != null) {
+ return disambiguatedName;
+ }
+ nameFrequencies[entity.name] = (nameFrequencies[entity.name] ?? -1) + 1;
+ final order = nameFrequencies[entity.name];
+ entityNames[entity] =
+ order == 0 ? entity.name : '${entity.name}%${order - 1}';
+
+ return entityNames[entity];
+ }
+}
+
/// Annotates [KernelInfoCollector] with info extracted from closed-world
/// analysis.
class DumpInfoAnnotator {
@@ -699,6 +728,7 @@
final JClosedWorld closedWorld;
final GlobalTypeInferenceResults _globalInferenceResults;
final DumpInfoTask dumpInfoTask;
+ final entityDisambiguator = EntityDisambiguator();
JElementEnvironment get environment => closedWorld.elementEnvironment;
@@ -901,8 +931,9 @@
}
ClosureInfo visitClosureClass(ClassEntity element) {
+ final disambiguatedElementName = entityDisambiguator.name(element);
final kClosureInfos = kernelInfo.state.info.closures
- .where((info) => info.name == element.name)
+ .where((info) => info.name == disambiguatedElementName)
.toList();
assert(
kClosureInfos.length == 1,
@@ -916,7 +947,8 @@
FunctionEntity callMethod = closedWorld.elementEnvironment
.lookupClassMember(element, Identifiers.call);
- visitFunction(callMethod, element.name);
+ final functionInfo = visitFunction(callMethod, disambiguatedElementName);
+ if (functionInfo == null) return null;
kClosureInfo.treeShakenStatus = TreeShakenStatus.Live;
return kClosureInfo;
@@ -926,8 +958,8 @@
// not always be valid. Check and validate later.
FunctionInfo visitFunction(FunctionEntity function, String parentName) {
int size = dumpInfoTask.sizeOf(function);
- // TODO(sigmund): consider adding a small info to represent unreachable
- // code here.
+ if (size == 0 && !shouldKeep(function)) return null;
+
var compareName = function.name;
if (function.isConstructor) {
compareName = compareName == ""
@@ -1477,63 +1509,36 @@
class LocalFunctionInfo {
final ir.LocalFunction localFunction;
- final List<ir.TreeNode> hierarchy;
final String name;
+ final int order;
bool isInvoked = false;
- LocalFunctionInfo._(this.localFunction, this.hierarchy, this.name);
+ LocalFunctionInfo(this.localFunction, this.name, this.order);
- factory LocalFunctionInfo(ir.LocalFunction localFunction) {
- String name = '';
- ir.TreeNode node = localFunction;
- final hierarchy = <ir.TreeNode>[];
- bool inClosure = false;
- while (node != null) {
- // Only consider nodes used for resolving a closure's full name.
- if (node is ir.FunctionDeclaration) {
- hierarchy.add(node);
- name = '_${node.variable.name}' + name;
- inClosure = false;
- } else if (node is ir.FunctionExpression) {
- hierarchy.add(node);
- name = (inClosure ? '_' : '_closure') + name;
- inClosure = true;
- } else if (node is ir.Member) {
- hierarchy.add(node);
- var cleanName = node.toStringInternal();
- if (cleanName.endsWith('.'))
- cleanName = cleanName.substring(0, cleanName.length - 1);
- final isFactory = node is ir.Procedure && node.isFactory;
- if (isFactory) {
- cleanName = cleanName.replaceAll('.', '\$');
- cleanName = '${node.enclosingClass.toStringInternal()}_' + cleanName;
- } else {
- cleanName = cleanName.replaceAll('.', '_');
- }
- name = cleanName + name;
- inClosure = false;
- }
- node = node.parent;
- }
-
- return LocalFunctionInfo._(localFunction, hierarchy, name);
- }
+ get disambiguatedName => order == 0 ? name : '$name%${order - 1}';
}
class LocalFunctionInfoCollector extends ir.RecursiveVisitor<void> {
final localFunctions = <ir.LocalFunction, LocalFunctionInfo>{};
+ final localFunctionNames = <String, int>{};
+
+ LocalFunctionInfo generateLocalFunctionInfo(ir.LocalFunction localFunction) {
+ final name = _computeClosureName(localFunction);
+ localFunctionNames[name] = (localFunctionNames[name] ?? -1) + 1;
+ return LocalFunctionInfo(localFunction, name, localFunctionNames[name]);
+ }
@override
void visitFunctionExpression(ir.FunctionExpression node) {
assert(localFunctions[node] == null);
- localFunctions[node] = LocalFunctionInfo(node);
+ localFunctions[node] = generateLocalFunctionInfo(node);
defaultExpression(node);
}
@override
void visitFunctionDeclaration(ir.FunctionDeclaration node) {
assert(localFunctions[node] == null);
- localFunctions[node] = LocalFunctionInfo(node);
+ localFunctions[node] = generateLocalFunctionInfo(node);
defaultStatement(node);
}
@@ -1544,3 +1549,57 @@
localFunctions[node.localFunction].isInvoked = true;
}
}
+
+// Returns a non-unique name for the given closure element.
+//
+// Must be kept logically identical to js_model/element_map_impl.dart.
+String _computeClosureName(ir.TreeNode treeNode) {
+ String reconstructConstructorName(ir.Member node) {
+ String className = node.enclosingClass.name;
+ if (node.name.text == '') {
+ return className;
+ } else {
+ return '$className\$${node.name}';
+ }
+ }
+
+ var parts = <String>[];
+ // First anonymous is called 'closure', outer ones called '' to give a
+ // compound name where increasing nesting level corresponds to extra
+ // underscores.
+ var anonymous = 'closure';
+ ir.TreeNode current = treeNode;
+ while (current != null) {
+ var node = current;
+ if (node is ir.FunctionExpression) {
+ parts.add(anonymous);
+ anonymous = '';
+ } else if (node is ir.FunctionDeclaration) {
+ String name = node.variable.name;
+ if (name != null && name != "") {
+ parts.add(entity_utils.operatorNameToIdentifier(name));
+ } else {
+ parts.add(anonymous);
+ anonymous = '';
+ }
+ } else if (node is ir.Class) {
+ parts.add(node.name);
+ break;
+ } else if (node is ir.Procedure) {
+ if (node.kind == ir.ProcedureKind.Factory) {
+ parts.add(reconstructConstructorName(node));
+ } else {
+ parts.add(entity_utils.operatorNameToIdentifier(node.name.text));
+ }
+ } else if (node is ir.Constructor) {
+ parts.add(reconstructConstructorName(node));
+ break;
+ } else if (node is ir.Field) {
+ // Add the field name for closures in field initializers.
+ String name = node.name?.text;
+ if (name != null) parts.add(name);
+ }
+ current = current.parent;
+ }
+ return parts.reversed.join('_');
+}
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 392e4e5..dc91161 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -9,7 +9,7 @@
import 'package:front_end/src/api_unstable/dart2js.dart'
show $0, $9, $A, $Z, $_, $a, $g, $s, $z;
-import 'package:js_runtime/synced/embedded_names.dart' show JsGetName;
+import 'package:js_shared/synced/embedded_names.dart' show JsGetName;
import '../closure.dart';
import '../common.dart';
diff --git a/pkg/compiler/lib/src/js_backend/string_reference.dart b/pkg/compiler/lib/src/js_backend/string_reference.dart
index 966223b..a07a756 100644
--- a/pkg/compiler/lib/src/js_backend/string_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/string_reference.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.10
-
/// StringReferences are 'holes' in the generated JavaScript that are filled in
/// by the emitter with code to access a large string.
///
@@ -64,7 +62,7 @@
import '../constants/values.dart' show StringConstantValue;
import '../js/js.dart' as js;
-import '../serialization/serialization.dart';
+import '../serialization/serialization_interfaces.dart';
import '../util/util.dart' show Hashing;
import 'frequency_assignment.dart';
import 'name_sequence.dart';
@@ -95,10 +93,10 @@
final StringConstantValue constant;
- js.Expression _value;
+ js.Expression? _value;
@override
- final js.JavaScriptNodeSourceInformation sourceInformation;
+ final js.JavaScriptNodeSourceInformation? sourceInformation;
StringReference(this.constant) : sourceInformation = null;
StringReference._(this.constant, this._value, this.sourceInformation);
@@ -117,14 +115,15 @@
}
set value(js.Expression value) {
- assert(!isFinalized && value != null);
+ assert(!isFinalized);
+ assert((value as dynamic) != null); // TODO(48820): Remove when sound.
_value = value;
}
@override
js.Expression get value {
assert(isFinalized, 'StringReference is unassigned');
- return _value;
+ return _value!;
}
@override
@@ -137,14 +136,14 @@
@override
StringReference withSourceInformation(
- js.JavaScriptNodeSourceInformation newSourceInformation) {
+ js.JavaScriptNodeSourceInformation? newSourceInformation) {
if (newSourceInformation == sourceInformation) return this;
if (newSourceInformation == null) return this;
return StringReference._(constant, _value, newSourceInformation);
}
@override
- Iterable<js.Node> get containedNodes => isFinalized ? [_value] : const [];
+ Iterable<js.Node> get containedNodes => isFinalized ? [_value!] : const [];
@override
String nonfinalizedDebugText() {
@@ -175,23 +174,24 @@
/// and initializes the variable.
class StringReferenceResource extends js.DeferredStatement
implements js.AstContainer {
- js.Statement _statement;
+ js.Statement? _statement;
@override
- final js.JavaScriptNodeSourceInformation sourceInformation;
+ final js.JavaScriptNodeSourceInformation? sourceInformation;
StringReferenceResource() : sourceInformation = null;
StringReferenceResource._(this._statement, this.sourceInformation);
set statement(js.Statement statement) {
- assert(!isFinalized && statement != null);
+ assert(!isFinalized);
+ assert((statement as dynamic) != null); // TODO(48820): Remove when sound.
_statement = statement;
}
@override
js.Statement get statement {
assert(isFinalized, 'StringReferenceResource is unassigned');
- return _statement;
+ return _statement!;
}
@override
@@ -199,14 +199,15 @@
@override
StringReferenceResource withSourceInformation(
- js.JavaScriptNodeSourceInformation newSourceInformation) {
+ js.JavaScriptNodeSourceInformation? newSourceInformation) {
if (newSourceInformation == sourceInformation) return this;
if (newSourceInformation == null) return this;
return StringReferenceResource._(_statement, newSourceInformation);
}
@override
- Iterable<js.Node> get containedNodes => isFinalized ? [_statement] : const [];
+ Iterable<js.Node> get containedNodes =>
+ isFinalized ? [_statement!] : const [];
@override
void visitChildren<T>(js.NodeVisitor<T> visitor) {
@@ -233,8 +234,8 @@
final bool _minify;
final int shortestSharedLength; // Configurable for testing.
- /*late final*/ _StringReferenceCollectorVisitor _visitor;
- StringReferenceResource _resource;
+ late final _StringReferenceCollectorVisitor _visitor;
+ StringReferenceResource? _resource;
/// Maps the recipe (type expression) to the references with the same recipe.
/// Much of the algorithm's state is stored in the _ReferenceSet objects.
@@ -295,20 +296,20 @@
List<js.Property> properties = [];
for (_ReferenceSet referenceSet in referenceSetsUsingProperties) {
String string = referenceSet.constant.stringValue;
- var propertyName = js.string(referenceSet.propertyName);
+ var propertyName = js.string(referenceSet.propertyName!);
properties.add(js.Property(propertyName, js.string(string)));
- var access = js.js('#.#', [holderLocalName, propertyName]);
+ js.Expression access = js.js('#.#', [holderLocalName, propertyName]);
for (StringReference ref in referenceSet._references) {
ref.value = access;
}
}
if (properties.isEmpty) {
- _resource.statement = js.Block.empty();
+ _resource!.statement = js.Block.empty();
} else {
js.Expression initializer =
js.ObjectInitializer(properties, isOneLiner: false);
- _resource.statement = js.js.statement(
+ _resource!.statement = js.js.statement(
r'var # = #', [js.VariableDeclaration(holderLocalName), initializer]);
}
}
@@ -377,7 +378,7 @@
referencesByFrequency[index].propertyName = name;
} else {
var refSet = referencesByFrequency[index];
- refSet.propertyName = name + '_' + refSet.name;
+ refSet.propertyName = name + '_' + refSet.name!;
}
}
@@ -401,10 +402,10 @@
/// Characteristic name of the recipe - this can be used as a property name
/// for emitting unminified code, and as a stable hash source for minified
/// names. [name] is `null` if [recipe] should always be generated at use.
- String name;
+ String? name;
/// Property name for 'indexing' into the precomputed types.
- String propertyName;
+ String? propertyName;
/// A stable hash code that can be used for picking stable minified names.
int hash = 0;
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 8f32690..5da86d0 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -807,7 +807,7 @@
resourceName,
fragment.fragments,
holderCode);
- js.Expression code = js.js(_deferredBoilerplate, {
+ js.Expression /*!*/ code = js.js(_deferredBoilerplate, {
// TODO(floitsch): don't just reference 'init'.
'embeddedGlobalsObject': js.Parameter('init'),
'isCollectingRuntimeMetrics': _options.experimentalTrackAllocations,
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 9ff95c5..254b4c7 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -10,7 +10,6 @@
import 'package:js_runtime/synced/embedded_names.dart'
show
- ARRAY_RTI_PROPERTY,
DEFERRED_INITIALIZED,
DEFERRED_LIBRARY_PARTS,
DEFERRED_PART_URIS,
@@ -19,18 +18,22 @@
INTERCEPTORS_BY_TAG,
IS_HUNK_INITIALIZED,
IS_HUNK_LOADED,
- JsGetName,
LEAF_TAGS,
MANGLED_GLOBAL_NAMES,
MANGLED_NAMES,
METADATA,
NATIVE_SUPERCLASS_TAG_NAME,
- RTI_UNIVERSE,
- RtiUniverseFieldNames,
RUNTIME_METRICS,
STARTUP_METRICS,
TearOffParametersPropertyNames,
- TYPE_TO_INTERCEPTOR_MAP,
+ TYPE_TO_INTERCEPTOR_MAP;
+
+import 'package:js_shared/synced/embedded_names.dart'
+ show
+ ARRAY_RTI_PROPERTY,
+ JsGetName,
+ RTI_UNIVERSE,
+ RtiUniverseFieldNames,
TYPES;
import 'package:js_ast/src/precedence.dart' as js_precedence;
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index a5172df..5b51960 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -261,6 +261,7 @@
'dart:_js_helper',
'dart:_js_names',
'dart:_js_primitives',
+ 'dart:_js_shared_embedded_names',
'dart:_late_helper',
'dart:_metadata',
'dart:_native_typed_data',
@@ -296,6 +297,7 @@
'dart:_js_helper',
'dart:_js_names',
'dart:_js_primitives',
+ 'dart:_js_shared_embedded_names',
'dart:_late_helper',
'dart:_native_typed_data',
'dart:_recipe_syntax',
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index f28ab293..e2437be 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -6,7 +6,7 @@
import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
import 'package:front_end/src/api_unstable/dart2js.dart' as ir;
-import 'package:js_runtime/synced/embedded_names.dart';
+import 'package:js_shared/synced/embedded_names.dart' show JsGetName;
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/class_hierarchy.dart' as ir;
import 'package:kernel/core_types.dart' as ir;
diff --git a/pkg/compiler/lib/src/serialization/serialization_interfaces.dart b/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
index 5fac8e9..2285eab 100644
--- a/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
+++ b/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
@@ -4,6 +4,7 @@
import 'package:kernel/ast.dart' as ir show DartType, Member, TreeNode;
+import '../constants/values.dart' show ConstantValue;
import '../elements/entities.dart';
import '../elements/types.dart' show DartType;
@@ -84,6 +85,8 @@
void writeList<E extends Object>(Iterable<E>? values, void f(E value),
{bool allowNull = false});
+
+ void writeConstant(ConstantValue value);
}
/// Migrated interface for methods of DataSourceReader.
@@ -129,4 +132,6 @@
List<E> readList<E extends Object>(E f());
List<E>? readListOrNull<E extends Object>(E f());
+
+ ConstantValue readConstant();
}
diff --git a/pkg/compiler/lib/src/serialization/sink.dart b/pkg/compiler/lib/src/serialization/sink.dart
index cc836b4..077bfd8 100644
--- a/pkg/compiler/lib/src/serialization/sink.dart
+++ b/pkg/compiler/lib/src/serialization/sink.dart
@@ -925,6 +925,7 @@
}
/// Writes the constant [value] to this data sink.
+ @override
void writeConstant(ConstantValue value) {
_writeDataKind(DataKind.constant);
_writeConstant(value);
diff --git a/pkg/compiler/lib/src/serialization/source.dart b/pkg/compiler/lib/src/serialization/source.dart
index a0e4284..81e477b 100644
--- a/pkg/compiler/lib/src/serialization/source.dart
+++ b/pkg/compiler/lib/src/serialization/source.dart
@@ -1098,6 +1098,7 @@
}
/// Reads a constant value from this data source.
+ @override
ConstantValue readConstant() {
_checkDataKind(DataKind.constant);
return _readConstant();
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index cc26197..dda60e0 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -5,6 +5,8 @@
// @dart = 2.10
import 'package:js_runtime/synced/embedded_names.dart';
+import 'package:js_shared/synced/embedded_names.dart'
+ show JsBuiltin, JsGetName, TYPES;
import 'package:kernel/ast.dart' as ir;
import '../closure.dart';
diff --git a/pkg/compiler/test/dump_info/data/closures.dart b/pkg/compiler/test/dump_info/data/closures.dart
index e8b525a..997b340 100644
--- a/pkg/compiler/test/dump_info/data/closures.dart
+++ b/pkg/compiler/test/dump_info/data/closures.dart
@@ -46,10 +46,13 @@
"id": "library/memory:sdk/tests/web/native/main.dart::",
"kind": "library",
"name": "<unnamed>",
- "size": 10341,
+ "size": 12431,
"children": [
"class/memory:sdk/tests/web/native/main.dart::Class1",
"function/memory:sdk/tests/web/native/main.dart::main",
+ "function/memory:sdk/tests/web/native/main.dart::nested",
+ "function/memory:sdk/tests/web/native/main.dart::nested2",
+ "function/memory:sdk/tests/web/native/main.dart::siblings",
"function/memory:sdk/tests/web/native/main.dart::topLevelMethod1",
"function/memory:sdk/tests/web/native/main.dart::topLevelMethod2",
"function/memory:sdk/tests/web/native/main.dart::topLevelMethod3",
@@ -66,7 +69,6 @@
"imports": []
}]
*/
-
/*class: Class1:class=[{
"id": "class/memory:sdk/tests/web/native/main.dart::Class1",
"kind": "class",
@@ -1080,12 +1082,216 @@
return local2;
}
+/*member: nested:
+ closure=[
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::nested.nested_nested1",
+ "kind": "closure",
+ "name": "nested_nested1",
+ "size": 225,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::nested",
+ "function": "function/memory:sdk/tests/web/native/main.dart::nested.nested_nested1.call"
+},
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::nested.nested_nested1_nested2",
+ "kind": "closure",
+ "name": "nested_nested1_nested2",
+ "size": 227,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::nested",
+ "function": "function/memory:sdk/tests/web/native/main.dart::nested.nested_nested1_nested2.call"
+}],
+ function=[{
+ "id": "function/memory:sdk/tests/web/native/main.dart::nested",
+ "kind": "function",
+ "name": "nested",
+ "size": 568,
+ "outputUnit": "outputUnit/main",
+ "parent": "library/memory:sdk/tests/web/native/main.dart::",
+ "children": [
+ "closure/memory:sdk/tests/web/native/main.dart::nested.nested_nested1",
+ "closure/memory:sdk/tests/web/native/main.dart::nested.nested_nested1_nested2"
+ ],
+ "modifiers": {
+ "static": false,
+ "const": false,
+ "factory": false,
+ "external": false
+ },
+ "returnType": "dynamic",
+ "inferredReturnType": "[null]",
+ "parameters": [],
+ "sideEffects": "SideEffects(reads anything; writes anything)",
+ "inlinedCount": 0,
+ "code": "nested() {\n var t1 = {};\n t1.x = null;\n new A.nested_nested1(t1).call$0();\n t1.x.call$0();\n }",
+ "type": "dynamic Function()"
+}],
+ holding=[
+ {"id":"function/dart:_rti::_setArrayType","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::nested.nested_nested1.call","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::nested.nested_nested1.call","mask":null}]
+*/
+dynamic nested() {
+ dynamic x;
+ nested1() {
+ nested2() => nested1;
+ x = nested2;
+ }
+
+ nested1();
+ x();
+}
+
+/*member: nested2:
+ closure=[
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1",
+ "kind": "closure",
+ "name": "nested2_local1",
+ "size": 195,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::nested2",
+ "function": "function/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1.call"
+},
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1__closure",
+ "kind": "closure",
+ "name": "nested2_local1__closure",
+ "size": 193,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::nested2",
+ "function": "function/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1__closure.call"
+},
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1_closure",
+ "kind": "closure",
+ "name": "nested2_local1_closure",
+ "size": 311,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::nested2",
+ "function": "function/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1_closure.call"
+}],
+ function=[{
+ "id": "function/memory:sdk/tests/web/native/main.dart::nested2",
+ "kind": "function",
+ "name": "nested2",
+ "size": 764,
+ "outputUnit": "outputUnit/main",
+ "parent": "library/memory:sdk/tests/web/native/main.dart::",
+ "children": [
+ "closure/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1",
+ "closure/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1__closure",
+ "closure/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1_closure"
+ ],
+ "modifiers": {
+ "static": false,
+ "const": false,
+ "factory": false,
+ "external": false
+ },
+ "returnType": "dynamic",
+ "inferredReturnType": "[null]",
+ "parameters": [],
+ "sideEffects": "SideEffects(reads anything; writes anything)",
+ "inlinedCount": 0,
+ "code": "nested2() {\n A.print(new A.nested2_local1().call$0());\n }",
+ "type": "dynamic Function()"
+}],
+ holding=[
+ {"id":"function/dart:_rti::_setArrayType","mask":null},
+ {"id":"function/dart:core::print","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1.call","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::nested2.nested2_local1.call","mask":null}]
+*/
+dynamic nested2() {
+ dynamic y;
+ int local1() {
+ return (() => 1 + (() => 2)())();
+ }
+
+ y = local1();
+ print(y);
+}
+
+/*member: siblings:
+ closure=[
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1",
+ "kind": "closure",
+ "name": "siblings_local1",
+ "size": 244,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::siblings",
+ "function": "function/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1.call"
+},
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1_closure",
+ "kind": "closure",
+ "name": "siblings_local1_closure",
+ "size": 193,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::siblings",
+ "function": "function/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1_closure.call"
+},
+ {
+ "id": "closure/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1_closure%0",
+ "kind": "closure",
+ "name": "siblings_local1_closure",
+ "size": 197,
+ "outputUnit": "outputUnit/main",
+ "parent": "function/memory:sdk/tests/web/native/main.dart::siblings",
+ "function": "function/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1_closure.call%0"
+}],
+ function=[{
+ "id": "function/memory:sdk/tests/web/native/main.dart::siblings",
+ "kind": "function",
+ "name": "siblings",
+ "size": 701,
+ "outputUnit": "outputUnit/main",
+ "parent": "library/memory:sdk/tests/web/native/main.dart::",
+ "children": [
+ "closure/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1",
+ "closure/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1_closure",
+ "closure/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1_closure%0"
+ ],
+ "modifiers": {
+ "static": false,
+ "const": false,
+ "factory": false,
+ "external": false
+ },
+ "returnType": "dynamic",
+ "inferredReturnType": "[null]",
+ "parameters": [],
+ "sideEffects": "SideEffects(reads anything; writes anything)",
+ "inlinedCount": 0,
+ "code": "siblings() {\n A.print(new A.siblings_local1().call$0());\n }",
+ "type": "dynamic Function()"
+}],
+ holding=[
+ {"id":"function/dart:_rti::_setArrayType","mask":null},
+ {"id":"function/dart:core::print","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1.call","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::siblings.siblings_local1.call","mask":null}]
+*/
+dynamic siblings() {
+ int local1() {
+ int a = (() => 1)();
+ dynamic b = () => 2;
+ int c = (() => 3)();
+ return a + c;
+ }
+
+ print(local1());
+}
+
/*member: main:
function=[{
"id": "function/memory:sdk/tests/web/native/main.dart::main",
"kind": "function",
"name": "main",
- "size": 649,
+ "size": 706,
"outputUnit": "outputUnit/main",
"parent": "library/memory:sdk/tests/web/native/main.dart::",
"children": [],
@@ -1100,7 +1306,7 @@
"parameters": [],
"sideEffects": "SideEffects(reads anything; writes anything)",
"inlinedCount": 0,
- "code": "main() {\n var t2,\n t1 = type$.int;\n A.createRuntimeType(A.Class1$(t1).$ti._precomputed1);\n A.Class1$(t1).method2$0();\n A.Class1_Class1$fact2(t1).funcField.call$0();\n A.Class1$(t1);\n t2 = type$.double;\n A.createRuntimeType(t2);\n A.Class1$(t1).method4$1$0(t2);\n A.Class1$(t1).method5$0();\n A.Class1$(t1).method6$1$0(t2);\n A.createRuntimeType(t2);\n A.Class1_staticMethod2(t2);\n A.Class1_staticMethod3();\n A.Class1_staticMethod4(t2);\n A.createRuntimeType(t2);\n A.topLevelMethod2(t2);\n A.topLevelMethod3();\n A.topLevelMethod4(t2);\n A.twoLocals();\n }",
+ "code": "main() {\n var t2,\n t1 = type$.int;\n A.createRuntimeType(A.Class1$(t1).$ti._precomputed1);\n A.Class1$(t1).method2$0();\n A.Class1_Class1$fact2(t1).funcField.call$0();\n A.Class1$(t1);\n t2 = type$.double;\n A.createRuntimeType(t2);\n A.Class1$(t1).method4$1$0(t2);\n A.Class1$(t1).method5$0();\n A.Class1$(t1).method6$1$0(t2);\n A.createRuntimeType(t2);\n A.Class1_staticMethod2(t2);\n A.Class1_staticMethod3();\n A.Class1_staticMethod4(t2);\n A.createRuntimeType(t2);\n A.topLevelMethod2(t2);\n A.topLevelMethod3();\n A.topLevelMethod4(t2);\n A.twoLocals();\n A.nested();\n A.nested2();\n A.siblings();\n }",
"type": "dynamic Function()"
}],
holding=[
@@ -1125,6 +1331,9 @@
{"id":"function/memory:sdk/tests/web/native/main.dart::Class1.staticMethod2","mask":null},
{"id":"function/memory:sdk/tests/web/native/main.dart::Class1.staticMethod3","mask":null},
{"id":"function/memory:sdk/tests/web/native/main.dart::Class1.staticMethod4","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::nested","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::nested2","mask":null},
+ {"id":"function/memory:sdk/tests/web/native/main.dart::siblings","mask":null},
{"id":"function/memory:sdk/tests/web/native/main.dart::topLevelMethod1","mask":"inlined"},
{"id":"function/memory:sdk/tests/web/native/main.dart::topLevelMethod1","mask":null},
{"id":"function/memory:sdk/tests/web/native/main.dart::topLevelMethod2","mask":null},
@@ -1149,4 +1358,7 @@
topLevelMethod3();
topLevelMethod4<double>();
twoLocals();
+ nested();
+ nested2();
+ siblings();
}
diff --git a/pkg/js_runtime/lib/synced/embedded_names.dart b/pkg/js_runtime/lib/synced/embedded_names.dart
index 9d48e1a..0c99f47 100644
--- a/pkg/js_runtime/lib/synced/embedded_names.dart
+++ b/pkg/js_runtime/lib/synced/embedded_names.dart
@@ -26,22 +26,12 @@
/// the static function's unique (potentially minified) name.
const STATIC_FUNCTION_NAME_PROPERTY_NAME = r'$static_name';
-/// The name of a property on the constructor function of Dart Object
-/// and interceptor types, used for caching Rti types.
-const CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME = r'$ccache';
-
/// The name of the embedded global for metadata.
///
/// Use [JsBuiltin.getMetadata] instead of directly accessing this embedded
/// global.
const METADATA = 'metadata';
-/// A list of types used in the program e.g. for reflection or encoding of
-/// function types.
-///
-/// Use [JsBuiltin.getType] instead of directly accessing this embedded global.
-const TYPES = 'types';
-
/// A JS map from mangled global names to their unmangled names.
///
/// If the program does not use reflection, this embedded global may be empty
@@ -94,11 +84,6 @@
// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
const ISOLATE_TAG = 'isolateTag';
-/// An embedded global that contains the property used to store type information
-/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
-/// is a String).
-const ARRAY_RTI_PROPERTY = 'arrayRti';
-
/// This embedded global (a function) returns the isolate-specific dispatch-tag
/// that is used to accelerate interceptor calls.
const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
@@ -174,11 +159,6 @@
/// globals don't clash with it.
const DEFERRED_INITIALIZED = 'deferredInitialized';
-/// A 'Universe' object used by 'dart:_rti'.
-///
-/// This embedded global is used for --experiment-new-rti.
-const RTI_UNIVERSE = 'typeUniverse';
-
/// An embedded global used to collect and access runtime metrics.
const RUNTIME_METRICS = 'rm';
@@ -188,103 +168,6 @@
/// An embedded global used to collect and access startup metrics.
const STARTUP_METRICS = 'sm';
-/// Names that are supported by [JS_GET_NAME].
-// TODO(herhut): Make entries lower case (as in fields) and find a better name.
-enum JsGetName {
- GETTER_PREFIX,
- SETTER_PREFIX,
- CALL_PREFIX,
- CALL_PREFIX0,
- CALL_PREFIX1,
- CALL_PREFIX2,
- CALL_PREFIX3,
- CALL_PREFIX4,
- CALL_PREFIX5,
- CALL_CATCH_ALL,
- REQUIRED_PARAMETER_PROPERTY,
- DEFAULT_VALUES_PROPERTY,
- CALL_NAME_PROPERTY,
- DEFERRED_ACTION_PROPERTY,
-
- /// Prefix used for generated type test property on classes.
- OPERATOR_IS_PREFIX,
-
- /// Name used for generated function types on classes and methods.
- SIGNATURE_NAME,
-
- /// Name of JavaScript property used to store runtime-type information on
- /// instances of parameterized classes.
- RTI_NAME,
-
- /// String representation of the type of the Future class.
- FUTURE_CLASS_TYPE_NAME,
-
- /// Field name used for determining if an object or its interceptor has
- /// JavaScript indexing behavior.
- IS_INDEXABLE_FIELD_NAME,
-
- /// String representation of the type of the null class.
- NULL_CLASS_TYPE_NAME,
-
- /// String representation of the type of the object class.
- OBJECT_CLASS_TYPE_NAME,
-
- /// String representation of the type of the List class.
- LIST_CLASS_TYPE_NAME,
-
- /// Property name for Rti._as field.
- RTI_FIELD_AS,
-
- /// Property name for Rti._is field.
- RTI_FIELD_IS,
-}
-
-enum JsBuiltin {
- /// Returns the JavaScript constructor function for Dart's Object class.
- /// This can be used for type tests, as in
- ///
- /// var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor);
- /// if (JS('bool', '# instanceof #', obj, constructor))
- /// ...
- dartObjectConstructor,
-
- /// Returns the JavaScript constructor function for the runtime's Closure
- /// class, the base class of all closure objects. This can be used for type
- /// tests, as in
- ///
- /// var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor);
- /// if (JS('bool', '# instanceof #', obj, constructor))
- /// ...
- dartClosureConstructor,
-
- /// Returns true if the given type is a type argument of a js-interop class
- /// or a supertype of a js-interop class.
- ///
- /// JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o)
- isJsInteropTypeArgument,
-
- /// Returns the metadata of the given [index].
- ///
- /// JS_BUILTIN('returns:var;effects:none;depends:none',
- /// JsBuiltin.getMetadata, index);
- getMetadata,
-
- /// Returns the type of the given [index].
- ///
- /// JS_BUILTIN('returns:var;effects:none;depends:none',
- /// JsBuiltin.getType, index);
- getType,
-}
-
-/// Names of fields of the Rti Universe object.
-class RtiUniverseFieldNames {
- static String evalCache = 'eC';
- static String typeRules = 'tR';
- static String erasedTypes = 'eT';
- static String typeParameterVariances = 'tPV';
- static String sharedEmptyArray = 'sEA';
-}
-
/// Names of fields of collected tear-off parameters object.
///
/// Tear-off getters are created before the Dart classes are initialized, so a
diff --git a/pkg/js_shared/lib/synced/embedded_names.dart b/pkg/js_shared/lib/synced/embedded_names.dart
new file mode 100644
index 0000000..c2f6307
--- /dev/null
+++ b/pkg/js_shared/lib/synced/embedded_names.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.12
+
+/// A 'Universe' object used by 'dart:_rti'.
+const RTI_UNIVERSE = 'typeUniverse';
+
+/// An embedded global that contains the property used to store type information
+/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
+/// is a String).
+const ARRAY_RTI_PROPERTY = 'arrayRti';
+
+/// A list of types used in the program e.g. for reflection or encoding of
+/// function types.
+///
+/// Use [JsBuiltin.getType] instead of directly accessing this embedded global.
+const TYPES = 'types';
+
+/// Names that are supported by [JS_GET_NAME].
+// TODO(herhut): Make entries lower case (as in fields) and find a better name.
+enum JsGetName {
+ GETTER_PREFIX,
+ SETTER_PREFIX,
+ CALL_PREFIX,
+ CALL_PREFIX0,
+ CALL_PREFIX1,
+ CALL_PREFIX2,
+ CALL_PREFIX3,
+ CALL_PREFIX4,
+ CALL_PREFIX5,
+ CALL_CATCH_ALL,
+ REQUIRED_PARAMETER_PROPERTY,
+ DEFAULT_VALUES_PROPERTY,
+ CALL_NAME_PROPERTY,
+ DEFERRED_ACTION_PROPERTY,
+
+ /// Prefix used for generated type test property on classes.
+ OPERATOR_IS_PREFIX,
+
+ /// Name used for generated function types on classes and methods.
+ SIGNATURE_NAME,
+
+ /// Name of JavaScript property used to store runtime-type information on
+ /// instances of parameterized classes.
+ RTI_NAME,
+
+ /// String representation of the type of the Future class.
+ FUTURE_CLASS_TYPE_NAME,
+
+ /// Field name used for determining if an object or its interceptor has
+ /// JavaScript indexing behavior.
+ IS_INDEXABLE_FIELD_NAME,
+
+ /// String representation of the type of the null class.
+ NULL_CLASS_TYPE_NAME,
+
+ /// String representation of the type of the object class.
+ OBJECT_CLASS_TYPE_NAME,
+
+ /// String representation of the type of the List class.
+ LIST_CLASS_TYPE_NAME,
+
+ /// Property name for Rti._as field.
+ RTI_FIELD_AS,
+
+ /// Property name for Rti._is field.
+ RTI_FIELD_IS,
+}
+
+enum JsBuiltin {
+ /// Returns the JavaScript constructor function for Dart's Object class.
+ /// This can be used for type tests, as in
+ ///
+ /// var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor);
+ /// if (JS('bool', '# instanceof #', obj, constructor))
+ /// ...
+ dartObjectConstructor,
+
+ /// Returns the JavaScript constructor function for the runtime's Closure
+ /// class, the base class of all closure objects. This can be used for type
+ /// tests, as in
+ ///
+ /// var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor);
+ /// if (JS('bool', '# instanceof #', obj, constructor))
+ /// ...
+ dartClosureConstructor,
+
+ /// Returns true if the given type is a type argument of a js-interop class
+ /// or a supertype of a js-interop class.
+ ///
+ /// JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o)
+ isJsInteropTypeArgument,
+
+ /// Returns the metadata of the given [index].
+ ///
+ /// JS_BUILTIN('returns:var;effects:none;depends:none',
+ /// JsBuiltin.getMetadata, index);
+ getMetadata,
+
+ /// Returns the type of the given [index].
+ ///
+ /// JS_BUILTIN('returns:var;effects:none;depends:none',
+ /// JsBuiltin.getType, index);
+ getType,
+}
+
+/// Names of fields of the Rti Universe object.
+class RtiUniverseFieldNames {
+ static String evalCache = 'eC';
+ static String typeRules = 'tR';
+ static String erasedTypes = 'eT';
+ static String typeParameterVariances = 'tPV';
+ static String sharedEmptyArray = 'sEA';
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
index 6e8cd72..66b06a7 100644
--- a/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
@@ -4,7 +4,7 @@
library _foreign_helper;
-import 'dart:_js_embedded_names' show JsGetName, JsBuiltin;
+import 'dart:_js_shared_embedded_names' show JsGetName, JsBuiltin;
import 'dart:_rti' show Rti;
/// Emits a JavaScript code fragment parametrized by arguments.
@@ -215,13 +215,14 @@
/// Reads an embedded global.
///
-/// The [name] should be a constant defined in the `_embedded_names` library.
+/// The [name] should be a constant defined in the `_embedded_names` or
+/// `_js_shared_embedded_names` library.
external JS_EMBEDDED_GLOBAL(String typeDescription, String name);
/// Instructs the compiler to execute the [builtinName] action at the call-site.
///
-/// The [builtin] should be a constant defined in the `_embedded_names`
-/// library.
+/// The [builtin] should be a constant defined in the
+/// `_js_shared_embedded_names` library.
// Add additional optional arguments if needed. The method is treated internally
// as a variable argument method.
external JS_BUILTIN(String typeDescription, JsBuiltin builtin,
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 50f9c4f..fd3ffd1 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -6,19 +6,15 @@
import 'dart:_js_embedded_names'
show
- ARRAY_RTI_PROPERTY,
CURRENT_SCRIPT,
DEFERRED_LIBRARY_PARTS,
DEFERRED_PART_URIS,
DEFERRED_PART_HASHES,
GET_ISOLATE_TAG,
INITIALIZE_LOADED_HUNK,
- INTERCEPTED_NAMES,
INTERCEPTORS_BY_TAG,
IS_HUNK_LOADED,
IS_HUNK_INITIALIZED,
- JsBuiltin,
- JsGetName,
LEAF_TAGS,
NATIVE_SUPERCLASS_TAG_NAME,
RUNTIME_METRICS,
@@ -26,6 +22,8 @@
STATIC_FUNCTION_NAME_PROPERTY_NAME,
TearOffParametersPropertyNames;
+import 'dart:_js_shared_embedded_names' show JsBuiltin, JsGetName;
+
import 'dart:collection';
import 'dart:async' show Completer, DeferredLoadException, Future, Zone;
diff --git a/sdk/lib/_internal/js_runtime/lib/synced/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/synced/embedded_names.dart
index 9d48e1a..0c99f47 100644
--- a/sdk/lib/_internal/js_runtime/lib/synced/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/synced/embedded_names.dart
@@ -26,22 +26,12 @@
/// the static function's unique (potentially minified) name.
const STATIC_FUNCTION_NAME_PROPERTY_NAME = r'$static_name';
-/// The name of a property on the constructor function of Dart Object
-/// and interceptor types, used for caching Rti types.
-const CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME = r'$ccache';
-
/// The name of the embedded global for metadata.
///
/// Use [JsBuiltin.getMetadata] instead of directly accessing this embedded
/// global.
const METADATA = 'metadata';
-/// A list of types used in the program e.g. for reflection or encoding of
-/// function types.
-///
-/// Use [JsBuiltin.getType] instead of directly accessing this embedded global.
-const TYPES = 'types';
-
/// A JS map from mangled global names to their unmangled names.
///
/// If the program does not use reflection, this embedded global may be empty
@@ -94,11 +84,6 @@
// [INTERCEPTORS_BY_TAG] and [LEAF_TAGS].
const ISOLATE_TAG = 'isolateTag';
-/// An embedded global that contains the property used to store type information
-/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
-/// is a String).
-const ARRAY_RTI_PROPERTY = 'arrayRti';
-
/// This embedded global (a function) returns the isolate-specific dispatch-tag
/// that is used to accelerate interceptor calls.
const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
@@ -174,11 +159,6 @@
/// globals don't clash with it.
const DEFERRED_INITIALIZED = 'deferredInitialized';
-/// A 'Universe' object used by 'dart:_rti'.
-///
-/// This embedded global is used for --experiment-new-rti.
-const RTI_UNIVERSE = 'typeUniverse';
-
/// An embedded global used to collect and access runtime metrics.
const RUNTIME_METRICS = 'rm';
@@ -188,103 +168,6 @@
/// An embedded global used to collect and access startup metrics.
const STARTUP_METRICS = 'sm';
-/// Names that are supported by [JS_GET_NAME].
-// TODO(herhut): Make entries lower case (as in fields) and find a better name.
-enum JsGetName {
- GETTER_PREFIX,
- SETTER_PREFIX,
- CALL_PREFIX,
- CALL_PREFIX0,
- CALL_PREFIX1,
- CALL_PREFIX2,
- CALL_PREFIX3,
- CALL_PREFIX4,
- CALL_PREFIX5,
- CALL_CATCH_ALL,
- REQUIRED_PARAMETER_PROPERTY,
- DEFAULT_VALUES_PROPERTY,
- CALL_NAME_PROPERTY,
- DEFERRED_ACTION_PROPERTY,
-
- /// Prefix used for generated type test property on classes.
- OPERATOR_IS_PREFIX,
-
- /// Name used for generated function types on classes and methods.
- SIGNATURE_NAME,
-
- /// Name of JavaScript property used to store runtime-type information on
- /// instances of parameterized classes.
- RTI_NAME,
-
- /// String representation of the type of the Future class.
- FUTURE_CLASS_TYPE_NAME,
-
- /// Field name used for determining if an object or its interceptor has
- /// JavaScript indexing behavior.
- IS_INDEXABLE_FIELD_NAME,
-
- /// String representation of the type of the null class.
- NULL_CLASS_TYPE_NAME,
-
- /// String representation of the type of the object class.
- OBJECT_CLASS_TYPE_NAME,
-
- /// String representation of the type of the List class.
- LIST_CLASS_TYPE_NAME,
-
- /// Property name for Rti._as field.
- RTI_FIELD_AS,
-
- /// Property name for Rti._is field.
- RTI_FIELD_IS,
-}
-
-enum JsBuiltin {
- /// Returns the JavaScript constructor function for Dart's Object class.
- /// This can be used for type tests, as in
- ///
- /// var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor);
- /// if (JS('bool', '# instanceof #', obj, constructor))
- /// ...
- dartObjectConstructor,
-
- /// Returns the JavaScript constructor function for the runtime's Closure
- /// class, the base class of all closure objects. This can be used for type
- /// tests, as in
- ///
- /// var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor);
- /// if (JS('bool', '# instanceof #', obj, constructor))
- /// ...
- dartClosureConstructor,
-
- /// Returns true if the given type is a type argument of a js-interop class
- /// or a supertype of a js-interop class.
- ///
- /// JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o)
- isJsInteropTypeArgument,
-
- /// Returns the metadata of the given [index].
- ///
- /// JS_BUILTIN('returns:var;effects:none;depends:none',
- /// JsBuiltin.getMetadata, index);
- getMetadata,
-
- /// Returns the type of the given [index].
- ///
- /// JS_BUILTIN('returns:var;effects:none;depends:none',
- /// JsBuiltin.getType, index);
- getType,
-}
-
-/// Names of fields of the Rti Universe object.
-class RtiUniverseFieldNames {
- static String evalCache = 'eC';
- static String typeRules = 'tR';
- static String erasedTypes = 'eT';
- static String typeParameterVariances = 'tPV';
- static String sharedEmptyArray = 'sEA';
-}
-
/// Names of fields of collected tear-off parameters object.
///
/// Tear-off getters are created before the Dart classes are initialized, so a
diff --git a/sdk/lib/_internal/js_shared/lib/rti.dart b/sdk/lib/_internal/js_shared/lib/rti.dart
index 356298b..b7c9881 100644
--- a/sdk/lib/_internal/js_shared/lib/rti.dart
+++ b/sdk/lib/_internal/js_shared/lib/rti.dart
@@ -18,24 +18,16 @@
RAW_DART_FUNCTION_REF,
TYPE_REF,
LEGACY_TYPE_REF;
-
import 'dart:_interceptors'
show JavaScriptFunction, JSArray, JSNull, JSUnmodifiableArray;
-
import 'dart:_js_names' show unmangleGlobalNameIfPreservedAnyways;
-
-import 'dart:_js_embedded_names'
- show
- JsBuiltin,
- JsGetName,
- RtiUniverseFieldNames,
- ARRAY_RTI_PROPERTY,
- CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME,
- RTI_UNIVERSE,
- TYPES;
-
+import 'dart:_js_shared_embedded_names';
import 'dart:_recipe_syntax';
+/// The name of a property on the constructor function of Dart Object
+/// and interceptor types, used for caching Rti types.
+const CONSTRUCTOR_RTI_CACHE_PROPERTY_NAME = r'$ccache';
+
// The top type `Object?` is used throughout this library even when values are
// not nullable or have narrower types in order to avoid incurring type checks
// before the type checking infrastructure has been set up.
diff --git a/sdk/lib/_internal/js_shared/lib/synced/embedded_names.dart b/sdk/lib/_internal/js_shared/lib/synced/embedded_names.dart
new file mode 100644
index 0000000..c2f6307
--- /dev/null
+++ b/sdk/lib/_internal/js_shared/lib/synced/embedded_names.dart
@@ -0,0 +1,116 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart=2.12
+
+/// A 'Universe' object used by 'dart:_rti'.
+const RTI_UNIVERSE = 'typeUniverse';
+
+/// An embedded global that contains the property used to store type information
+/// on JavaScript Array instances. This is a Symbol (except for IE11, where is
+/// is a String).
+const ARRAY_RTI_PROPERTY = 'arrayRti';
+
+/// A list of types used in the program e.g. for reflection or encoding of
+/// function types.
+///
+/// Use [JsBuiltin.getType] instead of directly accessing this embedded global.
+const TYPES = 'types';
+
+/// Names that are supported by [JS_GET_NAME].
+// TODO(herhut): Make entries lower case (as in fields) and find a better name.
+enum JsGetName {
+ GETTER_PREFIX,
+ SETTER_PREFIX,
+ CALL_PREFIX,
+ CALL_PREFIX0,
+ CALL_PREFIX1,
+ CALL_PREFIX2,
+ CALL_PREFIX3,
+ CALL_PREFIX4,
+ CALL_PREFIX5,
+ CALL_CATCH_ALL,
+ REQUIRED_PARAMETER_PROPERTY,
+ DEFAULT_VALUES_PROPERTY,
+ CALL_NAME_PROPERTY,
+ DEFERRED_ACTION_PROPERTY,
+
+ /// Prefix used for generated type test property on classes.
+ OPERATOR_IS_PREFIX,
+
+ /// Name used for generated function types on classes and methods.
+ SIGNATURE_NAME,
+
+ /// Name of JavaScript property used to store runtime-type information on
+ /// instances of parameterized classes.
+ RTI_NAME,
+
+ /// String representation of the type of the Future class.
+ FUTURE_CLASS_TYPE_NAME,
+
+ /// Field name used for determining if an object or its interceptor has
+ /// JavaScript indexing behavior.
+ IS_INDEXABLE_FIELD_NAME,
+
+ /// String representation of the type of the null class.
+ NULL_CLASS_TYPE_NAME,
+
+ /// String representation of the type of the object class.
+ OBJECT_CLASS_TYPE_NAME,
+
+ /// String representation of the type of the List class.
+ LIST_CLASS_TYPE_NAME,
+
+ /// Property name for Rti._as field.
+ RTI_FIELD_AS,
+
+ /// Property name for Rti._is field.
+ RTI_FIELD_IS,
+}
+
+enum JsBuiltin {
+ /// Returns the JavaScript constructor function for Dart's Object class.
+ /// This can be used for type tests, as in
+ ///
+ /// var constructor = JS_BUILTIN('', JsBuiltin.dartObjectConstructor);
+ /// if (JS('bool', '# instanceof #', obj, constructor))
+ /// ...
+ dartObjectConstructor,
+
+ /// Returns the JavaScript constructor function for the runtime's Closure
+ /// class, the base class of all closure objects. This can be used for type
+ /// tests, as in
+ ///
+ /// var constructor = JS_BUILTIN('', JsBuiltin.dartClosureConstructor);
+ /// if (JS('bool', '# instanceof #', obj, constructor))
+ /// ...
+ dartClosureConstructor,
+
+ /// Returns true if the given type is a type argument of a js-interop class
+ /// or a supertype of a js-interop class.
+ ///
+ /// JS_BUILTIN('bool', JsBuiltin.isJsInteropTypeArgument, o)
+ isJsInteropTypeArgument,
+
+ /// Returns the metadata of the given [index].
+ ///
+ /// JS_BUILTIN('returns:var;effects:none;depends:none',
+ /// JsBuiltin.getMetadata, index);
+ getMetadata,
+
+ /// Returns the type of the given [index].
+ ///
+ /// JS_BUILTIN('returns:var;effects:none;depends:none',
+ /// JsBuiltin.getType, index);
+ getType,
+}
+
+/// Names of fields of the Rti Universe object.
+class RtiUniverseFieldNames {
+ static String evalCache = 'eC';
+ static String typeRules = 'tR';
+ static String erasedTypes = 'eT';
+ static String typeParameterVariances = 'tPV';
+ static String sharedEmptyArray = 'sEA';
+}
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index 5a357e5..5cbab01 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -176,6 +176,11 @@
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
+ "_js_shared_embedded_names": const LibraryInfo(
+ "_internal/js_shared/lib/synced/embedded_names.dart",
+ categories: "",
+ documented: false,
+ platforms: DART2JS_PLATFORM),
"_async_await_error_codes": const LibraryInfo(
"_internal/js_runtime/lib/synced/async_await_error_codes.dart",
categories: "",
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 6f33d88..4c5eb19 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -386,6 +386,9 @@
"_js_embedded_names": {
"uri": "_internal/js_runtime/lib/synced/embedded_names.dart"
},
+ "_js_shared_embedded_names": {
+ "uri": "_internal/js_shared/lib/synced/embedded_names.dart"
+ },
"_async_await_error_codes": {
"uri": "_internal/js_runtime/lib/synced/async_await_error_codes.dart"
},
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index ed11fa5..c09c34e 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -354,6 +354,9 @@
_js_embedded_names:
uri: "_internal/js_runtime/lib/synced/embedded_names.dart"
+ _js_shared_embedded_names:
+ uri: "_internal/js_shared/lib/synced/embedded_names.dart"
+
_async_await_error_codes:
uri: "_internal/js_runtime/lib/synced/async_await_error_codes.dart"
diff --git a/tests/web/internal/rti/subtype_test.dart b/tests/web/internal/rti/subtype_test.dart
index d4f0c48..b6ceded 100644
--- a/tests/web/internal/rti/subtype_test.dart
+++ b/tests/web/internal/rti/subtype_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:_foreign_helper' show JS, JS_GET_NAME, TYPE_REF;
-import 'dart:_js_embedded_names' show JsGetName;
+import 'dart:_js_shared_embedded_names' show JsGetName;
import 'dart:_rti' as rti;
import 'package:expect/expect.dart';
diff --git a/tests/web_2/internal/rti/subtype_test.dart b/tests/web_2/internal/rti/subtype_test.dart
index 3ffea446..5cdb5ce 100644
--- a/tests/web_2/internal/rti/subtype_test.dart
+++ b/tests/web_2/internal/rti/subtype_test.dart
@@ -5,7 +5,7 @@
// @dart = 2.7
import 'dart:_foreign_helper' show JS, JS_GET_NAME, TYPE_REF;
-import 'dart:_js_embedded_names' show JsGetName;
+import 'dart:_js_shared_embedded_names' show JsGetName;
import 'dart:_rti' as rti;
import 'subtype_utils.dart';
diff --git a/tools/VERSION b/tools/VERSION
index df3ca95..e0ae251 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 146
+PRERELEASE 147
PRERELEASE_PATCH 0
\ No newline at end of file