Version 2.17.0-81.0.dev
Merge commit '5e8e68c2c86983f8f4bc856e3ad5092db4d65f6c' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8ea983b..db965d7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,14 @@
- Add `ref=` and `[]=` methods to the `StructPointer` and `UnionPointer`
extensions. They copy a compound instance into a native memory region.
+#### `dart:html`
+
+- Add `scrollIntoViewIfNeeded` to `Element`. Previously, this method was nested
+ within `scrollIntoView` based on the `ScrollAlignment` value. `scrollIntoView`
+ is unchanged for now, but users who intend to use the native
+ `Element.scrollIntoViewIfNeeded` should use the new `scrollIntoViewIfNeeded`
+ definition instead.
+
#### `dart:indexed_db`
- `IdbFactory.supportsDatabaseNames` has been deprecated. It will always return
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 79182f9..14a910c 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -159,6 +159,7 @@
CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT,
CompileTimeErrorCode.DUPLICATE_PART,
CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
+ CompileTimeErrorCode.ENUM_MIXIN_WITH_INSTANCE_VARIABLE,
CompileTimeErrorCode.EQUAL_ELEMENTS_IN_CONST_SET,
CompileTimeErrorCode.EQUAL_KEYS_IN_CONST_MAP,
CompileTimeErrorCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS,
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index e3bf80e..88d2afe 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -3636,6 +3636,13 @@
correctionMessage: "Try renaming the constant.",
);
+ static const CompileTimeErrorCode ENUM_MIXIN_WITH_INSTANCE_VARIABLE =
+ CompileTimeErrorCode(
+ 'ENUM_MIXIN_WITH_INSTANCE_VARIABLE',
+ "Mixins applied to enums can't have instance variables.",
+ correctionMessage: "Try replacing the instance variables with getters.",
+ );
+
/**
* No parameters.
*/
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index fec81ec..aa1f7c1 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -61,6 +61,18 @@
superclass: declaration.superclass2,
withClause: declaration.withClause,
).verify();
+ } else if (declaration is EnumDeclaration) {
+ _ClassVerifier(
+ typeSystem: _typeSystem,
+ typeProvider: _typeProvider,
+ inheritance: _inheritance,
+ reporter: _reporter,
+ featureSet: unit.featureSet,
+ library: library,
+ classNameNode: declaration.name,
+ implementsClause: declaration.implementsClause,
+ withClause: declaration.withClause,
+ ).verify();
} else if (declaration is MixinDeclaration) {
_ClassVerifier(
typeSystem: _typeSystem,
@@ -94,7 +106,7 @@
final FeatureSet featureSet;
final LibraryElementImpl library;
final Uri libraryUri;
- final ClassElementImpl classElement;
+ final AbstractClassElementImpl classElement;
final SimpleIdentifier classNameNode;
final List<ClassMember> members;
@@ -119,7 +131,7 @@
this.superclass,
this.withClause,
}) : libraryUri = library.source.uri,
- classElement = classNameNode.staticElement as ClassElementImpl;
+ classElement = classNameNode.staticElement as AbstractClassElementImpl;
bool get _isNonNullableByDefault => typeSystem.isNonNullableByDefault;
@@ -128,7 +140,8 @@
return;
}
- if (!classElement.isAbstract &&
+ if (!classElement.isEnum &&
+ !classElement.isAbstract &&
classElement.allSupertypes.any((e) => e.isDartCoreEnum)) {
reporter.reportErrorForNode(
CompileTimeErrorCode.NON_ABSTRACT_CLASS_HAS_ENUM_SUPERINTERFACE,
@@ -402,11 +415,36 @@
)) {
hasError = true;
}
+ if (classElement.isEnum && _checkEnumMixin(namedType)) {
+ hasError = true;
+ }
}
}
return hasError;
}
+ bool _checkEnumMixin(NamedType namedType) {
+ DartType type = namedType.typeOrThrow;
+ if (type is! InterfaceType) {
+ return false;
+ }
+
+ var interfaceElement = type.element;
+ if (interfaceElement.isEnum) {
+ return false;
+ }
+
+ if (interfaceElement.fields.every((e) => e.isStatic || e.isSynthetic)) {
+ return false;
+ }
+
+ reporter.reportErrorForNode(
+ CompileTimeErrorCode.ENUM_MIXIN_WITH_INSTANCE_VARIABLE,
+ namedType,
+ );
+ return true;
+ }
+
void _checkForOptionalParametersDifferentDefaultValues(
MethodElement baseExecutable,
MethodElement derivedExecutable,
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 50014bb..41e3bc3 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -3335,6 +3335,9 @@
ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING:
problemMessage: "The name of the enum constant can't be the same as the enum's name."
correctionMessage: Try renaming the constant.
+ ENUM_MIXIN_WITH_INSTANCE_VARIABLE:
+ problemMessage: Mixins applied to enums can't have instance variables.
+ correctionMessage: Try replacing the instance variables with getters.
EQUAL_ELEMENTS_IN_CONST_SET:
problemMessage: "Two elements in a constant set literal can't be equal."
correctionMessage: Change or remove the duplicate element.
diff --git a/pkg/analyzer/test/src/diagnostics/enum_mixin_with_instance_variable_test.dart b/pkg/analyzer/test/src/diagnostics/enum_mixin_with_instance_variable_test.dart
new file mode 100644
index 0000000..756833d
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/enum_mixin_with_instance_variable_test.dart
@@ -0,0 +1,81 @@
+// 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/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(EnumMixinWithInstanceVariableTest);
+ });
+}
+
+@reflectiveTest
+class EnumMixinWithInstanceVariableTest extends PubPackageResolutionTest {
+ test_field_instance() async {
+ await assertErrorsInCode(r'''
+mixin M {
+ var foo = 0;
+}
+
+enum E with M {
+ v
+}
+''', [
+ error(CompileTimeErrorCode.ENUM_MIXIN_WITH_INSTANCE_VARIABLE, 40, 1),
+ ]);
+ }
+
+ test_field_instance_final() async {
+ await assertErrorsInCode(r'''
+mixin M {
+ final foo = 0;
+}
+
+enum E with M {
+ v
+}
+''', [
+ error(CompileTimeErrorCode.ENUM_MIXIN_WITH_INSTANCE_VARIABLE, 42, 1),
+ ]);
+ }
+
+ test_field_static() async {
+ await assertNoErrorsInCode(r'''
+mixin M {
+ static var foo = 0;
+}
+
+enum E with M {
+ v
+}
+''');
+ }
+
+ test_getter_instance() async {
+ await assertNoErrorsInCode(r'''
+mixin M {
+ int get foo => 0;
+}
+
+enum E with M {
+ v
+}
+''');
+ }
+
+ test_setter_instance() async {
+ await assertNoErrorsInCode(r'''
+mixin M {
+ set foo(int _) {}
+}
+
+enum E with M {
+ v
+}
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart b/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart
index 37f5e9e..e06cd12 100644
--- a/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/implements_disallowed_class_test.dart
@@ -259,6 +259,26 @@
]);
}
+ test_enum_dartCoreEnum() async {
+ await assertErrorsInCode('''
+enum E implements Enum {
+ v
+}
+''', [
+ error(CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, 18, 4),
+ ]);
+ }
+
+ test_enum_int() async {
+ await assertErrorsInCode('''
+enum E implements int {
+ v
+}
+''', [
+ error(CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS, 18, 3),
+ ]);
+ }
+
test_mixin_dartCoreEnum() async {
await assertNoErrorsInCode('''
mixin M implements Enum {}
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart
index b72300b..8b32940 100644
--- a/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/mixin_of_disallowed_class_test.dart
@@ -163,4 +163,14 @@
error(CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS, 36, 3),
]);
}
+
+ test_enum_int() async {
+ await assertErrorsInCode('''
+enum E with int {
+ v
+}
+''', [
+ error(CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS, 12, 3),
+ ]);
+ }
}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index d8504b1..5ca7e69 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -147,6 +147,8 @@
import 'duplicate_shown_name_test.dart' as duplicate_shown_name;
import 'enum_constant_same_name_as_enclosing_test.dart'
as enum_constant_same_name_as_enclosing;
+import 'enum_mixin_with_instance_variable_test.dart'
+ as enum_mixin_with_instance_variable;
import 'equal_elements_in_const_set_test.dart' as equal_elements_in_const_set;
import 'equal_elements_in_set_test.dart' as equal_elements_in_set;
import 'equal_keys_in_const_map_test.dart' as equal_keys_in_const_map;
@@ -854,6 +856,7 @@
duplicate_part.main();
duplicate_shown_name.main();
enum_constant_same_name_as_enclosing.main();
+ enum_mixin_with_instance_variable.main();
equal_elements_in_const_set.main();
equal_elements_in_set.main();
equal_keys_in_const_map.main();
diff --git a/pkg/dartdev/lib/src/commands/doc.dart b/pkg/dartdev/lib/src/commands/doc.dart
index 907bba6..f3cdccf 100644
--- a/pkg/dartdev/lib/src/commands/doc.dart
+++ b/pkg/dartdev/lib/src/commands/doc.dart
@@ -54,7 +54,7 @@
}
@override
- String get invocation => '${super.invocation} <input directory>';
+ String get invocation => '${super.invocation} [<directory>]';
@override
FutureOr<int> run() async {
@@ -64,18 +64,19 @@
if (args['sdk-docs']) {
options.add('--sdk-docs');
} else {
- // At least one argument, the input directory, is required,
- // when we're not generating docs for the Dart SDK.
- if (args.rest.isEmpty) {
- usageException('Error: Input directory not specified');
+ if (args.rest.length > 1) {
+ usageException("'dart doc' only supports one input directory.'");
}
- // Determine input directory.
- final dir = io.Directory(args.rest[0]);
- if (!dir.existsSync()) {
- usageException('Error: Input directory doesn\'t exist: ${dir.path}');
+ // Determine input directory; default to the cwd if no explicit input dir
+ // is passed in.
+ final directory = args.rest.isEmpty
+ ? io.Directory.current
+ : io.Directory(args.rest.first);
+ if (!directory.existsSync()) {
+ usageException('Input directory doesn\'t exist: ${directory.path}');
}
- options.add('--input=${dir.path}');
+ options.add('--input=${directory.path}');
}
// Specify where dartdoc resources are located.
diff --git a/pkg/dartdev/test/commands/doc_test.dart b/pkg/dartdev/test/commands/doc_test.dart
index 42ee01b..b6f80ff 100644
--- a/pkg/dartdev/test/commands/doc_test.dart
+++ b/pkg/dartdev/test/commands/doc_test.dart
@@ -6,30 +6,49 @@
import '../utils.dart';
-const int compileErrorExitCode = 64;
+const int errorExitCode = 64;
void main() {
group('doc', defineDocTests, timeout: longTimeout);
}
void defineDocTests() {
- test('Passing no args fails', () async {
- final p = project();
- final result = await p.run(['doc']);
- expect(result.stderr, contains('Input directory not specified'));
- expect(result.exitCode, compileErrorExitCode);
- });
-
test('--help', () async {
final p = project();
final result = await p.run(['doc', '--help']);
expect(
result.stdout,
- contains('Usage: dart doc [arguments] <input directory>'),
+ contains('Usage: dart doc [arguments] [<directory>]'),
);
expect(result.exitCode, 0);
});
+ test('Passing multiple directories fails', () async {
+ final p = project();
+ final result = await p.run(['doc', 'foo', 'bar']);
+ expect(result.stderr,
+ contains("'dart doc' only supports one input directory.'"));
+ expect(result.exitCode, errorExitCode);
+ });
+
+ test('defaults to documenting cwd', () async {
+ final p = project(mainSrc: 'void main() { print("Hello, World"); }');
+ p.file('lib/foo.dart', '''
+/// This is Foo. It uses [Bar].
+class Foo {
+ Bar bar;
+}
+
+/// Bar is very nice.
+class Bar {
+ _i = 42;
+}
+''');
+ final result = await p.run(['doc'], workingDir: p.dirPath);
+ expect(result.stdout, contains('Documenting dartdev_temp'));
+ expect(result.exitCode, 0);
+ });
+
test('Document a library', () async {
final p = project(mainSrc: 'void main() { print("Hello, World"); }');
p.file('lib/foo.dart', '''
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 9b9fd08..e0a610a 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -837,11 +837,11 @@
final defaultLibrarySpecPath = p.join(getSdkPath(), 'lib', 'libraries.json');
-/// Returns the absolute path to the default `.packages` file, or `null` if one
-/// could not be found.
+/// Returns the absolute path to the default `package_config.json` file, or
+/// `null` if one could not be found.
///
-/// Checks for a `.packages` file in the current working directory, or in any
-/// parent directory.
+/// Checks for a `.dart_tool/package_config.json` file in the current working
+/// directory, or in any parent directory.
String _findPackagesFilePath() {
// TODO(jmesserly): this was copied from package:package_config/discovery.dart
// Unfortunately the relevant function is not public. CFE APIs require a URI
@@ -850,9 +850,9 @@
if (!dir.isAbsolute) dir = dir.absolute;
if (!dir.existsSync()) return null;
- // Check for $cwd/.packages
+ // Check for $cwd/.dart_tool/package_config.json
while (true) {
- var file = File(p.join(dir.path, '.packages'));
+ var file = File.fromUri(dir.uri.resolve('.dart_tool/package_config.json'));
if (file.existsSync()) return file.path;
// If we didn't find it, search the parent directory.
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 9e8ab9a..b421ddc 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1114,9 +1114,10 @@
DART_EXPORT void Dart_UpdateExternalSize(Dart_WeakPersistentHandle object,
intptr_t external_size) {
- IsolateGroup* isolate_group = IsolateGroup::Current();
+ Thread* T = Thread::Current();
+ IsolateGroup* isolate_group = T->isolate_group();
CHECK_ISOLATE_GROUP(isolate_group);
- NoSafepointScope no_safepoint_scope;
+ TransitionToVM transition(T);
ApiState* state = isolate_group->api_state();
ASSERT(state != NULL);
ASSERT(state->IsActiveWeakPersistentHandle(object));
@@ -1140,9 +1141,10 @@
}
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object) {
- IsolateGroup* isolate_group = IsolateGroup::Current();
+ Thread* T = Thread::Current();
+ IsolateGroup* isolate_group = T->isolate_group();
CHECK_ISOLATE_GROUP(isolate_group);
- NoSafepointScope no_safepoint_scope;
+ TransitionToVM transition(T);
ApiState* state = isolate_group->api_state();
ASSERT(state != NULL);
ASSERT(state->IsActivePersistentHandle(object));
@@ -1155,9 +1157,10 @@
DART_EXPORT void Dart_DeleteWeakPersistentHandle(
Dart_WeakPersistentHandle object) {
- IsolateGroup* isolate_group = IsolateGroup::Current();
+ Thread* T = Thread::Current();
+ IsolateGroup* isolate_group = T->isolate_group();
CHECK_ISOLATE_GROUP(isolate_group);
- NoSafepointScope no_safepoint_scope;
+ TransitionToVM transition(T);
ApiState* state = isolate_group->api_state();
ASSERT(state != NULL);
ASSERT(state->IsActiveWeakPersistentHandle(object));
diff --git a/tests/ffi/regress_flutter97301_test.dart b/tests/ffi/regress_flutter97301_test.dart
index c330d70..e0f844d 100644
--- a/tests/ffi/regress_flutter97301_test.dart
+++ b/tests/ffi/regress_flutter97301_test.dart
@@ -18,4 +18,6 @@
for (var i = 0; i < 2; i++) {
print(offsetsPtr.asTypedList(1));
}
+
+ calloc.free(offsetsPtr);
}
diff --git a/tests/ffi_2/regress_flutter97301_test.dart b/tests/ffi_2/regress_flutter97301_test.dart
index 1417a7a..83f97c7 100644
--- a/tests/ffi_2/regress_flutter97301_test.dart
+++ b/tests/ffi_2/regress_flutter97301_test.dart
@@ -20,4 +20,6 @@
for (var i = 0; i < 2; i++) {
print(offsetsPtr.asTypedList(1));
}
+
+ calloc.free(offsetsPtr);
}
diff --git a/tools/VERSION b/tools/VERSION
index 551b152..ff3bbc2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 80
+PRERELEASE 81
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index a3d9215..740881b 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -278,6 +278,8 @@
"out/DebugSIMARM64/",
"out/DebugSIMARM64C/",
"out/DebugSIMARM_X64/",
+ "out/DebugSIMRISCV32/",
+ "out/DebugSIMRISCV64/",
"out/DebugAndroidARM/",
"out/DebugAndroidARM_X64/",
"out/DebugAndroidARM64/",
@@ -289,6 +291,8 @@
"out/ReleaseSIMARM64/",
"out/ReleaseSIMARM64C/",
"out/ReleaseSIMARM_X64/",
+ "out/ReleaseSIMRISCV32/",
+ "out/ReleaseSIMRISCV64/",
"out/ReleaseAndroidARM/",
"out/ReleaseAndroidARM_X64/",
"out/ReleaseAndroidARM64/",
@@ -306,6 +310,8 @@
"out/ProductSIMARM64/",
"out/ProductSIMARM64C/",
"out/ProductSIMARM_X64/",
+ "out/ProductSIMRISCV32/",
+ "out/ProductSIMRISCV64/",
"out/ProductAndroidARM/",
"out/ProductAndroidARM64/",
"out/ProductAndroidARM64C/",
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index bd07d3a..19cbb45 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -72,7 +72,7 @@
if (defined(invoker.dot_packages)) {
dot_packages = invoker.dot_packages
} else {
- dot_packages = rebase_path("$_dart_root/.packages")
+ dot_packages = rebase_path("$_dart_root/.dart_tool/package_config.json")
}
output = "$root_gen_dir/$name.dart.snapshot"
if (defined(invoker.output)) {
@@ -197,7 +197,8 @@
# Any build dependencies.
#
# dot_packages (optional):
-# The .packages file for the app. Defaults to the $_dart_root/.packages.
+# The package config file for the app. Defaults to
+# $_dart_root/.dart_tool/package_config.json.
#
# output (optional):
# Overrides the full output path.
@@ -230,7 +231,8 @@
# Any build dependencies.
#
# dot_packages (optional):
-# The .packages file for the app. Defaults to the $_dart_root/.packages.
+# The packages config file for the app. Defaults to
+# $_dart_root/.dart_tool/package_config.json.
#
# output (optional):
# Overrides the full output path.