Version 3.11.0-272.0.dev
Merge 89250d64b93e1c0c278f7768e502f18144c4596f into dev
diff --git a/pkg/analyzer/lib/src/error/annotation_verifier.dart b/pkg/analyzer/lib/src/error/annotation_verifier.dart
index c82c5d6..4ae4282 100644
--- a/pkg/analyzer/lib/src/error/annotation_verifier.dart
+++ b/pkg/analyzer/lib/src/error/annotation_verifier.dart
@@ -408,25 +408,13 @@
/// `@nonVirtual` annotation.
void _checkNonVirtual(Annotation node) {
var parent = node.parent;
- if (parent is FieldDeclaration) {
- if (parent.isStatic) {
- _diagnosticReporter.report(
- diag.invalidNonVirtualAnnotation.at(node.name),
- );
- }
- } else if (parent is MethodDeclaration) {
- if (parent.parent?.parent is ExtensionDeclaration ||
- parent.parent?.parent is ExtensionTypeDeclaration ||
- parent.isStatic ||
+ if (parent is MethodDeclaration) {
+ if (parent.parent?.parent is ExtensionTypeDeclaration ||
parent.isAbstract) {
_diagnosticReporter.report(
diag.invalidNonVirtualAnnotation.at(node.name),
);
}
- } else {
- _diagnosticReporter.report(
- diag.invalidNonVirtualAnnotation.at(node.name),
- );
}
}
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index c0daae5..1abfc2d 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -27114,16 +27114,6 @@
#### Examples
- The following code produces this diagnostic because the annotation is on a
- class declaration rather than a member inside the class:
-
- ```dart
- import 'package:meta/meta.dart';
-
- @[!nonVirtual!]
- class C {}
- ```
-
The following code produces this diagnostic because the method `m` is an
abstract method:
@@ -27136,27 +27126,8 @@
}
```
- The following code produces this diagnostic because the method `m` is a
- static method:
-
- ```dart
- import 'package:meta/meta.dart';
-
- abstract class C {
- @[!nonVirtual!]
- static void m() {}
- }
- ```
-
#### Common fixes
- If the declaration isn't a member of a class, mixin, or enum, then remove
- the annotation:
-
- ```dart
- class C {}
- ```
-
If the member is intended to be a concrete instance member, then make it
so:
@@ -27168,15 +27139,6 @@
void m() {}
}
```
-
- If the member is not intended to be a concrete instance member, then
- remove the annotation:
-
- ```dart
- abstract class C {
- static void m() {}
- }
- ```
invalidOverrideOfNonVirtualMember:
type: staticWarning
parameters:
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart
index af1b480..3593e4d 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_annotation_target_test.dart
@@ -1213,7 +1213,7 @@
);
}
- void test_overridableMember_class_visibleForOverride() async {
+ void test_overridableMember_class_visibleForOverriding() async {
await assertErrorsInCode(
'''
import 'package:meta/meta.dart';
@@ -1243,6 +1243,20 @@
);
}
+ void test_overridableMember_enumConstant() async {
+ await assertErrorsInCode(
+ '''
+import 'package:meta/meta.dart';
+enum E {
+ @nonVirtual
+ a,
+ b, c
+}
+''',
+ [error(diag.invalidAnnotationTarget, 45, 10)],
+ );
+ }
+
void test_overridableMember_extensionType_visibleForOverride() async {
await assertErrorsInCode(
'''
@@ -1373,6 +1387,25 @@
''');
}
+ void test_overridableMember_staticField() async {
+ await assertErrorsInCode(
+ '''
+import 'package:meta/meta_meta.dart';
+
+@Target({TargetKind.overridableMember})
+class A {
+ const A();
+}
+
+class C {
+ @A()
+ static int x = 0;
+}
+''',
+ [error(diag.invalidAnnotationTarget, 118, 1)],
+ );
+ }
+
void test_overridableMember_staticMethod() async {
await assertErrorsInCode(
'''
@@ -1412,6 +1445,41 @@
);
}
+ void test_overridableMember_topLevelGetter_nonVirtual() async {
+ await assertErrorsInCode(
+ r'''
+import 'package:meta/meta.dart';
+
+@nonVirtual
+int get a => 1;
+''',
+ [error(diag.invalidAnnotationTarget, 35, 10)],
+ );
+ }
+
+ void test_overridableMember_topLevelSetter_nonVirtual() async {
+ await assertErrorsInCode(
+ r'''
+import 'package:meta/meta.dart';
+
+@nonVirtual
+set a(int value) {}
+''',
+ [error(diag.invalidAnnotationTarget, 35, 10)],
+ );
+ }
+
+ void test_overridableMember_typedef() async {
+ await assertErrorsInCode(
+ r'''
+import 'package:meta/meta.dart';
+@nonVirtual
+typedef bool predicate(Object o);
+''',
+ [error(diag.invalidAnnotationTarget, 34, 10)],
+ );
+ }
+
void test_parameter_function() async {
await assertErrorsInCode(
'''
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_non_virtual_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_non_virtual_annotation_test.dart
index c798eae..3d4b233 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_non_virtual_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_non_virtual_annotation_test.dart
@@ -21,19 +21,18 @@
writeTestPackageConfigWithMeta();
}
- test_class() async {
- await assertErrorsInCode(
- r'''
+ test_instanceMethod() async {
+ await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
-@nonVirtual
-class C {}
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
+abstract class C {
+ @nonVirtual
+ void m() {}
+}
+''');
}
- test_class_abstract_member() async {
+ test_instanceMethod_abstract() async {
await assertErrorsInCode(
r'''
import 'package:meta/meta.dart';
@@ -47,135 +46,7 @@
);
}
- test_class_getter() async {
- await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-
-class C {
- @nonVirtual
- int get g => 0;
-}
-''');
- }
-
- test_class_instance_field() async {
- await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-
-class C {
- @nonVirtual
- int f = 0;
-}
-''');
- }
-
- test_class_instance_member() async {
- await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-
-class C {
- @nonVirtual
- void m() {
- }
-}
-''');
- }
-
- test_class_setter() async {
- await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-
-class C {
- @nonVirtual
- set s(int v) {}
-}
-''');
- }
-
- test_class_static_field() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-class C {
- @nonVirtual
- static int f = 0;
-}
-''',
- [error(diag.invalidNonVirtualAnnotation, 48, 10)],
- );
- }
-
- test_class_static_method() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-class C {
- @nonVirtual
- static void m() {}
-}
-''',
- [error(diag.invalidNonVirtualAnnotation, 48, 10)],
- );
- }
-
- test_enum() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-enum E {
- a, b, c
-}
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
-
- test_enum_constant() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-enum E {
- @nonVirtual
- a,
- b, c
-}
-''',
- [error(diag.invalidNonVirtualAnnotation, 46, 10)],
- );
- }
-
- test_extension() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-extension E on Object {}
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
-
- test_extension_member() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-extension E on Object {
- @nonVirtual
- void m() {}
-}
-''',
- [error(diag.invalidNonVirtualAnnotation, 62, 10)],
- );
- }
-
- test_extensionType_instance_method() async {
+ test_instanceMethod_onExtensionType() async {
await assertErrorsInCode(
r'''
import 'package:meta/meta.dart';
@@ -188,125 +59,4 @@
[error(diag.invalidNonVirtualAnnotation, 63, 10)],
);
}
-
- test_import() async {
- await assertErrorsInCode(
- r'''
-@nonVirtual
-import 'package:meta/meta.dart';
-''',
- [error(diag.invalidNonVirtualAnnotation, 1, 10)],
- );
- }
-
- test_mixin() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-mixin M {}
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
-
- test_mixin_instance_member() async {
- await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-
-mixin M {
- @nonVirtual
- void m() {}
-}
-''');
- }
-
- test_mixin_static_field() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-mixin M {
- @nonVirtual
- static int f = 0;
-}
-''',
- [error(diag.invalidNonVirtualAnnotation, 47, 10)],
- );
- }
-
- test_mixin_static_method() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-mixin M {
- @nonVirtual
- static void m() {}
-}
-''',
- [error(diag.invalidNonVirtualAnnotation, 47, 10)],
- );
- }
-
- test_top_level_function() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-m() {}
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
-
- test_top_level_getter() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-int get g => 0;
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
-
- test_top_level_setter() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-set s(int v) {}
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
-
- test_top_level_var() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-int x = 0;
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
-
- test_typedef() async {
- await assertErrorsInCode(
- r'''
-import 'package:meta/meta.dart';
-
-@nonVirtual
-typedef bool predicate(Object o);
-''',
- [error(diag.invalidNonVirtualAnnotation, 35, 10)],
- );
- }
}
diff --git a/pkg/analyzer_testing/lib/src/mock_packages/meta/meta.dart b/pkg/analyzer_testing/lib/src/mock_packages/meta/meta.dart
index 21dbb9e..b4478245 100644
--- a/pkg/analyzer_testing/lib/src/mock_packages/meta/meta.dart
+++ b/pkg/analyzer_testing/lib/src/mock_packages/meta/meta.dart
@@ -199,6 +199,7 @@
const _MustCallSuper();
}
+@Target({TargetKind.overridableMember})
class _NonVirtual {
const _NonVirtual();
}
diff --git a/pkg/compiler/test/record_use/record_use_test.dart b/pkg/compiler/test/record_use/record_use_test.dart
index 1c206eb..6c6a744 100644
--- a/pkg/compiler/test/record_use/record_use_test.dart
+++ b/pkg/compiler/test/record_use/record_use_test.dart
@@ -2,6 +2,7 @@
// 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:convert';
import 'dart:io' show File, Directory, Platform;
import 'package:compiler/compiler_api.dart' as api show OutputType;
@@ -10,6 +11,7 @@
import 'package:compiler/src/util/memory_compiler.dart';
import 'package:expect/expect.dart' show Expect;
import 'package:path/path.dart' as path;
+import 'package:record_use/record_use.dart';
/// Options to pass to the compiler such as
/// `Flags.disableTypeInference` or `Flags.disableInlining`
@@ -18,24 +20,19 @@
/// Run `dart --define=updateExpectations=true pkg/compiler/test/record_use/record_use_test.dart`
/// to update.
Future<void> main() async {
- final directory = Directory.fromUri(Platform.script.resolve('data'));
- final testFiles =
- [
- ...directory.listSync(),
- ...Directory(
- 'pkg/vm/testcases/transformations/record_use',
- ).listSync(),
- ]
- .whereType<File>()
- .where((file) => file.path.endsWith('.dart'))
- .map(
- (file) => TestFile(
- file: file,
- basename: path.basename(file.path),
- contents: file.readAsStringSync(),
- uri: _createUri(path.basename(file.path)),
- ),
- );
+ final dataDirectory = Directory.fromUri(Platform.script.resolve('data'));
+ final vmTestCases = Directory('pkg/vm/testcases/transformations/record_use');
+ final testFiles = [...dataDirectory.listSync(), ...vmTestCases.listSync()]
+ .whereType<File>()
+ .where((file) => file.path.endsWith('.dart'))
+ .map(
+ (file) => TestFile(
+ file: file,
+ basename: path.basename(file.path),
+ contents: file.readAsStringSync(),
+ uri: _createUri(path.basename(file.path)),
+ ),
+ );
final allFiles = {for (final file in testFiles) file.uri.path: file.contents};
for (final testFile in testFiles.where((element) => element.hasMain)) {
@@ -45,6 +42,8 @@
);
final goldenFile = File(
path.join(
+ // TODO(https://github.com/dart-lang/native/issues/2885): Share test
+ // expectations with the VM.
Platform.script.resolve('golden').path,
path.setExtension(testFile.basename, '.json.expect'),
),
@@ -54,11 +53,18 @@
await goldenFile.create();
await goldenFile.writeAsString(recordedUsages);
} else {
- Expect.stringEquals(
- recordedUsages.trim(),
- (await goldenFile.readAsString()).trim(),
- 'Recorded usages for ${testFile.uri} do not match golden file.',
- );
+ final actual = RecordedUsages.fromJson(jsonDecode(recordedUsages));
+ final goldenContents = await goldenFile.readAsString();
+ final golden = RecordedUsages.fromJson(jsonDecode(goldenContents));
+ final semanticEquals = actual == golden;
+ if (!semanticEquals) {
+ // Print the error message based on string representation.
+ Expect.stringEquals(
+ recordedUsages.trim(),
+ goldenContents.trim(),
+ 'Recorded usages for ${testFile.uri} do not match golden file.',
+ );
+ }
}
}
}
diff --git a/pkg/dart2wasm/tool/compile_benchmark b/pkg/dart2wasm/tool/compile_benchmark
index fe16bec..2d13743 100755
--- a/pkg/dart2wasm/tool/compile_benchmark
+++ b/pkg/dart2wasm/tool/compile_benchmark
@@ -99,6 +99,12 @@
shift
;;
+ -O* | --optimization-level=*)
+ DART2WASM_ARGS+=("$1")
+ RUN_BINARYEN=1
+ shift
+ ;;
+
--phases=*)
PHASES="${1#--phases=}"
shift
diff --git a/pkg/dartdev/pubspec.yaml b/pkg/dartdev/pubspec.yaml
index aa02b8a..51da439 100644
--- a/pkg/dartdev/pubspec.yaml
+++ b/pkg/dartdev/pubspec.yaml
@@ -51,5 +51,6 @@
expect: any
lints: any
pub_semver: any
+ record_use: any
test: any
yaml_edit: any
diff --git a/pkg/dartdev/test/native_assets/compile_test.dart b/pkg/dartdev/test/native_assets/compile_test.dart
index a4236cb1..52918bc 100644
--- a/pkg/dartdev/test/native_assets/compile_test.dart
+++ b/pkg/dartdev/test/native_assets/compile_test.dart
@@ -4,8 +4,10 @@
// @dart=2.18
+import 'dart:convert';
import 'dart:io';
+import 'package:record_use/record_use.dart';
import 'package:test/test.dart';
import '../utils.dart';
@@ -38,8 +40,7 @@
});
});
- test('Golden test for recorded usages in dart2js', timeout: longTimeout,
- () async {
+ test('Recorded usages in dart2js', timeout: longTimeout, () async {
await recordUseTest('drop_data_asset', (dartAppUri) async {
await runDart(
arguments: ['pub', 'get'],
@@ -68,63 +69,21 @@
expect(recordedUsages.existsSync(), true);
final actualRecordedUsages = recordedUsages.readAsStringSync();
- final expectedRecordedUsages = '''{
- "constants": [
- {
- "type": "int",
- "value": 3
- },
- {
- "type": "int",
- "value": 4
- }
- ],
- "locations": [
- {
- "uri": "bin/drop_data_asset_calls.dart"
- }
- ],
- "metadata": {
- "comment": "Resources referenced by annotated resource identifiers",
- "AppTag": "TBD",
- "environment": {
- "dart.web.assertions_enabled": "false",
- "dart.tool.dart2js": "true",
- "dart.tool.dart2js.minify": "false",
- "dart.tool.dart2js.disable_rti_optimization": "false",
- "dart.tool.dart2js.primitives:trust": "false",
- "dart.tool.dart2js.types:trust": "false"
- },
- "version": "0.4.0"
- },
- "recordings": [
- {
- "calls": [
- {
- "@": 0,
- "loading_unit": "out.js",
- "positional": [
- 0,
- 1
- ],
- "type": "with_arguments"
- }
- ],
- "definition": {
- "identifier": {
- "name": "add",
- "scope": "MyMath",
- "uri": "package:drop_data_asset/src/drop_data_asset.dart"
- }
- }
- }
- ]
-}''';
- expect(actualRecordedUsages, expectedRecordedUsages);
+ final u = RecordedUsages.fromJson(jsonDecode(actualRecordedUsages));
+ final constArguments = u.constArgumentsFor(Identifier(
+ importUri: 'package:drop_data_asset/src/drop_data_asset.dart',
+ scope: 'MyMath',
+ name: 'add',
+ ));
+ expect(constArguments.length, 1);
+ expect(constArguments.first.named.isEmpty, true);
+ expect(constArguments.first.positional, [3, 4]);
});
});
- test('Golden test for recorded usages in dart2js - no instance support yet',
+ // TODO(https://github.com/dart-lang/native/issues/2893): Implement instance
+ // support.
+ test('Recorded usages in dart2js - no instance support yet',
timeout: longTimeout, () async {
await recordUseTest('drop_data_asset', (dartAppUri) async {
await runDart(
@@ -153,22 +112,12 @@
expect(recordedUsages.existsSync(), true);
final actualRecordedUsages = recordedUsages.readAsStringSync();
- final expectedRecordedUsages = '''{
- "metadata": {
- "comment": "Resources referenced by annotated resource identifiers",
- "AppTag": "TBD",
- "environment": {
- "dart.web.assertions_enabled": "false",
- "dart.tool.dart2js": "true",
- "dart.tool.dart2js.minify": "false",
- "dart.tool.dart2js.disable_rti_optimization": "false",
- "dart.tool.dart2js.primitives:trust": "false",
- "dart.tool.dart2js.types:trust": "false"
- },
- "version": "0.4.0"
- }
-}''';
- expect(actualRecordedUsages, expectedRecordedUsages);
+ final u = RecordedUsages.fromJson(jsonDecode(actualRecordedUsages));
+ final constantsOf = u.constantsOf(Identifier(
+ importUri: 'package:drop_data_asset/src/drop_data_asset.dart',
+ name: 'RecordCallToC',
+ ));
+ expect(constantsOf.length, 0);
});
});
}
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index a954039..be966ed 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -762,8 +762,7 @@
const _MustCallSuper();
}
-// TODO(srawlins): Enforce with `TargetKind.method`, `TargetKind.getter`,
-// `TargetKind.setter`, `TargetKind.field`.
+@Target({TargetKind.overridableMember})
class _NonVirtual {
const _NonVirtual();
}
diff --git a/pkg/vm/test/transformations/record_use_test.dart b/pkg/vm/test/transformations/record_use_test.dart
index c597316..28fb03a 100644
--- a/pkg/vm/test/transformations/record_use_test.dart
+++ b/pkg/vm/test/transformations/record_use_test.dart
@@ -2,12 +2,14 @@
// 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:convert';
import 'dart:io';
import 'package:kernel/ast.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:kernel/verifier.dart';
+import 'package:record_use/record_use_internal.dart';
import 'package:test/test.dart';
import 'package:vm/kernel_front_end.dart'
show runGlobalTransformations, ErrorDetector, KernelCompilationArguments;
@@ -65,11 +67,24 @@
).replaceAll(_pkgVmDir.toString(), 'org-dartlang-test:///');
compareResultWithExpectationsFile(source, actual, expectFilePostfix: '.aot');
- compareResultWithExpectationsFile(
- source,
- File.fromUri(recordedUsagesFile).readAsStringSync(),
- expectFilePostfix: '.json',
+
+ final actualSemantic = RecordedUsages.fromJson(
+ jsonDecode(File.fromUri(recordedUsagesFile).readAsStringSync()),
);
+ final goldenFile = File('${source.toFilePath()}.json.expect');
+ final goldenContents = await goldenFile.readAsString();
+ final golden = RecordedUsages.fromJson(jsonDecode(goldenContents));
+ final semanticEquals = actualSemantic == golden;
+ final update =
+ bool.fromEnvironment('updateExpectations') ||
+ Platform.environment['UPDATE_EXPECTATIONS'] != null;
+ if (!semanticEquals || update) {
+ compareResultWithExpectationsFile(
+ source,
+ File.fromUri(recordedUsagesFile).readAsStringSync(),
+ expectFilePostfix: '.json',
+ );
+ }
}
void main(List<String> args) {
diff --git a/tools/VERSION b/tools/VERSION
index d1a29d2..3adc47b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 3
MINOR 11
PATCH 0
-PRERELEASE 271
+PRERELEASE 272
PRERELEASE_PATCH 0