Version 2.17.0-216.0.dev
Merge commit 'acc535dfab7d53fe6f73e7bf36ab57f25e028ab8' into 'dev'
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 6cb63ed..fae383f 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -333,7 +333,11 @@
var packageName = file.parent.parent.shortName;
var content = _readFile(path);
var errorListener = RecordingErrorListener();
- var errorReporter = ErrorReporter(errorListener, file.createSource());
+ var errorReporter = ErrorReporter(
+ errorListener,
+ file.createSource(),
+ isNonNullableByDefault: false,
+ );
var parser = TransformSetParser(errorReporter, packageName);
parser.parse(content);
var converter = AnalyzerConverter();
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index 7e1578b..ae25ec1 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -14,6 +14,7 @@
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer/src/workspace/bazel.dart';
@@ -107,6 +108,13 @@
String toString() => message;
}
+class PluginFiles {
+ final File execution;
+ final File packages;
+
+ PluginFiles(this.execution, this.packages);
+}
+
/// Information about a single plugin.
abstract class PluginInfo {
/// The object used to manage the receiving and sending of notifications.
@@ -315,9 +323,9 @@
var isNew = false;
if (plugin == null) {
isNew = true;
- List<String> pluginPaths;
+ PluginFiles pluginFiles;
try {
- pluginPaths = pathsFor(path);
+ pluginFiles = filesFor(path);
} catch (exception, stackTrace) {
plugin = DiscoveredPluginInfo(
path, '', '', notificationManager, instrumentationService);
@@ -325,8 +333,12 @@
_pluginMap[path] = plugin;
return;
}
- plugin = DiscoveredPluginInfo(path, pluginPaths[0], pluginPaths[1],
- notificationManager, instrumentationService);
+ plugin = DiscoveredPluginInfo(
+ path,
+ pluginFiles.execution.path,
+ pluginFiles.packages.path,
+ notificationManager,
+ instrumentationService);
_pluginMap[path] = plugin;
try {
var session = await plugin.start(byteStorePath, sdkPath);
@@ -413,24 +425,24 @@
return responses;
}
- /// Return the execution path and .packages path associated with the plugin at
- /// the given [path]. Throw a [PluginException] if there is a problem that
- /// prevents the plugin from being executing.
+ /// Return the files associated with the plugin at the given [pluginPath].
+ /// Throw a [PluginException] if there is a problem that prevents the plugin
+ /// from being executing.
@visibleForTesting
- List<String> pathsFor(String pluginPath) {
+ PluginFiles filesFor(String pluginPath) {
var pluginFolder = resourceProvider.getFolder(pluginPath);
var pubspecFile = pluginFolder.getChildAssumingFile(file_paths.pubspecYaml);
if (!pubspecFile.exists) {
// If there's no pubspec file, then we don't need to copy the package
// because we won't be running pub.
- return _computePaths(pluginFolder);
+ return _computeFiles(pluginFolder);
}
var workspace = BazelWorkspace.find(resourceProvider, pluginFolder.path) ??
GnWorkspace.find(resourceProvider, pluginFolder.path);
if (workspace != null) {
// Similarly, we won't be running pub if we're in a workspace because
// there is exactly one version of each package.
- return _computePaths(pluginFolder, workspace: workspace);
+ return _computeFiles(pluginFolder, workspace: workspace);
}
//
// Copy the plugin directory to a unique subdirectory of the plugin
@@ -447,10 +459,10 @@
if (parentFolder.exists) {
var executionFolder =
parentFolder.getChildAssumingFolder(pluginFolder.shortName);
- return _computePaths(executionFolder, pubCommand: 'upgrade');
+ return _computeFiles(executionFolder, pubCommand: 'upgrade');
}
var executionFolder = pluginFolder.copyTo(parentFolder);
- return _computePaths(executionFolder, pubCommand: 'get');
+ return _computeFiles(executionFolder, pubCommand: 'get');
}
/// Return a list of all of the plugins that are currently associated with the
@@ -603,11 +615,11 @@
}));
}
- /// Compute the paths to be returned by the enclosing method given that the
+ /// Compute the files to be returned by the enclosing method given that the
/// plugin should exist in the given [pluginFolder].
///
/// Runs pub if [pubCommand] is provided and not null.
- List<String> _computePaths(Folder pluginFolder,
+ PluginFiles _computeFiles(Folder pluginFolder,
{String? pubCommand, Workspace? workspace}) {
var pluginFile = pluginFolder
.getChildAssumingFolder('bin')
@@ -616,7 +628,9 @@
throw PluginException('File "${pluginFile.path}" does not exist.');
}
String? reason;
- File? packagesFile = pluginFolder.getChildAssumingFile('.packages');
+ File? packagesFile = pluginFolder
+ .getChildAssumingFolder(file_paths.dotDartTool)
+ .getChildAssumingFile(file_paths.packageConfigJson);
if (pubCommand != null) {
var vmPath = Platform.executable;
var pubPath = path.join(path.dirname(vmPath), 'pub');
@@ -648,7 +662,8 @@
packagesFile =
_createPackagesFile(pluginFolder, workspace.packageUriResolver);
if (packagesFile == null) {
- reason = 'Could not create .packages file in workspace $workspace.';
+ var name = file_paths.packageConfigJson;
+ reason = 'Could not create $name file in workspace $workspace.';
}
} else {
reason = 'Could not create "${packagesFile.path}".';
@@ -659,7 +674,7 @@
reason ??= 'Could not create packages file for an unknown reason.';
throw PluginException(reason);
}
- return <String>[pluginFile.path, packagesFile.path];
+ return PluginFiles(pluginFile, packagesFile);
}
WatchEventType _convertChangeType(watcher.ChangeType type) {
@@ -679,15 +694,15 @@
return WatchEvent(_convertChangeType(watchEvent.type), watchEvent.path);
}
- /// Return a temporary `.packages` file that is appropriate for the plugin in
- /// the given [pluginFolder]. The [packageUriResolver] is used to determine
- /// the location of the packages that need to be included in the packages
- /// file.
+ /// Return a temporary `package_config.json` file that is appropriate for
+ /// the plugin in the given [pluginFolder]. The [packageUriResolver] is
+ /// used to determine the location of the packages that need to be included
+ /// in the packages file.
File? _createPackagesFile(
Folder pluginFolder, UriResolver packageUriResolver) {
var pluginPath = pluginFolder.path;
var stateFolder = resourceProvider.getStateLocation('.plugin_manager')!;
- var stateName = _uniqueDirectoryName(pluginPath) + '.packages';
+ var stateName = '${_uniqueDirectoryName(pluginPath)}.packages';
var packagesFile = stateFolder.getChildAssumingFile(stateName);
if (!packagesFile.exists) {
var pluginPubspec =
@@ -697,36 +712,55 @@
}
try {
- var visitedPackages = <String, String>{};
+ var visitedPackageNames = <String>{};
+ var packages = <_Package>[];
var context = resourceProvider.pathContext;
- visitedPackages[context.basename(pluginPath)] =
- context.join(pluginFolder.path, 'lib');
+ packages.add(
+ _Package(
+ context.basename(pluginPath),
+ pluginFolder,
+ ),
+ );
var pubspecFiles = <File>[];
pubspecFiles.add(pluginPubspec);
while (pubspecFiles.isNotEmpty) {
var pubspecFile = pubspecFiles.removeLast();
- for (var packageName in _readDependecies(pubspecFile)) {
- if (!visitedPackages.containsKey(packageName)) {
+ for (var packageName in _readDependencies(pubspecFile)) {
+ if (visitedPackageNames.add(packageName)) {
var uri = Uri.parse('package:$packageName/$packageName.dart');
var packageSource = packageUriResolver.resolveAbsolute(uri);
if (packageSource != null) {
- var libDirPath = context.dirname(packageSource.fullName);
- visitedPackages[packageName] = libDirPath;
- var pubspecPath = context.join(
- context.dirname(libDirPath), file_paths.pubspecYaml);
- pubspecFiles.add(resourceProvider.getFile(pubspecPath));
+ var packageRoot = resourceProvider
+ .getFile(packageSource.fullName)
+ .parent
+ .parent;
+ packages.add(
+ _Package(packageName, packageRoot),
+ );
+ pubspecFiles.add(
+ packageRoot.getChildAssumingFile(file_paths.pubspecYaml),
+ );
}
}
}
}
- var buffer = StringBuffer();
- visitedPackages.forEach((String name, String path) {
- buffer.write(name);
- buffer.write(':');
- buffer.writeln(Uri.file(path));
- });
- packagesFile.writeAsStringSync(buffer.toString());
+ packages.sort((a, b) => a.name.compareTo(b.name));
+
+ var packageConfigBuilder = PackageConfigFileBuilder();
+ for (var package in packages) {
+ packageConfigBuilder.add(
+ name: package.name,
+ rootPath: package.root.path,
+ );
+ }
+ packagesFile.writeAsStringSync(
+ packageConfigBuilder.toContent(
+ toUriStr: (path) {
+ return resourceProvider.pathContext.toUri(path).toString();
+ },
+ ),
+ );
} catch (exception) {
// If we are not able to produce a .packages file, return null so that
// callers will not try to load the plugin.
@@ -740,7 +774,7 @@
/// Return the names of packages that are listed as dependencies in the given
/// [pubspecFile].
- Iterable<String> _readDependecies(File pubspecFile) {
+ Iterable<String> _readDependencies(File pubspecFile) {
var document = loadYamlDocument(pubspecFile.readAsStringSync(),
sourceUrl: pubspecFile.toUri());
var contents = document.contents;
@@ -985,6 +1019,13 @@
}
}
+class _Package {
+ final String name;
+ final Folder root;
+
+ _Package(this.name, this.root);
+}
+
/// Information about a request that has been sent but for which a response has
/// not yet been received.
class _PendingRequest {
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 5f286c8..3104866 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -417,8 +417,13 @@
var configFile = provider.getFile(configFileName);
try {
var content = configFile.readAsStringSync();
- var parser = TransformOverrideSetParser(ErrorReporter(
- AnalysisErrorListener.NULL_LISTENER, configFile.createSource()));
+ var parser = TransformOverrideSetParser(
+ ErrorReporter(
+ AnalysisErrorListener.NULL_LISTENER,
+ configFile.createSource(),
+ isNonNullableByDefault: false,
+ ),
+ );
return parser.parse(content);
} on FileSystemException {
// Fall through to return null.
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart
index f21df2a..5f7e010 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_super_parameters.dart
@@ -67,7 +67,8 @@
var parameterMap = _parameterMap(constructor.parameters);
List<_ParameterData>? positional = [];
var named = <_ParameterData>[];
- var arguments = superInvocation.argumentList.arguments;
+ var argumentList = superInvocation.argumentList;
+ var arguments = argumentList.arguments;
for (var argumentIndex = 0;
argumentIndex < arguments.length;
argumentIndex++) {
@@ -156,18 +157,26 @@
}
// Remove the corresponding arguments.
- if (argumentsToDelete.length == arguments.length &&
- superInvocation.constructorName == null) {
- var initializers = constructor.initializers;
- SourceRange initializerRange;
- if (initializers.length == 1) {
- initializerRange =
- range.endEnd(constructor.parameters, superInvocation);
+ if (argumentsToDelete.length == arguments.length) {
+ if (superInvocation.constructorName == null) {
+ // Delete the whole invocation.
+ var initializers = constructor.initializers;
+ SourceRange initializerRange;
+ if (initializers.length == 1) {
+ initializerRange =
+ range.endEnd(constructor.parameters, superInvocation);
+ } else {
+ initializerRange = range.nodeInList(initializers, superInvocation);
+ }
+ builder.addDeletion(initializerRange);
} else {
- initializerRange = range.nodeInList(initializers, superInvocation);
+ // Leave the invocation, but remove all of the arguments, including
+ // any trailing comma.
+ builder.addDeletion(range.endStart(
+ argumentList.leftParenthesis, argumentList.rightParenthesis));
}
- builder.addDeletion(initializerRange);
} else {
+ // Remove just the arguments that are no longer needed.
var ranges = range.nodesInList(arguments, argumentsToDelete);
for (var range in ranges) {
builder.addDeletion(range);
@@ -260,16 +269,13 @@
}
/// Return the parameter corresponding to the [expression], or `null` if the
- /// expression isn't a simple reference to one of the parameters in the
+ /// expression isn't a simple reference to one of the normal parameters in the
/// constructor being converted.
_Parameter? _parameterFor(
Map<ParameterElement, _Parameter> parameterMap, Expression expression) {
if (expression is SimpleIdentifier) {
var element = expression.staticElement;
- var parameter = parameterMap[element];
- if (parameter != null) {
- return parameter;
- }
+ return parameterMap[element];
}
return null;
}
@@ -278,13 +284,23 @@
/// elements.
Map<ParameterElement, _Parameter> _parameterMap(
FormalParameterList parameterList) {
+ bool validParameter(FormalParameter parameter) {
+ if (parameter is DefaultFormalParameter) {
+ parameter = parameter.parameter;
+ }
+ return parameter is SimpleFormalParameter ||
+ parameter is FunctionTypedFormalParameter;
+ }
+
var map = <ParameterElement, _Parameter>{};
var parameters = parameterList.parameters;
for (var i = 0; i < parameters.length; i++) {
var parameter = parameters[i];
- var element = parameter.declaredElement;
- if (element != null) {
- map[element] = _Parameter(parameter, element, i);
+ if (validParameter(parameter)) {
+ var element = parameter.declaredElement;
+ if (element != null) {
+ map[element] = _Parameter(parameter, element, i);
+ }
}
}
return map;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
index 38efa60..d971585 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_manager.dart
@@ -58,7 +58,10 @@
var content = file.readAsStringSync();
var parser = TransformSetParser(
ErrorReporter(
- AnalysisErrorListener.NULL_LISTENER, file.createSource()),
+ AnalysisErrorListener.NULL_LISTENER,
+ file.createSource(),
+ isNonNullableByDefault: false,
+ ),
file.parent.parent.shortName);
return parser.parse(content);
} on FileSystemException {
diff --git a/pkg/analysis_server/lib/src/utilities/mocks.dart b/pkg/analysis_server/lib/src/utilities/mocks.dart
index 6ad7371..494b98c 100644
--- a/pkg/analysis_server/lib/src/utilities/mocks.dart
+++ b/pkg/analysis_server/lib/src/utilities/mocks.dart
@@ -207,8 +207,8 @@
}
@override
- List<String> pathsFor(String pluginPath) {
- fail('Unexpected invocation of pathsFor');
+ PluginFiles filesFor(String pluginPath) {
+ fail('Unexpected invocation of filesFor');
}
@override
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index cbf06cd..ab989d5 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -158,6 +158,7 @@
serverPath = normalize(join(dirname(Platform.resolvedExecutable),
'dart-sdk', 'bin', 'snapshots', 'analysis_server.dart.snapshot'));
}
+ // ignore: dead_code
} else {
final rootDir =
findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart
index 3ef73c2..1d0e499 100644
--- a/pkg/analysis_server/test/integration/support/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -639,6 +639,7 @@
'snapshots',
'analysis_server.dart.snapshot'));
}
+ // ignore: dead_code
} else {
var rootDir =
findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index 4241eec..e9d809e 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -474,21 +474,20 @@
expect(manager.notificationManager, notificationManager);
}
- void test_pathsFor_withPackagesFile() {
+ void test_pathsFor_withPackageConfigJsonFile() {
//
// Build the minimal directory structure for a plugin package that includes
- // a .packages file.
+ // a '.dart_tool/package_config.json' file.
//
var pluginDirPath = newFolder('/plugin').path;
- var pluginFilePath = newFile2('/plugin/bin/plugin.dart', '').path;
- var packagesFilePath = newDotPackagesFile('/plugin', '').path;
+ var pluginFile = newFile2('/plugin/bin/plugin.dart', '');
+ var packageConfigFile = newPackageConfigJsonFile('/plugin', '');
//
// Test path computation.
//
- var paths = manager.pathsFor(pluginDirPath);
- expect(paths, hasLength(2));
- expect(paths[0], pluginFilePath);
- expect(paths[1], packagesFilePath);
+ var files = manager.filesFor(pluginDirPath);
+ expect(files.execution, pluginFile);
+ expect(files.packages, packageConfigFile);
}
void test_pathsFor_withPubspec_inBazelWorkspace() {
@@ -515,30 +514,46 @@
}
var pluginDirPath = newPackage('plugin', ['b', 'c']);
- newPackage('b', ['d']);
- newPackage('c', ['d']);
- newPackage('d');
- var pluginFilePath = newFile2('$pluginDirPath/bin/plugin.dart', '').path;
+ var bRootPath = newPackage('b', ['d']);
+ var cRootPath = newPackage('c', ['d']);
+ var dRootPath = newPackage('d');
+ var pluginFile = newFile2('$pluginDirPath/bin/plugin.dart', '');
//
// Test path computation.
//
- var paths = manager.pathsFor(pluginDirPath);
- expect(paths, hasLength(2));
- expect(paths[0], pluginFilePath);
- var packagesFile = getFile(paths[1]);
+ var files = manager.filesFor(pluginDirPath);
+ expect(files.execution, pluginFile);
+ var packagesFile = files.packages;
expect(packagesFile.exists, isTrue);
+
var content = packagesFile.readAsStringSync();
- var lines = content.split('\n');
- String asFileUri(String input) => Uri.file(convertPath(input)).toString();
- expect(
- lines,
- unorderedEquals([
- 'plugin:${asFileUri('/workspaceRoot/third_party/dart/plugin/lib')}',
- 'b:${asFileUri('/workspaceRoot/third_party/dart/b/lib')}',
- 'c:${asFileUri('/workspaceRoot/third_party/dart/c/lib')}',
- 'd:${asFileUri('/workspaceRoot/third_party/dart/d/lib')}',
- ''
- ]));
+ expect(content, '''
+{
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "b",
+ "rootUri": "${toUriStr(bRootPath)}",
+ "packageUri": "lib/"
+ },
+ {
+ "name": "c",
+ "rootUri": "${toUriStr(cRootPath)}",
+ "packageUri": "lib/"
+ },
+ {
+ "name": "d",
+ "rootUri": "${toUriStr(dRootPath)}",
+ "packageUri": "lib/"
+ },
+ {
+ "name": "plugin",
+ "rootUri": "${toUriStr(pluginDirPath)}",
+ "packageUri": "lib/"
+ }
+ ]
+}
+''');
}
void test_pluginsForContextRoot_none() {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_super_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_super_parameters_test.dart
index 1923910..1bf7f74 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_super_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_super_parameters_test.dart
@@ -164,6 +164,39 @@
''');
}
+ Future<void> test_functionTypedFormalParameter() async {
+ await resolveTestCode('''
+class A {
+ A(int f(int x));
+}
+class B extends A {
+ B(int f(int x)) : super(f);
+}
+''');
+ await assertHasAssistAt('B(', '''
+class A {
+ A(int f(int x));
+}
+class B extends A {
+ B(super.f);
+}
+''');
+ }
+
+ Future<void> test_invalid_fieldFormalParameter() async {
+ await resolveTestCode('''
+class A {
+ int x;
+ A(this.x);
+}
+class B extends A {
+ int y;
+ B(this.y) : super(y);
+}
+''');
+ await assertNoAssistAt('B(');
+ }
+
Future<void> test_invalid_namedToPositional() async {
await resolveTestCode('''
class A {
@@ -702,4 +735,23 @@
}
''');
}
+
+ Future<void> test_trailingComma() async {
+ await resolveTestCode('''
+class A {
+ A._(int x, int y);
+}
+class B extends A {
+ B(int x, int y) : super._(x, y,);
+}
+''');
+ await assertHasAssistAt('B(', '''
+class A {
+ A._(int x, int y);
+}
+class B extends A {
+ B(super.x, super.y) : super._();
+}
+''');
+ }
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart
index d20113b..8878039 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/code_fragment_parser_test.dart
@@ -68,7 +68,11 @@
CodeFragmentParser _parser(GatheringErrorListener listener,
{List<String>? variables}) {
- var errorReporter = ErrorReporter(listener, MockSource());
+ var errorReporter = ErrorReporter(
+ listener,
+ MockSource(),
+ isNonNullableByDefault: false,
+ );
var map = <String, ValueGenerator>{};
if (variables != null) {
for (var variableName in variables) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_test.dart
index 9d4c388..50fdbb9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_override_set_parser_test.dart
@@ -56,8 +56,11 @@
void parse(String content) {
errorListener = GatheringErrorListener();
- var errorReporter =
- ErrorReporter(errorListener, MockSource(fullName: 'data.yaml'));
+ var errorReporter = ErrorReporter(
+ errorListener,
+ MockSource(fullName: 'data.yaml'),
+ isNonNullableByDefault: false,
+ );
var parser = TransformOverrideSetParser(errorReporter);
result = parser.parse(content);
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart
index 66ddafd..5ed5d4e 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test_support.dart
@@ -39,8 +39,11 @@
expectedContextMessages: contextMessages);
void parse(String content) {
- var errorReporter =
- ErrorReporter(errorListener, MockSource(fullName: 'data.yaml'));
+ var errorReporter = ErrorReporter(
+ errorListener,
+ MockSource(fullName: 'data.yaml'),
+ isNonNullableByDefault: false,
+ );
var parser = TransformSetParser(errorReporter, 'myPackage');
result = parser.parse(content);
}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index a1312a7..1886590 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -12,6 +12,7 @@
* Changed `CompilationUnitElement.lineInfo` to be non-nullable.
* Deprecated `ResourceProviderMixin.newFile`, use `newFile2` instead.
* Deprecated `ResourceProviderMixin.newAnalysisOptionsYamlFile`.
+* Added `AnalysisContext.changeFile` and `AnalysisContext.applyPendingFileChanges`.
## 3.3.1
* Report HintCode.OVERRIDE_ON_NON_OVERRIDING_xyz on enum.
diff --git a/pkg/analyzer/lib/dart/analysis/analysis_context.dart b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
index 68fb611..2a49b01 100644
--- a/pkg/analyzer/lib/dart/analysis/analysis_context.dart
+++ b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
@@ -42,8 +42,16 @@
/// The value is the set of all files that are potentially affected by
/// the pending changes. This set can be both wider than the set of analyzed
/// files (because it may include files imported from other packages, and
- /// which are on the import path from a changed file to an analyze file),
+ /// which are on the import path from a changed file to an analyzed file),
/// and narrower than the set of analyzed files (because only files that
/// were previously accessed are considered to be known and affected).
Future<List<String>> applyPendingFileChanges();
+
+ /// Schedules the file with the [path] to be read before producing new
+ /// analysis results.
+ ///
+ /// The file is expected to be a Dart file, reporting non-Dart files, such
+ /// as configuration files `analysis_options.yaml`, `package_config.json`,
+ /// etc will not re-create analysis contexts.
+ void changeFile(String path);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
index 2f3fd34..266ad41 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
@@ -14,6 +14,7 @@
import 'package:analyzer/src/dart/analysis/file_content_cache.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/util/sdk.dart';
/// An implementation of [AnalysisContextCollection].
@@ -42,6 +43,7 @@
AnalysisDriverScheduler? scheduler,
FileContentCache? fileContentCache,
void Function(AnalysisOptionsImpl)? updateAnalysisOptions,
+ MacroKernelBuilder? macroKernelBuilder,
}) : resourceProvider =
resourceProvider ?? PhysicalResourceProvider.INSTANCE {
sdkPath ??= getSdkPath();
@@ -74,6 +76,7 @@
scheduler: scheduler,
updateAnalysisOptions: updateAnalysisOptions,
fileContentCache: fileContentCache,
+ macroKernelBuilder: macroKernelBuilder,
);
contexts.add(context);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index 0aa945a..ddb9cc9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -25,6 +25,7 @@
import 'package:analyzer/src/hint/sdk_constraint_extractor.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
@@ -58,6 +59,7 @@
String? sdkSummaryPath,
void Function(AnalysisOptionsImpl)? updateAnalysisOptions,
FileContentCache? fileContentCache,
+ MacroKernelBuilder? macroKernelBuilder,
}) {
// TODO(scheglov) Remove this, and make `sdkPath` required.
sdkPath ??= getSdkPath();
@@ -115,6 +117,7 @@
externalSummaries: summaryData,
retainDataForTesting: retainDataForTesting,
fileContentCache: fileContentCache,
+ macroKernelBuilder: macroKernelBuilder,
);
if (declaredVariables != null) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 562528c..5ab147e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -42,6 +42,7 @@
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary2/ast_binary_flags.dart';
+import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/util/file_paths.dart' as file_paths;
import 'package:analyzer/src/util/performance/operation_performance.dart';
import 'package:meta/meta.dart';
@@ -82,7 +83,7 @@
/// TODO(scheglov) Clean up the list of implicitly analyzed files.
class AnalysisDriver implements AnalysisDriverGeneric {
/// The version of data format, should be incremented on every format change.
- static const int DATA_VERSION = 210;
+ static const int DATA_VERSION = 211;
static const bool _applyFileChangesSynchronously = true;
@@ -124,6 +125,8 @@
/// from file paths.
SourceFactory _sourceFactory;
+ final MacroKernelBuilder? macroKernelBuilder;
+
/// The declared environment variables.
DeclaredVariables declaredVariables = DeclaredVariables();
@@ -257,6 +260,7 @@
required SourceFactory sourceFactory,
required AnalysisOptionsImpl analysisOptions,
required Packages packages,
+ this.macroKernelBuilder,
FileContentCache? fileContentCache,
bool enableIndex = false,
SummaryDataStore? externalSummaries,
@@ -322,7 +326,9 @@
analysisOptions: _analysisOptions,
declaredVariables: declaredVariables,
sourceFactory: _sourceFactory,
+ macroKernelBuilder: macroKernelBuilder,
externalSummaries: _externalSummaries,
+ fileSystemState: _fsState,
);
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index 79b54c0..394b920 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -58,4 +58,9 @@
Future<List<String>> applyPendingFileChanges() {
return driver.applyPendingFileChanges();
}
+
+ @override
+ void changeFile(String path) {
+ driver.changeFile(path);
+ }
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 2e1c323..9424fd1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -40,6 +40,7 @@
import 'package:collection/collection.dart';
import 'package:convert/convert.dart';
import 'package:meta/meta.dart';
+import 'package:path/path.dart' as package_path;
import 'package:pub_semver/pub_semver.dart';
var counterFileStateRefresh = 0;
@@ -599,6 +600,7 @@
var exports = <UnlinkedNamespaceDirective>[];
var imports = <UnlinkedNamespaceDirective>[];
var parts = <String>[];
+ var macroClasses = <MacroClass>[];
var hasDartCoreImport = false;
var hasLibraryDirective = false;
var hasPartOfDirective = false;
@@ -621,6 +623,25 @@
hasPartOfDirective = true;
}
}
+ for (var declaration in unit.declarations) {
+ if (declaration is ClassDeclarationImpl) {
+ if (declaration.macroKeyword != null) {
+ var constructors = declaration.members
+ .whereType<ConstructorDeclaration>()
+ .map((e) => e.name?.name ?? '')
+ .where((e) => !e.startsWith('_'))
+ .toList();
+ if (constructors.isNotEmpty) {
+ macroClasses.add(
+ MacroClass(
+ name: declaration.name.name,
+ constructors: constructors,
+ ),
+ );
+ }
+ }
+ }
+ }
if (!hasDartCoreImport) {
imports.add(
UnlinkedNamespaceDirective(
@@ -637,6 +658,7 @@
imports: imports,
informativeBytes: writeUnitInformative(unit),
lineStarts: Uint32List.fromList(unit.lineInfo.lineStarts),
+ macroClasses: macroClasses,
partOfName: null,
partOfUri: null,
parts: parts,
@@ -764,6 +786,8 @@
_testView = FileSystemStateTestView(this);
}
+ package_path.Context get pathContext => _resourceProvider.pathContext;
+
@visibleForTesting
FileSystemStateTestView get test => _testView;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 53cdde8..4610294 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -22,7 +22,9 @@
import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/link.dart' as link2;
import 'package:analyzer/src/summary2/linked_element_factory.dart';
+import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/summary2/reference.dart';
+import 'package:path/src/context.dart';
var counterLinkedLibraries = 0;
var counterLoadedLibraries = 0;
@@ -39,6 +41,8 @@
final LibraryContextTestView testView;
final PerformanceLog logger;
final ByteStore byteStore;
+ final FileSystemState fileSystemState;
+ final MacroKernelBuilder? macroKernelBuilder;
final SummaryDataStore store = SummaryDataStore();
late final AnalysisContextImpl analysisContext;
@@ -49,9 +53,11 @@
required AnalysisSessionImpl analysisSession,
required PerformanceLog logger,
required ByteStore byteStore,
+ required this.fileSystemState,
required AnalysisOptionsImpl analysisOptions,
required DeclaredVariables declaredVariables,
required SourceFactory sourceFactory,
+ this.macroKernelBuilder,
required SummaryDataStore? externalSummaries,
}) : logger = logger,
byteStore = byteStore {
@@ -120,9 +126,28 @@
cycle.directDependencies.forEach(loadBundle);
var unitsInformativeBytes = <Uri, Uint8List>{};
+ var macroLibraries = <MacroLibrary>[];
for (var library in cycle.libraries) {
+ var macroClasses = <MacroClass>[];
for (var file in library.libraryFiles) {
unitsInformativeBytes[file.uri] = file.unlinked2.informativeBytes;
+ for (var macroClass in file.unlinked2.macroClasses) {
+ macroClasses.add(
+ MacroClass(
+ name: macroClass.name,
+ constructors: macroClass.constructors,
+ ),
+ );
+ }
+ }
+ if (macroClasses.isNotEmpty) {
+ macroLibraries.add(
+ MacroLibrary(
+ uri: library.uri,
+ path: library.path,
+ classes: macroClasses,
+ ),
+ );
}
}
@@ -206,6 +231,17 @@
),
);
}
+
+ final macroKernelBuilder = this.macroKernelBuilder;
+ if (macroKernelBuilder != null && macroLibraries.isNotEmpty) {
+ var macroKernelKey = cycle.transitiveSignature + '.macro_kernel';
+ var macroKernelBytes = macroKernelBuilder.build(
+ fileSystem: _MacroFileSystem(fileSystemState),
+ libraries: macroLibraries,
+ );
+ byteStore.put(macroKernelKey, macroKernelBytes);
+ bytesPut += macroKernelBytes.length;
+ }
}
logger.run('Prepare linked bundles', () {
@@ -259,3 +295,30 @@
class LibraryContextTestView {
final List<Set<String>> linkedCycles = [];
}
+
+class _MacroFileEntry implements MacroFileEntry {
+ final FileState fileState;
+
+ _MacroFileEntry(this.fileState);
+
+ @override
+ String get content => fileState.content;
+
+ @override
+ bool get exists => fileState.exists;
+}
+
+class _MacroFileSystem implements MacroFileSystem {
+ final FileSystemState fileSystemState;
+
+ _MacroFileSystem(this.fileSystemState);
+
+ @override
+ Context get pathContext => fileSystemState.pathContext;
+
+ @override
+ MacroFileEntry getFile(String path) {
+ var fileState = fileSystemState.getFileForPath(path);
+ return _MacroFileEntry(fileState);
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
index 5ab1857..88cfdb8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/unlinked_data.dart
@@ -65,6 +65,31 @@
}
}
+/// Unlinked information about a `macro` class.
+class MacroClass {
+ final String name;
+ final List<String> constructors;
+
+ MacroClass({
+ required this.name,
+ required this.constructors,
+ });
+
+ factory MacroClass.read(
+ SummaryDataReader reader,
+ ) {
+ return MacroClass(
+ name: reader.readStringUtf8(),
+ constructors: reader.readStringUtf8List(),
+ );
+ }
+
+ void write(BufferedSink sink) {
+ sink.writeStringUtf8(name);
+ sink.writeStringUtf8Iterable(constructors);
+ }
+}
+
/// Unlinked information about a namespace directive.
class UnlinkedNamespaceDirective {
/// The configurations that control which library will actually be used.
@@ -159,6 +184,9 @@
/// Offsets of the first character of each line in the source code.
final Uint32List lineStarts;
+ /// The list of `macro` classes.
+ final List<MacroClass> macroClasses;
+
/// The library name of the `part of my.name;` directive.
final String? partOfName;
@@ -176,6 +204,7 @@
required this.imports,
required this.informativeBytes,
required this.lineStarts,
+ required this.macroClasses,
required this.partOfName,
required this.partOfUri,
required this.parts,
@@ -194,6 +223,9 @@
),
informativeBytes: reader.readUint8List(),
lineStarts: reader.readUInt30List(),
+ macroClasses: reader.readTypedList(
+ () => MacroClass.read(reader),
+ ),
partOfName: reader.readOptionalStringUtf8(),
partOfUri: reader.readOptionalStringUtf8(),
parts: reader.readStringUtf8List(),
@@ -212,6 +244,9 @@
});
sink.writeUint8List(informativeBytes);
sink.writeUint30List(lineStarts);
+ sink.writeList<MacroClass>(macroClasses, (x) {
+ x.write(sink);
+ });
sink.writeOptionalStringUtf8(partOfName);
sink.writeOptionalStringUtf8(partOfUri);
sink.writeStringUtf8Iterable(parts);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 11e0af2..05beef2 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1617,6 +1617,20 @@
return null;
}
+ @override
+ EvaluationResultImpl? get evaluationResult {
+ if (constantInitializer != null) {
+ return super.evaluationResult;
+ }
+
+ var superConstructorParameter = this.superConstructorParameter;
+ if (superConstructorParameter is ParameterElementImpl) {
+ return superConstructorParameter.evaluationResult;
+ }
+
+ return null;
+ }
+
DartObject? get _superConstructorParameterDefaultValue {
var superDefault = superConstructorParameter?.computeConstantValue();
var superDefaultType = superDefault?.type;
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 3953099..1f04dee 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -962,6 +962,7 @@
imports: imports,
informativeBytes: writeUnitInformative(unit),
lineStarts: Uint32List.fromList(unit.lineInfo.lineStarts),
+ macroClasses: [],
partOfName: partOfName,
partOfUri: partOfUriStr,
parts: parts,
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 6b789f1..635bb96 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -119,11 +119,6 @@
final Set<String> _libraryUris = <String>{};
final Set<String> _partUris = <String>{};
- SummaryDataStore();
-
- @Deprecated('Use SummaryDataStore() instead')
- SummaryDataStore.tmp();
-
/// Add the given [bundle] loaded from the file with the given [path].
void addBundle(String? path, PackageBundleReader bundle) {
bundles.add(bundle);
diff --git a/pkg/analyzer/lib/src/summary2/macro.dart b/pkg/analyzer/lib/src/summary2/macro.dart
new file mode 100644
index 0000000..a3502d0
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/macro.dart
@@ -0,0 +1,50 @@
+// 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.
+
+import 'dart:typed_data';
+
+import 'package:path/path.dart' as package_path;
+
+class MacroClass {
+ final String name;
+ final List<String> constructors;
+
+ MacroClass({
+ required this.name,
+ required this.constructors,
+ });
+}
+
+abstract class MacroFileEntry {
+ String get content;
+
+ /// When CFE searches for `package_config.json` we need to check this.
+ bool get exists;
+}
+
+abstract class MacroFileSystem {
+ /// Used to convert `file:` URIs into paths.
+ package_path.Context get pathContext;
+
+ MacroFileEntry getFile(String path);
+}
+
+abstract class MacroKernelBuilder {
+ Uint8List build({
+ required MacroFileSystem fileSystem,
+ required List<MacroLibrary> libraries,
+ });
+}
+
+class MacroLibrary {
+ final Uri uri;
+ final String path;
+ final List<MacroClass> classes;
+
+ MacroLibrary({
+ required this.uri,
+ required this.path,
+ required this.classes,
+ });
+}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 993aa69..82cba35 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -140,7 +140,7 @@
class _ConstructorInferenceNode extends _InferenceNode {
final _InferenceWalker _walker;
- final ConstructorElement _constructor;
+ final ConstructorElementImpl _constructor;
final List<_FieldFormalParameter> _fieldParameters = [];
final List<_SuperFormalParameter> _superParameters = [];
@@ -199,11 +199,14 @@
List<_InferenceNode> computeDependencies() {
var dependencies = [
..._fieldParameters.map((e) => _walker.getNode(e.field)).whereNotNull(),
- ..._superParameters
- .map((e) => _walker.getNode(e.superParameter))
- .whereNotNull(),
];
+ if (_superParameters.isNotEmpty) {
+ dependencies.addIfNotNull(
+ _walker.getNode(_constructor.superConstructor),
+ );
+ }
+
dependencies.addIfNotNull(
_walker.getNode(_baseConstructor?.element),
);
@@ -224,12 +227,11 @@
// Update types of a mixin application constructor formal parameters.
var baseConstructor = _baseConstructor;
if (baseConstructor != null) {
- var constructor = _constructor as ConstructorElementImpl;
var substitution = Substitution.fromInterfaceType(
baseConstructor.superType,
);
forCorrespondingPairs<ParameterElement, ParameterElement>(
- constructor.parameters,
+ _constructor.parameters,
baseConstructor.element.parameters,
(parameter, baseParameter) {
var type = substitution.substituteType(baseParameter.type);
@@ -239,10 +241,10 @@
// Update arguments of `SuperConstructorInvocation` to have the types
// (which we have just set) of the corresponding formal parameters.
// MixinApp(x, y) : super(x, y);
- var initializers = constructor.constantInitializers;
+ var initializers = _constructor.constantInitializers;
var initializer = initializers.single as SuperConstructorInvocation;
forCorrespondingPairs<ParameterElement, Expression>(
- constructor.parameters,
+ _constructor.parameters,
initializer.argumentList.arguments,
(parameter, argument) {
(argument as SimpleIdentifierImpl).staticType = parameter.type;
@@ -370,6 +372,7 @@
void _addClassConstructorFieldFormals(ClassElement class_) {
for (var constructor in class_.constructors) {
+ constructor as ConstructorElementImpl;
var inferenceNode = _ConstructorInferenceNode(_walker, constructor);
_walker._nodes[constructor] = inferenceNode;
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 768ae62..24b3c13 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -24,7 +24,13 @@
path: ../analyzer_utilities
args: ^2.0.0
async: ^2.5.0
+ front_end:
+ path: ../front_end
+ kernel:
+ path: ../kernel
linter: ^1.12.0
matcher: ^0.12.10
test: ^1.16.0
test_reflective_loader: ^0.2.0
+ vm:
+ path: ../vm
diff --git a/pkg/analyzer/test/dart/analysis/analysis_context_test.dart b/pkg/analyzer/test/dart/analysis/analysis_context_test.dart
new file mode 100644
index 0000000..685fa7b
--- /dev/null
+++ b/pkg/analyzer/test/dart/analysis/analysis_context_test.dart
@@ -0,0 +1,74 @@
+// 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.
+
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../src/dart/resolution/context_collection_resolution.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisContextTest);
+ });
+}
+
+@reflectiveTest
+class AnalysisContextTest extends PubPackageResolutionTest {
+ test_changeFile_imported() async {
+ var a = newFile2('$testPackageLibPath/a.dart', '');
+
+ var b = newFile2('$testPackageLibPath/b.dart', r'''
+import 'a.dart';
+''');
+
+ var c = newFile2('$testPackageLibPath/c.dart', '');
+
+ var analysisContext = contextFor(a.path);
+
+ // Ask for files, so that they are known.
+ var analysisSession = analysisContext.currentSession;
+ await analysisSession.getFile2(a.path);
+ await analysisSession.getFile2(b.path);
+ await analysisSession.getFile2(c.path);
+
+ analysisContext.changeFile(a.path);
+
+ var affected = await analysisContext.applyPendingFileChanges();
+ expect(affected, unorderedEquals([a.path, b.path]));
+
+ expect(analysisContext.currentSession, isNot(analysisSession));
+ }
+
+ test_changeFile_part() async {
+ var a = newFile2('$testPackageLibPath/a.dart', r'''
+part 'b.dart';
+''');
+
+ var b = newFile2('$testPackageLibPath/b.dart', r'''
+part of 'a.dart';
+''');
+
+ var c = newFile2('$testPackageLibPath/c.dart', r'''
+import 'a.dart';
+''');
+
+ var d = newFile2('$testPackageLibPath/d.dart', '');
+
+ var analysisContext = contextFor(a.path);
+
+ // Ask for files, so that they are known.
+ var analysisSession = analysisContext.currentSession;
+ await analysisSession.getFile2(a.path);
+ await analysisSession.getFile2(b.path);
+ await analysisSession.getFile2(c.path);
+ await analysisSession.getFile2(d.path);
+
+ analysisContext.changeFile(b.path);
+
+ var affected = await analysisContext.applyPendingFileChanges();
+ expect(affected, unorderedEquals([a.path, b.path, c.path]));
+
+ expect(analysisContext.currentSession, isNot(analysisSession));
+ }
+}
diff --git a/pkg/analyzer/test/dart/analysis/test_all.dart b/pkg/analyzer/test/dart/analysis/test_all.dart
index 40e2965..13113c5 100644
--- a/pkg/analyzer/test/dart/analysis/test_all.dart
+++ b/pkg/analyzer/test/dart/analysis/test_all.dart
@@ -4,11 +4,13 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'analysis_context_test.dart' as analysis_context;
import 'from_environment_evaluator_test.dart' as declared_variables;
import 'utilities_test.dart' as utilities;
void main() {
defineReflectiveSuite(() {
+ analysis_context.main();
declared_variables.main();
utilities.main();
}, name: 'analysis');
diff --git a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
index 45f9fd3..5b9d9a4 100644
--- a/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/context_collection_resolution.dart
@@ -12,6 +12,7 @@
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/test_utilities/mock_packages.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
@@ -26,6 +27,7 @@
import 'package:test/test.dart';
import '../../../generated/test_support.dart';
+import '../../summary/repository_macro_kernel_builder.dart';
import 'context_collection_resolution_caching.dart';
import 'resolution.dart';
@@ -139,6 +141,8 @@
_declaredVariables = map;
}
+ MacroKernelBuilder? get macroKernelBuilder => null;
+
bool get retainDataForTesting => false;
Folder get sdkRoot => newFolder('/sdk');
@@ -246,6 +250,7 @@
retainDataForTesting: retainDataForTesting,
sdkPath: sdkRoot.path,
updateAnalysisOptions: updateAnalysisOptions,
+ macroKernelBuilder: macroKernelBuilder,
);
verifyCreatedCollection();
@@ -321,6 +326,7 @@
bool ffi = false,
bool js = false,
bool meta = false,
+ MacrosEnvironment? macrosEnvironment,
}) {
config = config.copy();
@@ -354,6 +360,15 @@
config.add(name: 'meta', rootPath: metaPath);
}
+ if (macrosEnvironment != null) {
+ var packagesRootFolder = getFolder(packagesRootPath);
+ macrosEnvironment.packageSharedFolder.copyTo(packagesRootFolder);
+ config.add(
+ name: '_fe_analyzer_shared',
+ rootPath: getFolder('$packagesRootPath/_fe_analyzer_shared').path,
+ );
+ }
+
var path = '$testPackageRootPath/.dart_tool/package_config.json';
writePackageConfig(path, config);
}
diff --git a/pkg/analyzer/test/src/dart/resolution/macro_test.dart b/pkg/analyzer/test/src/dart/resolution/macro_test.dart
new file mode 100644
index 0000000..2b41573
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/macro_test.dart
@@ -0,0 +1,54 @@
+// 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.
+
+import 'package:analyzer/src/summary2/macro.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../summary/repository_macro_kernel_builder.dart';
+import 'context_collection_resolution.dart';
+
+main() {
+ try {
+ MacrosEnvironment.instance;
+ } catch (_) {
+ print('Cannot initialize environment. Skip macros tests.');
+ return;
+ }
+
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MacroResolutionTest);
+ });
+}
+
+@reflectiveTest
+class MacroResolutionTest extends PubPackageResolutionTest {
+ @override
+ MacroKernelBuilder? get macroKernelBuilder {
+ return DartRepositoryMacroKernelBuilder(
+ MacrosEnvironment.instance.platformDillBytes,
+ );
+ }
+
+ @override
+ void setUp() {
+ super.setUp();
+
+ writeTestPackageConfig(
+ PackageConfigFileBuilder(),
+ macrosEnvironment: MacrosEnvironment.instance,
+ );
+ }
+
+ test_0() async {
+ await assertNoErrorsInCode(r'''
+import 'dart:async';
+import 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+macro class EmptyMacro implements ClassTypesMacro {
+ const EmptyMacro();
+ FutureOr<void> buildTypesForClass(clazz, builder) {}
+}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 079b416..eb4521e 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -44,6 +44,7 @@
import 'library_element_test.dart' as library_element;
import 'local_function_test.dart' as local_function;
import 'local_variable_test.dart' as local_variable;
+import 'macro_test.dart' as macro;
import 'metadata_test.dart' as metadata;
import 'method_declaration_test.dart' as method_declaration;
import 'method_invocation_test.dart' as method_invocation;
@@ -108,6 +109,7 @@
library_element.main();
local_function.main();
local_variable.main();
+ macro.main();
metadata.main();
method_declaration.main();
method_invocation.main();
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
index af72941..67cdfa0 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
@@ -315,6 +315,34 @@
]);
}
+ test_superFormalParameter_explicit() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ const A({int a = 0});
+}
+
+class B extends A {
+ static const f = B();
+
+ const B({super.a = 2});
+}
+''');
+ }
+
+ test_superFormalParameter_inherited() async {
+ await assertNoErrorsInCode(r'''
+class A {
+ const A({int a = 0});
+}
+
+class B extends A {
+ static const f = B();
+
+ const B({super.a});
+}
+''');
+ }
+
test_unknown_conditionalExpression_unknownCondition() async {
await assertNoErrorsInCode(r'''
const bool kIsWeb = identical(0, 0.0);
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index f96b17d..09c0acc 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -1760,6 +1760,53 @@
''');
}
+ test_class_constructor_parameters_super_requiredPositional_inferenceOrder() async {
+ // It is important that `C` is declared after `B`, so that we check that
+ // inference happens in order - first `C`, then `B`.
+ var library = await buildLibrary('''
+abstract class A {
+ A(int a);
+}
+
+class B extends C {
+ B(super.a);
+}
+
+class C extends A {
+ C(super.a);
+}
+''');
+ checkElementText(library, r'''
+library
+ definingUnit
+ classes
+ abstract class A @15
+ constructors
+ @21
+ parameters
+ requiredPositional a @27
+ type: int
+ class B @40
+ supertype: C
+ constructors
+ @56
+ parameters
+ requiredPositional final super.a @64
+ type: int
+ superConstructorParameter: a@101
+ superConstructor: self::@class::C::@constructor::•
+ class C @77
+ supertype: A
+ constructors
+ @93
+ parameters
+ requiredPositional final super.a @101
+ type: int
+ superConstructorParameter: a@27
+ superConstructor: self::@class::A::@constructor::•
+''');
+ }
+
test_class_constructor_parameters_super_requiredPositional_unresolved() async {
var library = await buildLibrary('''
class A {}
diff --git a/pkg/analyzer/test/src/summary/repository_macro_kernel_builder.dart b/pkg/analyzer/test/src/summary/repository_macro_kernel_builder.dart
new file mode 100644
index 0000000..2d0b635
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/repository_macro_kernel_builder.dart
@@ -0,0 +1,210 @@
+// 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.
+
+// ignore: deprecated_member_use
+import 'dart:cli' as cli;
+import 'dart:convert';
+import 'dart:io' as io;
+import 'dart:typed_data';
+
+import 'package:_fe_analyzer_shared/src/macros/bootstrap.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor/serialization.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/summary2/macro.dart';
+import 'package:analyzer/src/util/uri.dart';
+import 'package:analyzer_utilities/package_root.dart' as package_root;
+import 'package:front_end/src/api_prototype/compiler_options.dart' as fe;
+import 'package:front_end/src/api_prototype/file_system.dart' as fe;
+import 'package:front_end/src/fasta/kernel/utils.dart' as fe;
+import 'package:kernel/target/targets.dart' as fe;
+import 'package:path/path.dart' as package_path;
+import 'package:vm/kernel_front_end.dart' as fe;
+import 'package:vm/target/vm.dart' as fe;
+
+final Uri _platformDillUri = Uri.parse('org-dartlang-sdk://vm.dill');
+
+/// Implementation of [MacroKernelBuilder] that can run in Dart SDK repository.
+///
+/// This is a temporary implementation, to be replaced with a more stable
+/// approach, e.g. a `dart:` API for compilation, shipping `front_end`
+/// with SDK, etc.
+class DartRepositoryMacroKernelBuilder implements MacroKernelBuilder {
+ final Uint8List platformDillBytes;
+
+ DartRepositoryMacroKernelBuilder(this.platformDillBytes);
+
+ @override
+ Uint8List build({
+ required MacroFileSystem fileSystem,
+ required List<MacroLibrary> libraries,
+ }) {
+ var options = fe.CompilerOptions()
+ ..sdkSummary = _platformDillUri
+ ..target = fe.VmTarget(fe.TargetFlags(enableNullSafety: true));
+
+ var macroMainContent = bootstrapMacroIsolate(
+ {
+ for (var library in libraries)
+ library.uri.toString(): {
+ for (var c in library.classes) c.name: c.constructors
+ },
+ },
+ SerializationMode.byteDataClient,
+ );
+
+ var macroMainBytes = utf8.encode(macroMainContent) as Uint8List;
+ var macroMainPath = libraries.first.path + '.macro';
+ var macroMainUri = fileSystem.pathContext.toUri(macroMainPath);
+
+ options
+ ..fileSystem = _FileSystem(
+ fileSystem,
+ platformDillBytes,
+ macroMainUri,
+ macroMainBytes,
+ );
+
+ // TODO(scheglov) For now we convert async into sync.
+ // ignore: deprecated_member_use
+ var compilationResults = cli.waitFor(
+ fe.compileToKernel(
+ macroMainUri,
+ options,
+ environmentDefines: {},
+ ),
+ );
+
+ return fe.serializeComponent(
+ compilationResults.component!,
+ filter: (library) {
+ return !library.importUri.isScheme('dart');
+ },
+ includeSources: false,
+ );
+ }
+}
+
+/// Environment for compiling macros to kernels, expecting that we run
+/// a test in the Dart SDK repository.
+///
+/// Just like [DartRepositoryMacroKernelBuilder], this is a temporary
+/// implementation.
+class MacrosEnvironment {
+ static late final instance = MacrosEnvironment._();
+
+ final _resourceProvider = MemoryResourceProvider(context: package_path.posix);
+ late final Uint8List platformDillBytes;
+
+ MacrosEnvironment._() {
+ var physical = PhysicalResourceProvider.INSTANCE;
+
+ var packageRoot = physical.pathContext.normalize(package_root.packageRoot);
+ physical
+ .getFolder(packageRoot)
+ .getChildAssumingFolder('_fe_analyzer_shared/lib/src/macros')
+ .copyTo(
+ packageSharedFolder.getChildAssumingFolder('lib/src'),
+ );
+
+ platformDillBytes = physical
+ .getFile(io.Platform.resolvedExecutable)
+ .parent
+ .parent
+ .getChildAssumingFolder('lib')
+ .getChildAssumingFolder('_internal')
+ .getChildAssumingFile('vm_platform_strong.dill')
+ .readAsBytesSync();
+ }
+
+ Folder get packageSharedFolder {
+ return _resourceProvider.getFolder('/packages/_fe_analyzer_shared');
+ }
+}
+
+class _BytesFileSystemEntity implements fe.FileSystemEntity {
+ @override
+ final Uri uri;
+
+ final Uint8List bytes;
+
+ _BytesFileSystemEntity(this.uri, this.bytes);
+
+ @override
+ Future<bool> exists() async => true;
+
+ @override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
+ Future<List<int>> readAsBytes() async => bytes;
+
+ @override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
+ Future<String> readAsString() async {
+ var bytes = await readAsBytes();
+ return utf8.decode(bytes);
+ }
+}
+
+class _FileSystem implements fe.FileSystem {
+ final MacroFileSystem fileSystem;
+ final Uint8List platformDillBytes;
+ final Uri macroMainUri;
+ final Uint8List macroMainBytes;
+
+ _FileSystem(
+ this.fileSystem,
+ this.platformDillBytes,
+ this.macroMainUri,
+ this.macroMainBytes,
+ );
+
+ @override
+ fe.FileSystemEntity entityForUri(Uri uri) {
+ if (uri == _platformDillUri) {
+ return _BytesFileSystemEntity(uri, platformDillBytes);
+ } else if (uri == macroMainUri) {
+ return _BytesFileSystemEntity(uri, macroMainBytes);
+ } else if (uri.isScheme('file')) {
+ var path = fileUriToNormalizedPath(fileSystem.pathContext, uri);
+ return _FileSystemEntity(
+ uri,
+ fileSystem.getFile(path),
+ );
+ } else {
+ throw fe.FileSystemException(uri, 'Only supports file: URIs');
+ }
+ }
+}
+
+class _FileSystemEntity implements fe.FileSystemEntity {
+ @override
+ final Uri uri;
+
+ final MacroFileEntry file;
+
+ _FileSystemEntity(this.uri, this.file);
+
+ @override
+ Future<bool> exists() async => file.exists;
+
+ @override
+ Future<bool> existsAsyncIfPossible() => exists();
+
+ @override
+ Future<List<int>> readAsBytes() async {
+ var string = await readAsString();
+ return utf8.encode(string);
+ }
+
+ @override
+ Future<List<int>> readAsBytesAsyncIfPossible() => readAsBytes();
+
+ @override
+ Future<String> readAsString() async => file.content;
+}
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart
index 644f54d..7efa925 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart
@@ -216,7 +216,6 @@
enum E2 with M {
v1, v2, id_string;
- int get index => 10;
}
mixin M on Enum {
@@ -297,7 +296,7 @@
await driver.check(
breakpointId: 'bp',
expression: 'E2.v2.mixinMethod()',
- expectedResult: '1000');
+ expectedResult: '100');
});
});
}
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.expect b/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.expect
index 4f4319e..95a7fb9 100644
--- a/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.expect
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.expect
@@ -3,7 +3,9 @@
import self as self;
import "dart:core" as core;
+@#C1
import "org-dartlang-testcase:///redirecting_factory_invocation_metadata.dart" as self;
+@#C1
export "org-dartlang-testcase:///redirecting_factory_invocation_metadata.dart";
@#C1
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.modular.expect b/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.modular.expect
index 4f4319e..95a7fb9 100644
--- a/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.modular.expect
@@ -3,7 +3,9 @@
import self as self;
import "dart:core" as core;
+@#C1
import "org-dartlang-testcase:///redirecting_factory_invocation_metadata.dart" as self;
+@#C1
export "org-dartlang-testcase:///redirecting_factory_invocation_metadata.dart";
@#C1
diff --git a/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.transformed.expect b/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.transformed.expect
index 4f4319e..95a7fb9 100644
--- a/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/redirecting_factory_invocation_metadata.dart.weak.transformed.expect
@@ -3,7 +3,9 @@
import self as self;
import "dart:core" as core;
+@#C1
import "org-dartlang-testcase:///redirecting_factory_invocation_metadata.dart" as self;
+@#C1
export "org-dartlang-testcase:///redirecting_factory_invocation_metadata.dart";
@#C1
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart b/pkg/front_end/testcases/macros/multiple_imports.dart
new file mode 100644
index 0000000..71e46d3
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart
@@ -0,0 +1,13 @@
+// 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.
+
+@Const(2)
+import 'dart:async';
+
+@Const(3)
+import augment 'multiple_imports_lib.dart';
+
+FutureOr<void> main() {
+ method();
+}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.expect
new file mode 100644
index 0000000..bb8a142
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.expect
@@ -0,0 +1,47 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+import "dart:convert" as con;
+
+@#C2
+@#C4
+import "dart:math";
+@#C6
+@#C8
+import "dart:convert";
+import "dart:async";
+import "org-dartlang-testcase:///multiple_imports.dart";
+
+class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart
+ final field core::int field;
+ const constructor •(core::int field) → self::Const
+ : self::Const::field = field, super core::Object::•()
+ ;
+}
+static method main() → FutureOr<void> {
+ self::method();
+}
+static method /* from org-dartlang-testcase:///multiple_imports_lib.dart */ method() → dynamic {
+ math::Random::•();
+ #C10.{con::JsonCodec::encoder}{con::JsonEncoder};
+}
+
+constants {
+ #C1 = 0
+ #C2 = self::Const {field:#C1}
+ #C3 = 2
+ #C4 = self::Const {field:#C3}
+ #C5 = 1
+ #C6 = self::Const {field:#C5}
+ #C7 = 3
+ #C8 = self::Const {field:#C7}
+ #C9 = null
+ #C10 = con::JsonCodec {_reviver:#C9, _toEncodable:#C9}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///multiple_imports.dart:
+- Const. (from org-dartlang-testcase:///multiple_imports_lib.dart:18:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.transformed.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.transformed.expect
new file mode 100644
index 0000000..bb8a142
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.transformed.expect
@@ -0,0 +1,47 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+import "dart:convert" as con;
+
+@#C2
+@#C4
+import "dart:math";
+@#C6
+@#C8
+import "dart:convert";
+import "dart:async";
+import "org-dartlang-testcase:///multiple_imports.dart";
+
+class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart
+ final field core::int field;
+ const constructor •(core::int field) → self::Const
+ : self::Const::field = field, super core::Object::•()
+ ;
+}
+static method main() → FutureOr<void> {
+ self::method();
+}
+static method /* from org-dartlang-testcase:///multiple_imports_lib.dart */ method() → dynamic {
+ math::Random::•();
+ #C10.{con::JsonCodec::encoder}{con::JsonEncoder};
+}
+
+constants {
+ #C1 = 0
+ #C2 = self::Const {field:#C1}
+ #C3 = 2
+ #C4 = self::Const {field:#C3}
+ #C5 = 1
+ #C6 = self::Const {field:#C5}
+ #C7 = 3
+ #C8 = self::Const {field:#C7}
+ #C9 = null
+ #C10 = con::JsonCodec {_reviver:#C9, _toEncodable:#C9}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///multiple_imports.dart:
+- Const. (from org-dartlang-testcase:///multiple_imports_lib.dart:18:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.textual_outline.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.textual_outline.expect
new file mode 100644
index 0000000..bc18faf
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+@Const(2)
+import 'dart:async';
+@Const(3)
+import augment 'multiple_imports_lib.dart';
+FutureOr<void> main() {}
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.weak.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.expect
new file mode 100644
index 0000000..bb8a142
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.expect
@@ -0,0 +1,47 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+import "dart:convert" as con;
+
+@#C2
+@#C4
+import "dart:math";
+@#C6
+@#C8
+import "dart:convert";
+import "dart:async";
+import "org-dartlang-testcase:///multiple_imports.dart";
+
+class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart
+ final field core::int field;
+ const constructor •(core::int field) → self::Const
+ : self::Const::field = field, super core::Object::•()
+ ;
+}
+static method main() → FutureOr<void> {
+ self::method();
+}
+static method /* from org-dartlang-testcase:///multiple_imports_lib.dart */ method() → dynamic {
+ math::Random::•();
+ #C10.{con::JsonCodec::encoder}{con::JsonEncoder};
+}
+
+constants {
+ #C1 = 0
+ #C2 = self::Const {field:#C1}
+ #C3 = 2
+ #C4 = self::Const {field:#C3}
+ #C5 = 1
+ #C6 = self::Const {field:#C5}
+ #C7 = 3
+ #C8 = self::Const {field:#C7}
+ #C9 = null
+ #C10 = con::JsonCodec {_reviver:#C9, _toEncodable:#C9}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///multiple_imports.dart:
+- Const. (from org-dartlang-testcase:///multiple_imports_lib.dart:18:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.weak.modular.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.modular.expect
new file mode 100644
index 0000000..bb8a142
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.modular.expect
@@ -0,0 +1,47 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+import "dart:convert" as con;
+
+@#C2
+@#C4
+import "dart:math";
+@#C6
+@#C8
+import "dart:convert";
+import "dart:async";
+import "org-dartlang-testcase:///multiple_imports.dart";
+
+class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart
+ final field core::int field;
+ const constructor •(core::int field) → self::Const
+ : self::Const::field = field, super core::Object::•()
+ ;
+}
+static method main() → FutureOr<void> {
+ self::method();
+}
+static method /* from org-dartlang-testcase:///multiple_imports_lib.dart */ method() → dynamic {
+ math::Random::•();
+ #C10.{con::JsonCodec::encoder}{con::JsonEncoder};
+}
+
+constants {
+ #C1 = 0
+ #C2 = self::Const {field:#C1}
+ #C3 = 2
+ #C4 = self::Const {field:#C3}
+ #C5 = 1
+ #C6 = self::Const {field:#C5}
+ #C7 = 3
+ #C8 = self::Const {field:#C7}
+ #C9 = null
+ #C10 = con::JsonCodec {_reviver:#C9, _toEncodable:#C9}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///multiple_imports.dart:
+- Const. (from org-dartlang-testcase:///multiple_imports_lib.dart:18:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.weak.outline.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.outline.expect
new file mode 100644
index 0000000..bdcb1f0
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.outline.expect
@@ -0,0 +1,19 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "dart:math";
+import "dart:convert";
+import "dart:async";
+import "org-dartlang-testcase:///multiple_imports.dart";
+
+class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart
+ final field core::int field;
+ const constructor •(core::int field) → self::Const
+ : self::Const::field = field, super core::Object::•()
+ ;
+}
+static method main() → FutureOr<void>
+ ;
+static method /* from org-dartlang-testcase:///multiple_imports_lib.dart */ method() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.weak.transformed.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.transformed.expect
new file mode 100644
index 0000000..bb8a142
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports.dart.weak.transformed.expect
@@ -0,0 +1,47 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+import "dart:convert" as con;
+
+@#C2
+@#C4
+import "dart:math";
+@#C6
+@#C8
+import "dart:convert";
+import "dart:async";
+import "org-dartlang-testcase:///multiple_imports.dart";
+
+class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart
+ final field core::int field;
+ const constructor •(core::int field) → self::Const
+ : self::Const::field = field, super core::Object::•()
+ ;
+}
+static method main() → FutureOr<void> {
+ self::method();
+}
+static method /* from org-dartlang-testcase:///multiple_imports_lib.dart */ method() → dynamic {
+ math::Random::•();
+ #C10.{con::JsonCodec::encoder}{con::JsonEncoder};
+}
+
+constants {
+ #C1 = 0
+ #C2 = self::Const {field:#C1}
+ #C3 = 2
+ #C4 = self::Const {field:#C3}
+ #C5 = 1
+ #C6 = self::Const {field:#C5}
+ #C7 = 3
+ #C8 = self::Const {field:#C7}
+ #C9 = null
+ #C10 = con::JsonCodec {_reviver:#C9, _toEncodable:#C9}
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///multiple_imports.dart:
+- Const. (from org-dartlang-testcase:///multiple_imports_lib.dart:18:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/macros/multiple_imports_lib.dart b/pkg/front_end/testcases/macros/multiple_imports_lib.dart
new file mode 100644
index 0000000..80db5fc
--- /dev/null
+++ b/pkg/front_end/testcases/macros/multiple_imports_lib.dart
@@ -0,0 +1,19 @@
+// 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.
+
+@Const(0)
+import 'dart:math';
+@Const(1)
+import 'dart:convert';
+
+method() {
+ new Random();
+ json.encoder;
+}
+
+class Const {
+ final int field;
+
+ const Const(this.field);
+}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 7c5d010..900255e 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -153,6 +153,7 @@
macros/class_members: FormatterCrash
macros/inject_constructor: FormatterCrash
macros/macro_class: FormatterCrash
+macros/multiple_imports: FormatterCrash
nnbd/abstract_field_errors: FormatterCrash
nnbd/covariant_late_field: FormatterCrash
nnbd/duplicates_instance: FormatterCrash
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 7f0ce5d..dafccc6 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1989,6 +1989,7 @@
@override
void visitLibraryDependency(LibraryDependency node) {
+ writeAnnotationList(node.annotations);
writeIndentation();
writeWord(node.isImport ? 'import' : 'export');
String uriString;
diff --git a/pkg/smith/lib/configuration.dart b/pkg/smith/lib/configuration.dart
index 9284ec3..3202bf6 100644
--- a/pkg/smith/lib/configuration.dart
+++ b/pkg/smith/lib/configuration.dart
@@ -577,11 +577,9 @@
static const x64c = Architecture._('x64c');
static const arm = Architecture._('arm');
static const arm_x64 = Architecture._('arm_x64');
- static const armv6 = Architecture._('armv6');
static const arm64 = Architecture._('arm64');
static const arm64c = Architecture._('arm64c');
static const simarm = Architecture._('simarm');
- static const simarmv6 = Architecture._('simarmv6');
static const simarm64 = Architecture._('simarm64');
static const simarm64c = Architecture._('simarm64c');
static const riscv32 = Architecture._('riscv32');
@@ -596,12 +594,10 @@
x64,
x64c,
arm,
- armv6,
arm_x64,
arm64,
arm64c,
simarm,
- simarmv6,
simarm64,
simarm64c,
riscv32,
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index 4cba518..fdaa061 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -257,8 +257,6 @@
case Architecture.arm_x64:
case Architecture.arm64:
case Architecture.arm64c:
- case Architecture.simarmv6:
- case Architecture.armv6:
case Architecture.simarm64:
case Architecture.simarm64c:
case Architecture.simriscv32:
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 1212928..0f08859 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -2298,17 +2298,23 @@
}
void Assembler::PushRegisters(const RegisterSet& regs) {
- const intptr_t fpu_regs_count = regs.FpuRegisterCount();
- if (fpu_regs_count > 0) {
- // Store fpu registers with the lowest register number at the lowest
- // address.
- for (intptr_t i = kNumberOfVRegisters - 1; i >= 0; --i) {
- VRegister fpu_reg = static_cast<VRegister>(i);
- if (regs.ContainsFpuRegister(fpu_reg)) {
- PushQuad(fpu_reg);
+ VRegister vprev = kNoVRegister;
+ // Store fpu registers with the lowest register number at the lowest
+ // address.
+ for (intptr_t i = kNumberOfVRegisters - 1; i >= 0; --i) {
+ VRegister fpu_reg = static_cast<VRegister>(i);
+ if (regs.ContainsFpuRegister(fpu_reg)) {
+ if (vprev != kNoVRegister) {
+ PushQuadPair(/*low=*/fpu_reg, /*high=*/vprev);
+ vprev = kNoVRegister;
+ } else {
+ vprev = fpu_reg;
}
}
}
+ if (vprev != kNoVRegister) {
+ PushQuad(vprev);
+ }
// The order in which the registers are pushed must match the order
// in which the registers are encoded in the safe point's stack map.
@@ -2350,50 +2356,98 @@
}
ASSERT(prev == kNoRegister);
- const intptr_t fpu_regs_count = regs.FpuRegisterCount();
- if (fpu_regs_count > 0) {
- // Fpu registers have the lowest register number at the lowest address.
- for (intptr_t i = 0; i < kNumberOfVRegisters; ++i) {
- VRegister fpu_reg = static_cast<VRegister>(i);
- if (regs.ContainsFpuRegister(fpu_reg)) {
+ pop_single = (regs.FpuRegisterCount() & 1) == 1;
+ VRegister vprev = kNoVRegister;
+ // Fpu registers have the lowest register number at the lowest address.
+ for (intptr_t i = 0; i < kNumberOfVRegisters; ++i) {
+ VRegister fpu_reg = static_cast<VRegister>(i);
+ if (regs.ContainsFpuRegister(fpu_reg)) {
+ if (pop_single) {
PopQuad(fpu_reg);
+ pop_single = false;
+ } else if (vprev != kNoVRegister) {
+ PopQuadPair(/*low=*/vprev, /*high=*/fpu_reg);
+ vprev = kNoVRegister;
+ } else {
+ vprev = fpu_reg;
}
}
}
+ ASSERT(vprev == kNoVRegister);
}
void Assembler::PushNativeCalleeSavedRegisters() {
// Save the callee-saved registers.
+ // We use str instead of the Push macro because we will be pushing the PP
+ // register when it is not holding a pool-pointer since we are coming from
+ // C++ code.
+ Register prev = kNoRegister;
for (int i = kAbiFirstPreservedCpuReg; i <= kAbiLastPreservedCpuReg; i++) {
const Register r = static_cast<Register>(i);
- // We use str instead of the Push macro because we will be pushing the PP
- // register when it is not holding a pool-pointer since we are coming from
- // C++ code.
- str(r, Address(SP, -1 * target::kWordSize, Address::PreIndex));
+ if (prev != kNoRegister) {
+ stp(/*low=*/r, /*high=*/prev,
+ Address(SP, -2 * target::kWordSize, Address::PairPreIndex));
+ prev = kNoRegister;
+ } else {
+ prev = r;
+ }
+ }
+ if (prev != kNoRegister) {
+ str(prev, Address(SP, -1 * target::kWordSize, Address::PreIndex));
}
// Save the bottom 64-bits of callee-saved V registers.
+ VRegister vprev = kNoVRegister;
for (int i = kAbiFirstPreservedFpuReg; i <= kAbiLastPreservedFpuReg; i++) {
const VRegister r = static_cast<VRegister>(i);
- PushDouble(r);
+ if (vprev != kNoVRegister) {
+ PushDoublePair(/*low=*/r, /*high=*/vprev);
+ vprev = kNoVRegister;
+ } else {
+ vprev = r;
+ }
+ }
+ if (vprev != kNoVRegister) {
+ PushDouble(vprev);
}
}
void Assembler::PopNativeCalleeSavedRegisters() {
// Restore the bottom 64-bits of callee-saved V registers.
+ bool pop_single = (kAbiPreservedCpuRegCount & 1) == 1;
+ VRegister vprev = kNoVRegister;
for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
const VRegister r = static_cast<VRegister>(i);
- PopDouble(r);
+ if (pop_single) {
+ PopDouble(r);
+ pop_single = false;
+ } else if (vprev != kNoVRegister) {
+ PopDoublePair(/*low=*/vprev, /*high=*/r);
+ vprev = kNoVRegister;
+ } else {
+ vprev = r;
+ }
}
// Restore C++ ABI callee-saved registers.
+ // We use ldr instead of the Pop macro because we will be popping the PP
+ // register when it is not holding a pool-pointer since we are returning to
+ // C++ code. We also skip the dart stack pointer SP, since we are still
+ // using it as the stack pointer.
+ pop_single = (kAbiPreservedCpuRegCount & 1) == 1;
+ Register prev = kNoRegister;
for (int i = kAbiLastPreservedCpuReg; i >= kAbiFirstPreservedCpuReg; i--) {
Register r = static_cast<Register>(i);
- // We use ldr instead of the Pop macro because we will be popping the PP
- // register when it is not holding a pool-pointer since we are returning to
- // C++ code. We also skip the dart stack pointer SP, since we are still
- // using it as the stack pointer.
- ldr(r, Address(SP, 1 * target::kWordSize, Address::PostIndex));
+ if (pop_single) {
+ ldr(r, Address(SP, 1 * target::kWordSize, Address::PostIndex));
+ pop_single = false;
+ } else if (prev != kNoRegister) {
+ ldp(/*low=*/prev, /*high=*/r,
+ Address(SP, 2 * target::kWordSize, Address::PairPostIndex));
+ prev = kNoRegister;
+ } else {
+ prev = r;
+ }
}
}
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index a1126ec..812ff3f 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1129,6 +1129,18 @@
(a.type() == Address::PairPreIndex));
EmitLoadStoreRegPair(STP, rt, rt2, a, sz);
}
+ void fldp(VRegister rt, VRegister rt2, Address a, OperandSize sz) {
+ ASSERT((a.type() == Address::PairOffset) ||
+ (a.type() == Address::PairPostIndex) ||
+ (a.type() == Address::PairPreIndex));
+ EmitLoadStoreVRegPair(FLDP, rt, rt2, a, sz);
+ }
+ void fstp(VRegister rt, VRegister rt2, Address a, OperandSize sz) {
+ ASSERT((a.type() == Address::PairOffset) ||
+ (a.type() == Address::PairPostIndex) ||
+ (a.type() == Address::PairPreIndex));
+ EmitLoadStoreVRegPair(FSTP, rt, rt2, a, sz);
+ }
void ldxr(Register rt, Register rn, OperandSize size = kEightBytes) {
// rt = value
@@ -1619,6 +1631,22 @@
void PopQuad(VRegister reg) {
fldrq(reg, Address(SP, 1 * kQuadSize, Address::PostIndex));
}
+ void PushDoublePair(VRegister low, VRegister high) {
+ fstp(low, high,
+ Address(SP, -2 * kDoubleSize, Address::PairPreIndex, kDWord), kDWord);
+ }
+ void PopDoublePair(VRegister low, VRegister high) {
+ fldp(low, high,
+ Address(SP, 2 * kDoubleSize, Address::PairPostIndex, kDWord), kDWord);
+ }
+ void PushQuadPair(VRegister low, VRegister high) {
+ fstp(low, high, Address(SP, -2 * kQuadSize, Address::PairPreIndex, kQWord),
+ kQWord);
+ }
+ void PopQuadPair(VRegister low, VRegister high) {
+ fldp(low, high, Address(SP, 2 * kQuadSize, Address::PairPostIndex, kQWord),
+ kQWord);
+ }
void TagAndPushPP() {
// Add the heap object tag back to PP before putting it on the stack.
add(TMP, PP, Operand(kHeapObjectTag));
@@ -2744,6 +2772,35 @@
Emit(encoding);
}
+ void EmitLoadStoreVRegPair(LoadStoreRegPairOp op,
+ VRegister rt,
+ VRegister rt2,
+ Address a,
+ OperandSize sz) {
+ ASSERT(op != FLDP || rt != rt2);
+ ASSERT((sz == kSWord) || (sz == kDWord) || (sz == kQWord));
+ ASSERT(a.log2sz_ == -1 || a.log2sz_ == Log2OperandSizeBytes(sz));
+ int32_t opc = 0;
+ switch (sz) {
+ case kSWord:
+ opc = 0;
+ break;
+ case kDWord:
+ opc = B30;
+ break;
+ case kQWord:
+ opc = B31;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ const int32_t encoding =
+ opc | op | Arm64Encode::Rt(static_cast<Register>(rt)) |
+ Arm64Encode::Rt2(static_cast<Register>(rt2)) | a.encoding();
+ Emit(encoding);
+ }
+
void EmitPCRelOp(PCRelOp op, Register rd, const Immediate& imm) {
ASSERT(Utils::IsInt(21, imm.value()));
ASSERT((rd != R31) && (rd != CSP));
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index 4c40284..cb29a3c 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -861,6 +861,70 @@
"ret\n");
}
+ASSEMBLER_TEST_GENERATE(LoadStoreDoublePair, assembler) {
+ __ SetupDartSP();
+ __ LoadDImmediate(V1, 3.0);
+ __ LoadDImmediate(V2, 4.0);
+ __ PushDoublePair(V1, V2);
+ __ LoadDImmediate(V1, 0.0);
+ __ LoadDImmediate(V2, 0.0);
+ __ PopDoublePair(V1, V2);
+ __ fsubd(V0, V2, V1);
+ __ RestoreCSP();
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(LoadStoreDoublePair, test) {
+ typedef double (*DoubleReturn)() DART_UNUSED;
+ EXPECT_EQ(1.0, EXECUTE_TEST_CODE_DOUBLE(DoubleReturn, test->entry()));
+ EXPECT_DISASSEMBLY(
+ "mov sp, csp\n"
+ "sub csp, csp, #0x1000\n"
+ "fmovd v1, 3.000000\n"
+ "fmovd v2, 4.000000\n"
+ "fstpd v1, v2, [sp, #-16]!\n"
+ "movz tmp, #0x0\n"
+ "fmovdr v1, tmp\n"
+ "movz tmp, #0x0\n"
+ "fmovdr v2, tmp\n"
+ "fldpd v1, v2, [sp], #16 !\n"
+ "fsubd v0, v2, v1\n"
+ "mov csp, sp\n"
+ "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(LoadStoreQuadPair, assembler) {
+ __ SetupDartSP();
+ __ LoadDImmediate(V1, 3.0);
+ __ LoadDImmediate(V2, 4.0);
+ __ PushQuadPair(V1, V2);
+ __ LoadDImmediate(V1, 0.0);
+ __ LoadDImmediate(V2, 0.0);
+ __ PopQuadPair(V1, V2);
+ __ fsubd(V0, V2, V1);
+ __ RestoreCSP();
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(LoadStoreQuadPair, test) {
+ typedef double (*DoubleReturn)() DART_UNUSED;
+ EXPECT_EQ(1.0, EXECUTE_TEST_CODE_DOUBLE(DoubleReturn, test->entry()));
+ EXPECT_DISASSEMBLY(
+ "mov sp, csp\n"
+ "sub csp, csp, #0x1000\n"
+ "fmovd v1, 3.000000\n"
+ "fmovd v2, 4.000000\n"
+ "fstpq v1, v2, [sp, #-32]!\n"
+ "movz tmp, #0x0\n"
+ "fmovdr v1, tmp\n"
+ "movz tmp, #0x0\n"
+ "fmovdr v2, tmp\n"
+ "fldpq v1, v2, [sp], #32 !\n"
+ "fsubd v0, v2, v1\n"
+ "mov csp, sp\n"
+ "ret\n");
+}
+
ASSEMBLER_TEST_GENERATE(Semaphore, assembler) {
__ SetupDartSP();
__ movz(R0, Immediate(40), 0);
diff --git a/runtime/vm/compiler/assembler/disassembler_arm64.cc b/runtime/vm/compiler/assembler/disassembler_arm64.cc
index 490569d..e742ef7 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm64.cc
@@ -255,7 +255,9 @@
void ARM64Decoder::PrintPairMemOperand(Instr* instr) {
const Register rn = instr->RnField();
const uint32_t simm7 = instr->SImm7Field();
- const int32_t offset = simm7 << (2 + instr->Bit(31));
+ const intptr_t shift =
+ (instr->Bit(26) == 1) ? 2 + instr->SzField() : 2 + instr->SFField();
+ const int32_t offset = simm7 << shift;
Print("[");
PrintRegister(rn, R31IsSP);
switch (instr->Bits(23, 3)) {
@@ -300,6 +302,11 @@
PrintRegister(reg, R31IsZR);
return 2;
} else if (format[1] == 't') { // 'rt: Rt register
+ if (format[2] == '2') {
+ int reg = instr->Rt2Field();
+ PrintRegister(reg, R31IsZR);
+ return 3;
+ }
int reg = instr->RtField();
PrintRegister(reg, R31IsZR);
return 2;
@@ -331,6 +338,11 @@
PrintVRegister(reg);
return 2;
} else if (format[1] == 't') {
+ if (format[2] == '2') {
+ int reg = instr->Vt2Field();
+ PrintVRegister(reg);
+ return 3;
+ }
int reg = instr->VtField();
PrintVRegister(reg);
return 2;
@@ -536,6 +548,32 @@
PrintMemOperand(instr);
return 5;
}
+ case 'o': {
+ ASSERT(STRING_STARTS_WITH(format, "opc"));
+ if (instr->Bit(26) == 0) {
+ if (instr->Bit(31) == 0) {
+ Print("w");
+ } else {
+ // 64-bit width is most commonly used, no need to print "x".
+ }
+ } else {
+ switch (instr->Bits(30, 2)) {
+ case 0:
+ Print("s");
+ break;
+ case 1:
+ Print("d");
+ break;
+ case 2:
+ Print("q");
+ break;
+ case 3:
+ Print("?");
+ break;
+ }
+ }
+ return 3;
+ }
case 'p': {
if (format[1] == 'c') {
if (format[2] == 'a') {
@@ -719,12 +757,20 @@
}
void ARM64Decoder::DecodeLoadStoreRegPair(Instr* instr) {
- if (instr->Bit(22) == 1) {
- // Load.
- Format(instr, "ldp'sf 'rt, 'ra, 'pmemop");
+ if (instr->Bit(26) == 1) {
+ // SIMD or FP src/dst.
+ if (instr->Bit(22) == 1) {
+ Format(instr, "fldp'opc 'vt, 'vt2, 'pmemop");
+ } else {
+ Format(instr, "fstp'opc 'vt, 'vt2, 'pmemop");
+ }
} else {
- // Store.
- Format(instr, "stp'sf 'rt, 'ra, 'pmemop");
+ // Integer src/dst.
+ if (instr->Bit(22) == 1) {
+ Format(instr, "ldp'opc 'rt, 'rt2, 'pmemop");
+ } else {
+ Format(instr, "stp'opc 'rt, 'rt2, 'pmemop");
+ }
}
}
diff --git a/runtime/vm/compiler/stub_code_compiler.h b/runtime/vm/compiler/stub_code_compiler.h
index b1ee80e..7dd9e8f 100644
--- a/runtime/vm/compiler/stub_code_compiler.h
+++ b/runtime/vm/compiler/stub_code_compiler.h
@@ -128,9 +128,9 @@
#elif defined(TARGET_ARCH_ARM64)
static constexpr intptr_t kNativeCallbackTrampolineSize = 12;
#if defined(DART_COMPRESSED_POINTERS)
- static constexpr intptr_t kNativeCallbackSharedStubSize = 292;
+ static constexpr intptr_t kNativeCallbackSharedStubSize = 260;
#else
- static constexpr intptr_t kNativeCallbackSharedStubSize = 268;
+ static constexpr intptr_t kNativeCallbackSharedStubSize = 236;
#endif
static constexpr intptr_t kNativeCallbackTrampolineStackDelta = 2;
#elif defined(TARGET_ARCH_RISCV32)
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 8977115..0d96c71 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -719,6 +719,8 @@
LoadStoreRegPairFixed = LoadStoreFixed | B29,
STP = LoadStoreRegPairFixed,
LDP = LoadStoreRegPairFixed | B22,
+ FSTP = STP | B26,
+ FLDP = LDP | B26,
};
// C3.4.1
@@ -1061,6 +1063,8 @@
kVmBits = 5,
kVtShift = 0,
kVtBits = 5,
+ kVt2Shift = 10,
+ kVt2Bits = 5,
// Immediates.
kImm3Shift = 10,
@@ -1291,6 +1295,9 @@
inline VRegister VtField() const {
return static_cast<VRegister>(Bits(kVtShift, kVtBits));
}
+ inline VRegister Vt2Field() const {
+ return static_cast<VRegister>(Bits(kVt2Shift, kVt2Bits));
+ }
// Immediates
inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); }
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 056678d..6bb1c20 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -2113,17 +2113,16 @@
void Simulator::DecodeLoadStoreRegPair(Instr* instr) {
const int32_t opc = instr->Bits(23, 3);
const Register rn = instr->RnField();
- const Register rt = instr->RtField();
- const Register rt2 = instr->Rt2Field();
const int64_t rn_val = get_register(rn, R31IsSP);
- const intptr_t shift = 2 + instr->SFField();
+ const intptr_t shift =
+ (instr->Bit(26) == 1) ? 2 + instr->SzField() : 2 + instr->SFField();
const intptr_t size = 1 << shift;
const int32_t offset = (static_cast<uint32_t>(instr->SImm7Field()) << shift);
uword address = 0;
uword wb_address = 0;
bool wb = false;
- if ((instr->Bits(30, 2) == 3) || (instr->Bit(26) != 0)) {
+ if ((instr->Bits(30, 2) == 3)) {
UnimplementedInstruction(instr);
return;
}
@@ -2155,45 +2154,109 @@
}
// Do access.
- if (instr->Bit(22)) {
- // Format(instr, "ldp'sf 'rt, 'ra, 'memop");
- const bool signd = instr->Bit(30) == 1;
- int64_t val1 = 0; // Sign extend into an int64_t.
- int64_t val2 = 0;
- if (instr->Bit(31) == 1) {
- // 64-bit read.
- val1 = ReadX(address, instr);
- val2 = ReadX(address + size, instr);
+ if (instr->Bit(26) == 1) {
+ // SIMD/FP.
+ const VRegister vt = instr->VtField();
+ const VRegister vt2 = instr->Vt2Field();
+ if (instr->Bit(22)) {
+ // Format(instr, "ldp 'vt, 'vt2, 'memop");
+ switch (size) {
+ case 4:
+ set_vregisterd(vt, 0, static_cast<int64_t>(ReadWU(address, instr)));
+ set_vregisterd(vt, 1, 0);
+ set_vregisterd(vt2, 0,
+ static_cast<int64_t>(ReadWU(address + 4, instr)));
+ set_vregisterd(vt2, 1, 0);
+ break;
+ case 8:
+ set_vregisterd(vt, 0, ReadX(address, instr));
+ set_vregisterd(vt, 1, 0);
+ set_vregisterd(vt2, 0, ReadX(address + 8, instr));
+ set_vregisterd(vt2, 1, 0);
+ break;
+ case 16: {
+ simd_value_t val;
+ val.bits.i64[0] = ReadX(address, instr);
+ val.bits.i64[1] = ReadX(address + 8, instr);
+ set_vregister(vt, val);
+ val.bits.i64[0] = ReadX(address + 16, instr);
+ val.bits.i64[1] = ReadX(address + 24, instr);
+ set_vregister(vt2, val);
+ break;
+ }
+ default:
+ UnimplementedInstruction(instr);
+ return;
+ }
} else {
- if (signd) {
- val1 = static_cast<int64_t>(ReadW(address, instr));
- val2 = static_cast<int64_t>(ReadW(address + size, instr));
- } else {
- val1 = static_cast<int64_t>(ReadWU(address, instr));
- val2 = static_cast<int64_t>(ReadWU(address + size, instr));
+ // Format(instr, "stp 'vt, 'vt2, 'memop");
+ switch (size) {
+ case 4:
+ WriteW(address, get_vregisterd(vt, 0) & kWRegMask, instr);
+ WriteW(address + 4, get_vregisterd(vt2, 0) & kWRegMask, instr);
+ break;
+ case 8:
+ WriteX(address, get_vregisterd(vt, 0), instr);
+ WriteX(address + 8, get_vregisterd(vt2, 0), instr);
+ break;
+ case 16: {
+ simd_value_t val;
+ get_vregister(vt, &val);
+ WriteX(address, val.bits.i64[0], instr);
+ WriteX(address + 8, val.bits.i64[1], instr);
+ get_vregister(vt2, &val);
+ WriteX(address + 16, val.bits.i64[0], instr);
+ WriteX(address + 24, val.bits.i64[1], instr);
+ break;
+ }
+ default:
+ UnimplementedInstruction(instr);
+ return;
}
}
-
- // Write to register.
- if (instr->Bit(31) == 1) {
- set_register(instr, rt, val1, R31IsZR);
- set_register(instr, rt2, val2, R31IsZR);
- } else {
- set_wregister(rt, static_cast<int32_t>(val1), R31IsZR);
- set_wregister(rt2, static_cast<int32_t>(val2), R31IsZR);
- }
} else {
- // Format(instr, "stp'sf 'rt, 'ra, 'memop");
- if (instr->Bit(31) == 1) {
- const int64_t val1 = get_register(rt, R31IsZR);
- const int64_t val2 = get_register(rt2, R31IsZR);
- WriteX(address, val1, instr);
- WriteX(address + size, val2, instr);
+ // Integer.
+ const Register rt = instr->RtField();
+ const Register rt2 = instr->Rt2Field();
+ if (instr->Bit(22)) {
+ // Format(instr, "ldp'sf 'rt, 'rt2, 'memop");
+ const bool signd = instr->Bit(30) == 1;
+ int64_t val1 = 0; // Sign extend into an int64_t.
+ int64_t val2 = 0;
+ if (instr->Bit(31) == 1) {
+ // 64-bit read.
+ val1 = ReadX(address, instr);
+ val2 = ReadX(address + size, instr);
+ } else {
+ if (signd) {
+ val1 = static_cast<int64_t>(ReadW(address, instr));
+ val2 = static_cast<int64_t>(ReadW(address + size, instr));
+ } else {
+ val1 = static_cast<int64_t>(ReadWU(address, instr));
+ val2 = static_cast<int64_t>(ReadWU(address + size, instr));
+ }
+ }
+ // Write to register.
+ if (instr->Bit(31) == 1) {
+ set_register(instr, rt, val1, R31IsZR);
+ set_register(instr, rt2, val2, R31IsZR);
+ } else {
+ set_wregister(rt, static_cast<int32_t>(val1), R31IsZR);
+ set_wregister(rt2, static_cast<int32_t>(val2), R31IsZR);
+ }
} else {
- const int32_t val1 = get_wregister(rt, R31IsZR);
- const int32_t val2 = get_wregister(rt2, R31IsZR);
- WriteW(address, val1, instr);
- WriteW(address + size, val2, instr);
+ // Format(instr, "stp'sf 'rt, 'rt2, 'memop");
+ if (instr->Bit(31) == 1) {
+ const int64_t val1 = get_register(rt, R31IsZR);
+ const int64_t val2 = get_register(rt2, R31IsZR);
+ WriteX(address, val1, instr);
+ WriteX(address + size, val2, instr);
+ } else {
+ const int32_t val1 = get_wregister(rt, R31IsZR);
+ const int32_t val2 = get_wregister(rt2, R31IsZR);
+ WriteW(address, val1, instr);
+ WriteW(address + size, val2, instr);
+ }
}
}
diff --git a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
index 29544d8..37e538b 100644
--- a/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
+++ b/sdk/lib/web_audio/dart2js/web_audio_dart2js.dart
@@ -386,7 +386,7 @@
int? get numberOfOutputs native;
@JSName('connect')
- AudioNode _connect(destination, [int? output, int? input]) native;
+ AudioNode? _connect(destination, [int? output, int? input]) native;
void disconnect([destination_OR_output, int? output, int? input]) native;
diff --git a/tools/VERSION b/tools/VERSION
index 1c7d543..fa720fe 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 215
+PRERELEASE 216
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index ac5b337..674af14 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -451,6 +451,15 @@
};
[DartSupplemental]
+interface AudioNode : EventTarget {
+ [DartSuppress] AudioNode connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0);
+ [DartSuppress] void connect(AudioParam destination, optional unsigned long output = 0);
+ AudioNode? connect(AudioNode destination, optional unsigned long output = 0, optional unsigned long input = 0);
+ // Scripts don't unify return types, so this is changed from void to do so.
+ AudioNode? connect(AudioParam destination, optional unsigned long output = 0);
+};
+
+[DartSupplemental]
interface HTMLInputElement {
[DartSuppress] attribute boolean webkitSpeech;
[DartSuppress] attribute boolean webkitGrammar;
diff --git a/tools/gn.py b/tools/gn.py
index e54c331..f5c01ad 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -97,13 +97,10 @@
m = platform.machine()
if m == 'aarch64' or m == 'arm64':
return 'arm64'
- if m == 'armv7l' or m == 'armv6l':
+ if m == 'armv7l':
return 'arm'
- if arch in [
- 'ia32', 'arm', 'armv6', 'simarm', 'simarm_x64', 'riscv32',
- 'simriscv32'
- ]:
+ if arch in ['ia32', 'arm', 'simarm', 'simarm_x64', 'riscv32', 'simriscv32']:
return 'x86'
if arch in [
'x64', 'arm64', 'simarm64', 'arm_x64', 'x64c', 'arm64c',
@@ -239,11 +236,6 @@
gn_args['arm_version'] = 7
gn_args['arm_float_abi'] = floatabi
gn_args['arm_use_neon'] = True
- elif gn_args['target_cpu'] == 'armv6':
- floatabi = 'softfp' if args.arm_float_abi == '' else args.arm_float_abi
- gn_args['target_cpu'] = 'arm'
- gn_args['arm_version'] = 6
- gn_args['arm_float_abi'] = floatabi
gn_args['is_debug'] = mode == 'debug'
gn_args['is_release'] = mode == 'release'
@@ -389,7 +381,6 @@
'x64',
'arm',
'arm_x64',
- 'armv6',
'arm64',
'x64c',
'arm64c',
diff --git a/tools/linux_dist_support/create_debian_packages.py b/tools/linux_dist_support/create_debian_packages.py
index 94c0d53..ae3473f 100755
--- a/tools/linux_dist_support/create_debian_packages.py
+++ b/tools/linux_dist_support/create_debian_packages.py
@@ -35,7 +35,7 @@
result.add_option("-a",
"--arch",
help='Target architectures (comma-separated).',
- metavar='[all,ia32,x64,armel,armhf]',
+ metavar='[all,ia32,x64,armhf]',
default='x64')
result.add_option("-t",
"--toolchain",
@@ -92,12 +92,6 @@
RunBuildPackage(['-B', '-aarmhf', '-us', '-uc'],
join(temp_dir, tarroot), toolchain)
- # Build armel binary package.
- if 'armel' in arch:
- print("Building armel package")
- RunBuildPackage(['-B', '-aarmel', '-us', '-uc'],
- join(temp_dir, tarroot), toolchain)
-
# Copy the Debian package files to the build directory.
debbase = 'dart_%s' % version
source_package = [
@@ -108,7 +102,6 @@
i386_package = ['%s-1_i386.deb' % debbase]
amd64_package = ['%s-1_amd64.deb' % debbase]
armhf_package = ['%s-1_armhf.deb' % debbase]
- armel_package = ['%s-1_armel.deb' % debbase]
for name in source_package:
copyfile(join(temp_dir, name), join(out_dir, name))
@@ -121,9 +114,6 @@
if ('armhf' in arch):
for name in armhf_package:
copyfile(join(temp_dir, name), join(out_dir, name))
- if ('armel' in arch):
- for name in armel_package:
- copyfile(join(temp_dir, name), join(out_dir, name))
def Main():
diff --git a/tools/sdks/update.sh b/tools/sdks/update.sh
index 8cb5633..09255a7 100755
--- a/tools/sdks/update.sh
+++ b/tools/sdks/update.sh
@@ -34,7 +34,7 @@
gsutil.py cp "gs://dart-archive/channels/$channel/release/$1/sdk/dartsdk-linux-arm-release.zip" .
unzip -q dartsdk-linux-arm-release.zip -d sdk
cipd create \
- -name dart/dart-sdk/linux-armv6l \
+ -name dart/dart-sdk/linux-arm \
-in sdk \
-install-mode copy \
-tag version:$1 \
diff --git a/tools/utils.py b/tools/utils.py
index 3741a0b..2f42263 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -152,9 +152,7 @@
# Try to guess the host architecture.
def GuessArchitecture():
os_id = platform.machine()
- if os_id.startswith('armv6'):
- return 'armv6'
- elif os_id.startswith('aarch64') or os_id == 'arm64':
+ if os_id.startswith('aarch64') or os_id == 'arm64':
return 'arm64'
elif os_id.startswith('arm'):
return 'arm'