Version 2.12.0-104.0.dev
Merge commit '95ad66642eab0c1dbd97d8743276391e1cd56af1' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart b/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
index 828e28e..561d209 100644
--- a/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
+++ b/pkg/analysis_server/lib/src/services/completion/yaml/yaml_completion_generator.dart
@@ -4,6 +4,7 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/completion/yaml/producer.dart';
+import 'package:analysis_server/src/utilities/extensions/yaml.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:yaml/yaml.dart';
@@ -182,62 +183,3 @@
replacementOffset = 0,
replacementLength = 0;
}
-
-extension on YamlMap {
- /// Return the node representing the key that corresponds to the value
- /// represented by the [value] node.
- YamlNode keyAtValue(YamlNode value) {
- for (var entry in nodes.entries) {
- if (entry.value == value) {
- return entry.key;
- }
- }
- return null;
- }
-}
-
-extension on YamlNode {
- /// Return the child of this node that contains the given [offset], or `null`
- /// if none of the children contains the offset.
- YamlNode childContainingOffset(int offset) {
- var node = this;
- if (node is YamlList) {
- for (var element in node.nodes) {
- if (element.containsOffset(offset)) {
- return element;
- }
- }
- for (var element in node.nodes) {
- if (element is YamlScalar && element.value == null) {
- // TODO(brianwilkerson) Testing for a null value probably gets
- // confused when there are multiple null values.
- return element;
- }
- }
- } else if (node is YamlMap) {
- for (var entry in node.nodes.entries) {
- if ((entry.key as YamlNode).containsOffset(offset)) {
- return entry.key;
- }
- var value = entry.value;
- if (value.containsOffset(offset) ||
- (value is YamlScalar && value.value == null)) {
- // TODO(brianwilkerson) Testing for a null value probably gets
- // confused when there are multiple null values or when there is a
- // null value before the node that actually contains the offset.
- return entry.value;
- }
- }
- }
- return null;
- }
-
- /// Return `true` if this node contains the given [offset].
- bool containsOffset(int offset) {
- // TODO(brianwilkerson) Nodes at the end of the file contain any trailing
- // whitespace. This needs to be accounted for, here or elsewhere.
- var nodeOffset = span.start.offset;
- var nodeEnd = nodeOffset + span.length;
- return nodeOffset <= offset && offset <= nodeEnd;
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
index 5b57f61..351608c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/transform_set_parser.dart
@@ -1033,18 +1033,3 @@
}
}
}
-
-extension on YamlMap {
- // TODO(brianwilkerson) Copied from YamlCompletionGenerator. Refactor to a
- // utility file that is shared between them.
- /// Return the node representing the key that corresponds to the value
- /// represented by the [value] node.
- YamlNode keyAtValue(YamlNode value) {
- for (var entry in nodes.entries) {
- if (entry.value == value) {
- return entry.key;
- }
- }
- return null;
- }
-}
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart b/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
index 0107f62..6ce971a 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/yaml.dart
@@ -5,6 +5,17 @@
import 'package:yaml/yaml.dart';
extension YamlMapExtensions on YamlMap {
+ /// Return the node representing the key that corresponds to the value
+ /// represented by the [value] node.
+ YamlNode keyAtValue(YamlNode value) {
+ for (var entry in nodes.entries) {
+ if (entry.value == value) {
+ return entry.key;
+ }
+ }
+ return null;
+ }
+
/// Return the value associated with the key whose value matches the given
/// [key], or `null` if there is no matching key.
YamlNode valueAt(String key) {
@@ -16,3 +27,49 @@
return null;
}
}
+
+extension YamlNodeExtensions on YamlNode {
+ /// Return the child of this node that contains the given [offset], or `null`
+ /// if none of the children contains the offset.
+ YamlNode childContainingOffset(int offset) {
+ var node = this;
+ if (node is YamlList) {
+ for (var element in node.nodes) {
+ if (element.containsOffset(offset)) {
+ return element;
+ }
+ }
+ for (var element in node.nodes) {
+ if (element is YamlScalar && element.value == null) {
+ // TODO(brianwilkerson) Testing for a null value probably gets
+ // confused when there are multiple null values.
+ return element;
+ }
+ }
+ } else if (node is YamlMap) {
+ for (var entry in node.nodes.entries) {
+ if ((entry.key as YamlNode).containsOffset(offset)) {
+ return entry.key;
+ }
+ var value = entry.value;
+ if (value.containsOffset(offset) ||
+ (value is YamlScalar && value.value == null)) {
+ // TODO(brianwilkerson) Testing for a null value probably gets
+ // confused when there are multiple null values or when there is a
+ // null value before the node that actually contains the offset.
+ return entry.value;
+ }
+ }
+ }
+ return null;
+ }
+
+ /// Return `true` if this node contains the given [offset].
+ bool containsOffset(int offset) {
+ // TODO(brianwilkerson) Nodes at the end of the file contain any trailing
+ // whitespace. This needs to be accounted for, here or elsewhere.
+ var nodeOffset = span.start.offset;
+ var nodeEnd = nodeOffset + span.length;
+ return nodeOffset <= offset && offset <= nodeEnd;
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index ae9ae5d..2efd369 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -5950,11 +5950,12 @@
if (builder?.next != null) {
// Duplicated name, already reported.
return <Initializer>[
- new LocalInitializer(new VariableDeclaration.forValue(buildProblem(
- fasta.templateDuplicatedDeclarationUse.withArguments(name),
- fieldNameOffset,
- name.length)))
- ..fileOffset = fieldNameOffset
+ buildInvalidInitializer(
+ buildProblem(
+ fasta.templateDuplicatedDeclarationUse.withArguments(name),
+ fieldNameOffset,
+ name.length),
+ fieldNameOffset)
];
} else if (builder is FieldBuilder && builder.isDeclarationInstanceMember) {
initializedFields ??= <String, int>{};
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect
index 02fa4fc..92572f2 100644
--- a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.expect
@@ -21,7 +21,7 @@
constructor •(core::int* a) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
A(this.a);
- ^", super core::Object::•()
+ ^"
;
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect
index 02fa4fc..92572f2 100644
--- a/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/duplicated_field_initializer.dart.strong.transformed.expect
@@ -21,7 +21,7 @@
constructor •(core::int* a) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/duplicated_field_initializer.dart:8:10: Error: Can't use 'a' because it is declared more than once.
A(this.a);
- ^", super core::Object::•()
+ ^"
;
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general/issue38938.dart.strong.expect b/pkg/front_end/testcases/general/issue38938.dart.strong.expect
index ffb21f8..2ed9c3f 100644
--- a/pkg/front_end/testcases/general/issue38938.dart.strong.expect
+++ b/pkg/front_end/testcases/general/issue38938.dart.strong.expect
@@ -21,7 +21,7 @@
constructor •(core::int* v) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue38938.dart:8:10: Error: Can't use 'v' because it is declared more than once.
A(this.v);
- ^", super core::Object::•()
+ ^"
;
constructor second() → self::A*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect
index ffb21f8..2ed9c3f 100644
--- a/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue38938.dart.strong.transformed.expect
@@ -21,7 +21,7 @@
constructor •(core::int* v) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue38938.dart:8:10: Error: Can't use 'v' because it is declared more than once.
A(this.v);
- ^", super core::Object::•()
+ ^"
;
constructor second() → self::A*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general/issue43363.dart b/pkg/front_end/testcases/general/issue43363.dart
new file mode 100644
index 0000000..86d91ec
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2020, 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.
+
+class E {
+ final int x;
+ final int y;
+ E() : this.named(),
+ this.x = 1;
+ this.y = 2;
+
+ E.named() : this.x = 5,
+ this.y = 6;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/general/issue43363.dart.outline.expect b/pkg/front_end/testcases/general/issue43363.dart.outline.expect
new file mode 100644
index 0000000..e44f548
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.outline.expect
@@ -0,0 +1,47 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:9: Error: Expected a class member, but got 'this'.
+// this.y = 2;
+// ^^^^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:13: Error: Expected a class member, but got '.'.
+// this.y = 2;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// this.y = 2;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: 'y' is already declared in this scope.
+// this.y = 2;
+// ^
+// pkg/front_end/testcases/general/issue43363.dart:7:13: Context: Previous declaration of 'y'.
+// final int y;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+ final field core::int* x;
+ final field core::int* y;
+ constructor •() → self::E*
+ ;
+ constructor named() → self::E*
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/general/issue43363.dart.strong.expect b/pkg/front_end/testcases/general/issue43363.dart.strong.expect
new file mode 100644
index 0000000..b4cfb49
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.strong.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:9: Error: Expected a class member, but got 'this'.
+// this.y = 2;
+// ^^^^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:13: Error: Expected a class member, but got '.'.
+// this.y = 2;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// this.y = 2;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: 'y' is already declared in this scope.
+// this.y = 2;
+// ^
+// pkg/front_end/testcases/general/issue43363.dart:7:13: Context: Previous declaration of 'y'.
+// final int y;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+// this.x = 1;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+// this.y = 6;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+ final field core::int* x;
+ final field core::int* y = null;
+ constructor •() → self::E*
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+ this.x = 1;
+ ^", this self::E::named()
+ ;
+ constructor named() → self::E*
+ : self::E::x = 5, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+ this.y = 6;
+ ^"
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue43363.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue43363.dart.strong.transformed.expect
new file mode 100644
index 0000000..b4cfb49
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.strong.transformed.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:9: Error: Expected a class member, but got 'this'.
+// this.y = 2;
+// ^^^^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:13: Error: Expected a class member, but got '.'.
+// this.y = 2;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+// Try adding the name of the type of the variable or the keyword 'var'.
+// this.y = 2;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:10:14: Error: 'y' is already declared in this scope.
+// this.y = 2;
+// ^
+// pkg/front_end/testcases/general/issue43363.dart:7:13: Context: Previous declaration of 'y'.
+// final int y;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+// this.x = 1;
+// ^
+//
+// pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+// this.y = 6;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+ final field core::int* x;
+ final field core::int* y = null;
+ constructor •() → self::E*
+ : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:9:16: Error: A redirecting constructor can't have other initializers.
+ this.x = 1;
+ ^", this self::E::named()
+ ;
+ constructor named() → self::E*
+ : self::E::x = 5, final dynamic #t2 = invalid-expression "pkg/front_end/testcases/general/issue43363.dart:13:20: Error: Can't use 'y' because it is declared more than once.
+ this.y = 6;
+ ^"
+ ;
+ abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+ abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+ abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+ abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+ abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+ abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+ abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+ abstract member-signature method toString() → core::String*; -> core::Object::toString
+ abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+ abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue43363.dart.textual_outline.expect b/pkg/front_end/testcases/general/issue43363.dart.textual_outline.expect
new file mode 100644
index 0000000..f2bf39e
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue43363.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+class E {
+ final int x;
+ final int y;
+ E() : this.named(), this.x = 1;
+ this.
+ y = 2;
+ E.named() : this.x = 5, this.y = 6;
+}
+main() {}
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect
index 02b4a69..64e0ad7 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.expect
@@ -21,7 +21,7 @@
constructor •(core::int* a) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart:10:10: Error: Can't use 'a' because it is declared more than once.
A(this.a);
- ^", super core::Object::•()
+ ^"
;
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect
index 02b4a69..64e0ad7 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart.weak.transformed.expect
@@ -21,7 +21,7 @@
constructor •(core::int* a) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/duplicated_field_initializer.dart:10:10: Error: Can't use 'a' because it is declared more than once.
A(this.a);
- ^", super core::Object::•()
+ ^"
;
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect
index c592b47..227ba25 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.expect
@@ -21,7 +21,7 @@
constructor •(core::int* v) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart:10:10: Error: Can't use 'v' because it is declared more than once.
A(this.v);
- ^", super core::Object::•()
+ ^"
;
constructor second() → self::A*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect
index c592b47..227ba25 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart.weak.transformed.expect
@@ -21,7 +21,7 @@
constructor •(core::int* v) → self::A*
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/issue38938.dart:10:10: Error: Can't use 'v' because it is declared more than once.
A(this.v);
- ^", super core::Object::•()
+ ^"
;
constructor second() → self::A*
: super core::Object::•()
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index ab8fac6..0553975 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -118,6 +118,7 @@
general/invalid_operator: FormatterCrash
general/issue40242: FormatterCrash
general/issue42997: FormatterCrash
+general/issue43363: FormatterCrash
general/many_errors: FormatterCrash
general/null_safety_invalid_experiment_and_language_version: FormatterCrash
general/type_parameter_usage_in_static_method_in_extension: FormatterCrash
@@ -169,9 +170,9 @@
late_lowering/later: FormatterCrash
late_lowering/override: FormatterCrash
late_lowering/override_getter_setter: FormatterCrash
+late_lowering/skip_late_final_uninitialized_instance_fields/main: FormatterCrash
late_lowering/uninitialized_non_nullable_late_fields: FormatterCrash
late_lowering_sentinel/late_fields: FormatterCrash
-late_lowering/skip_late_final_uninitialized_instance_fields/main: FormatterCrash
nnbd/abstract_field_errors: FormatterCrash
nnbd/covariant_late_field: FormatterCrash
nnbd/definitely_unassigned: FormatterCrash
@@ -260,3 +261,4 @@
variance/generic_covariance_sound_variance: FormatterCrash
variance/mixin_type_parameter_modifier: FormatterCrash
variance/unconstrained_inference: FormatterCrash
+
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index db90835..4dff755 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -615,7 +615,18 @@
@override
void onException(String detail) {
- if (_hasExceptions) return;
+ if (_hasExceptions) {
+ if (!options.ignoreExceptions) {
+ // Our intention is to exit immediately when an exception occurred. We
+ // tried, but failed (probably due to permissive mode logic in the
+ // migration tool itself catching the MigrationExit exception). The
+ // stack has now been unwound further, so throw again.
+ throw MigrationExit(1);
+ }
+ // We're not exiting immediately when an exception occurs. We've already
+ // reported that an exception happened. So do nothing further.
+ return;
+ }
_hasExceptions = true;
if (options.ignoreExceptions) {
logger.stdout('''
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 5fac352..7003df0 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -2144,15 +2144,20 @@
}
DecoratedType _dispatch(AstNode node, {bool skipNullCheckHint = false}) {
- var type = node?.accept(this);
- if (!skipNullCheckHint &&
- node is Expression &&
- // A /*!*/ hint following an AsExpression should be interpreted as a
- // nullability hint for the type, not a null-check hint.
- node is! AsExpression) {
- type = _handleNullCheckHint(node, type);
+ try {
+ var type = node?.accept(this);
+ if (!skipNullCheckHint &&
+ node is Expression &&
+ // A /*!*/ hint following an AsExpression should be interpreted as a
+ // nullability hint for the type, not a null-check hint.
+ node is! AsExpression) {
+ type = _handleNullCheckHint(node, type);
+ }
+ return type;
+ } catch (exception, stackTrace) {
+ listener.reportException(source, node, exception, stackTrace);
+ return null;
}
- return type;
}
void _dispatchList(NodeList nodeList) {
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 16f8003..d746ac6 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -692,7 +692,12 @@
}
test_lifecycle_exception_handling_ignore() async {
- var projectContents = simpleProject(sourceText: 'main() { print(0); }');
+ var projectContents = simpleProject(sourceText: '''
+main() {
+ print(0);
+ int x = null;
+}
+''');
var projectDir = createProjectDir(projectContents);
injectArtificialException = true;
var cli = _createCli();
@@ -707,6 +712,14 @@
' of --ignore-exceptions.'));
expect(output, contains('re-run without --ignore-exceptions'));
await assertPreviewServerResponsive(url);
+ await _tellPreviewToApplyChanges(url);
+ assertProjectContents(
+ projectDir, simpleProject(migrated: true, sourceText: '''
+main() {
+ print(0);
+ int? x = null;
+}
+'''));
});
expect(logger.stderrBuffer.toString(), isEmpty);
}
@@ -982,14 +995,7 @@
expect(
logger.stdoutBuffer.toString(), contains('No analysis issues found'));
await assertPreviewServerResponsive(url);
- var uri = Uri.parse(url);
- var authToken = uri.queryParameters['authToken'];
- var response = await httpPost(
- uri.replace(
- path: PreviewSite.applyMigrationPath,
- queryParameters: {'authToken': authToken}),
- headers: {'Content-Type': 'application/json; charset=UTF-8'});
- assertHttpSuccess(response);
+ await _tellPreviewToApplyChanges(url);
expect(applyHookCalled, true);
});
}
@@ -2113,6 +2119,17 @@
ArgResults _parseArgs(List<String> args) {
return MigrationCli.createParser().parse(args);
}
+
+ Future<void> _tellPreviewToApplyChanges(String url) async {
+ var uri = Uri.parse(url);
+ var authToken = uri.queryParameters['authToken'];
+ var response = await httpPost(
+ uri.replace(
+ path: PreviewSite.applyMigrationPath,
+ queryParameters: {'authToken': authToken}),
+ headers: {'Content-Type': 'application/json; charset=UTF-8'});
+ assertHttpSuccess(response);
+ }
}
@reflectiveTest
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 6cd97fc..52a98e6 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -134,9 +134,7 @@
/// If [getAllSources] is false it will ask specifically for report
/// (and thus hits) for "lib1.dart" only.
Future<Set<int>> collectAndCheckCoverageData(int port, bool getAllSources,
- {bool resume: true,
- bool onGetAllVerifyCount: true,
- Set<int> coverageForLines}) async {
+ {bool resume: true}) async {
RemoteVm remoteVm = new RemoteVm(port);
// Wait for the script to have finished.
@@ -191,7 +189,7 @@
}
i++;
}
- if (getAllSources && onGetAllVerifyCount) {
+ if (getAllSources) {
expect(scriptIdToIndex.length >= 2, isTrue);
}
@@ -228,16 +226,12 @@
}
}
for (int pos in coverage["misses"]) positions.add(pos);
- if (range["possibleBreakpoints"] != null) {
- for (int pos in range["possibleBreakpoints"]) positions.add(pos);
- }
+ for (int pos in range["possibleBreakpoints"]) positions.add(pos);
Map script = scriptIndexToScript[range["scriptIndex"]];
Set<int> knownPositions = new Set<int>();
- Map<int, int> tokenPosToLine = {};
if (script["tokenPosTable"] != null) {
for (List tokenPosTableLine in script["tokenPosTable"]) {
for (int i = 1; i < tokenPosTableLine.length; i += 2) {
- tokenPosToLine[tokenPosTableLine[i]] = tokenPosTableLine[0];
knownPositions.add(tokenPosTableLine[i]);
}
}
@@ -250,14 +244,6 @@
"line and column.");
}
}
-
- if (coverageForLines != null) {
- for (int pos in coverage["hits"]) {
- if (lib1scriptIndices.contains(range["scriptIndex"])) {
- coverageForLines.add(tokenPosToLine[pos]);
- }
- }
- }
}
}
}
@@ -500,243 +486,6 @@
});
});
- group('multiple kernels constant coverage', () {
- Directory mytest;
- File main;
- File lib1;
- int lineForUnnamedConstructor;
- int lineForNamedConstructor;
- Process vm;
- setUpAll(() {
- mytest = Directory.systemTemp.createTempSync('incremental');
- main = new File('${mytest.path}/main.dart')..createSync();
- main.writeAsStringSync("""
- // This file - combined with the lib - should have coverage for both
- // constructors of Foo.
- import 'lib1.dart' as lib1;
-
- void testFunction() {
- const foo = lib1.Foo.named();
- const foo2 = lib1.Foo.named();
- if (!identical(foo, foo2)) throw "what?";
- }
-
- main() {
- lib1.testFunction();
- testFunction();
- print("main");
- }
- """);
- lib1 = new File('${mytest.path}/lib1.dart')..createSync();
- lib1.writeAsStringSync("""
- // Compiling this file should mark the default constructor - but not the
- // named constructor - as having coverage.
- class Foo {
- final int x;
- const Foo([int? x]) : this.x = x ?? 42;
- const Foo.named([int? x]) : this.x = x ?? 42;
- }
-
- void testFunction() {
- const foo = Foo();
- const foo2 = Foo();
- if (!identical(foo, foo2)) throw "what?";
- }
-
- main() {
- testFunction();
- print("lib1");
- }
- """);
- lineForUnnamedConstructor = 5;
- lineForNamedConstructor = 6;
- });
-
- tearDownAll(() {
- try {
- mytest.deleteSync(recursive: true);
- } catch (_) {
- // Ignore errors;
- }
- try {
- vm.kill();
- } catch (_) {
- // Ignore errors;
- }
- });
-
- Future<Set<int>> runAndGetLineCoverage(
- File list, String expectStdoutContains) async {
- vm = await Process.start(Platform.resolvedExecutable, <String>[
- "--pause-isolates-on-exit",
- "--enable-vm-service:0",
- "--disable-service-auth-codes",
- "--disable-dart-dev",
- list.path
- ]);
-
- const kObservatoryListening = 'Observatory listening on ';
- final RegExp observatoryPortRegExp =
- new RegExp("Observatory listening on http://127.0.0.1:\([0-9]*\)");
- int port;
- final splitter = new LineSplitter();
- Completer<String> portLineCompleter = new Completer<String>();
- Set<int> coverageLines = {};
- bool foundExpectedString = false;
- vm.stdout
- .transform(utf8.decoder)
- .transform(splitter)
- .listen((String s) async {
- if (s == expectStdoutContains) {
- foundExpectedString = true;
- }
- if (s.startsWith(kObservatoryListening)) {
- expect(observatoryPortRegExp.hasMatch(s), isTrue);
- final match = observatoryPortRegExp.firstMatch(s);
- port = int.parse(match.group(1));
- await collectAndCheckCoverageData(port, true,
- onGetAllVerifyCount: false, coverageForLines: coverageLines);
- if (!portLineCompleter.isCompleted) {
- portLineCompleter.complete("done");
- }
- }
- print("vm stdout: $s");
- });
- vm.stderr.transform(utf8.decoder).transform(splitter).listen((String s) {
- print("vm stderr: $s");
- });
- await portLineCompleter.future;
- print("Compiler terminated with ${await vm.exitCode} exit code");
- expect(foundExpectedString, isTrue);
- return coverageLines;
- }
-
- test('compile seperatly, check coverage', () async {
- Directory dir = mytest.createTempSync();
-
- // First compile lib, run and verify coverage (un-named constructor
- // covered, but not the named constructor).
- // Note that it's called 'lib1' to match with expectations from coverage
- // collector helper in this file.
- File libDill = File(p.join(dir.path, p.basename(lib1.path + ".dill")));
- IncrementalCompiler compiler = new IncrementalCompiler(options, lib1.uri);
- Component component = await compiler.compile();
- expect(component.libraries.length, equals(1));
- expect(component.libraries.single.fileUri, equals(lib1.uri));
- IOSink sink = libDill.openWrite();
- BinaryPrinter printer = new BinaryPrinter(sink);
- printer.writeComponentFile(component);
- await sink.flush();
- await sink.close();
- File list = new File(p.join(dir.path, 'dill.list'))..createSync();
- list.writeAsStringSync("#@dill\n${libDill.path}\n");
- Set<int> lineCoverage = await runAndGetLineCoverage(list, "lib1");
- // Expect coverage for unnamed constructor but not for the named one.
- expect(
- lineCoverage.intersection(
- {lineForUnnamedConstructor, lineForNamedConstructor}),
- equals({lineForUnnamedConstructor}));
-
- try {
- vm.kill();
- } catch (_) {
- // Ignore errors;
- }
- // Accept the compile to not include the lib again.
- compiler.accept();
-
- // Then compile lib, run and verify coverage (un-named constructor
- // covered, and the named constructor coveraged too).
- File mainDill = File(p.join(dir.path, p.basename(main.path + ".dill")));
- component = await compiler.compile(entryPoint: main.uri);
- expect(component.libraries.length, equals(1));
- expect(component.libraries.single.fileUri, equals(main.uri));
- sink = mainDill.openWrite();
- printer = new BinaryPrinter(sink);
- printer.writeComponentFile(component);
- await sink.flush();
- await sink.close();
- list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
- lineCoverage = await runAndGetLineCoverage(list, "main");
-
- // Expect coverage for both unnamed constructor and for the named one.
- expect(
- lineCoverage.intersection(
- {lineForUnnamedConstructor, lineForNamedConstructor}),
- equals({lineForUnnamedConstructor, lineForNamedConstructor}));
-
- try {
- vm.kill();
- } catch (_) {
- // Ignore errors;
- }
- // Accept the compile to not include the lib again.
- compiler.accept();
-
- // Finally, change lib to shift the constructors so the old line numbers
- // doesn't match. Compile lib by itself, compile lib, run with the old
- // main and verify coverage is still correct (both un-named constructor
- // and named constructor (at new line numbers) are covered, and the old
- // line numbers are not coverage.
-
- lib1.writeAsStringSync("""
- //
- // Shift lines down by five
- // lines so the original
- // lines can't be coverred
- //
- class Foo {
- final int x;
- const Foo([int? x]) : this.x = x ?? 42;
- const Foo.named([int? x]) : this.x = x ?? 42;
- }
-
- void testFunction() {
- const foo = Foo();
- const foo2 = Foo();
- if (!identical(foo, foo2)) throw "what?";
- }
-
- main() {
- testFunction();
- print("lib1");
- }
- """);
- int newLineForUnnamedConstructor = 8;
- int newLineForNamedConstructor = 9;
- compiler.invalidate(lib1.uri);
- component = await compiler.compile(entryPoint: lib1.uri);
- expect(component.libraries.length, equals(1));
- expect(component.libraries.single.fileUri, equals(lib1.uri));
- sink = libDill.openWrite();
- printer = new BinaryPrinter(sink);
- printer.writeComponentFile(component);
- await sink.flush();
- await sink.close();
- list.writeAsStringSync("#@dill\n${mainDill.path}\n${libDill.path}\n");
- lineCoverage = await runAndGetLineCoverage(list, "main");
-
- // Expect coverage for both unnamed constructor and for the named one on
- // the new positions, but no coverage on the old positions.
- expect(
- lineCoverage.intersection({
- lineForUnnamedConstructor,
- lineForNamedConstructor,
- newLineForUnnamedConstructor,
- newLineForNamedConstructor
- }),
- equals({newLineForUnnamedConstructor, newLineForNamedConstructor}));
-
- try {
- vm.kill();
- } catch (_) {
- // Ignore errors;
- }
- // Accept the compile to not include the lib again.
- compiler.accept();
- });
- });
-
group('multiple kernels 2', () {
Directory mytest;
File main;
diff --git a/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart b/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart
deleted file mode 100644
index b0f078d..0000000
--- a/runtime/observatory/tests/service/get_source_report_const_coverage_lib.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2020, 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 "get_source_report_const_coverage_test.dart";
-
-void testFunction() {
- const namedFoo = Foo.named3();
- const namedFoo2 = Foo.named3();
- const namedIdentical = identical(namedFoo, namedFoo2);
- print("namedIdentical: $namedIdentical");
-}
diff --git a/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart b/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart
deleted file mode 100644
index 32cb035..0000000
--- a/runtime/observatory/tests/service/get_source_report_const_coverage_test.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2020, 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:observatory/service_io.dart';
-import 'package:test/test.dart';
-import 'test_helper.dart';
-import 'service_test_common.dart';
-import 'dart:developer';
-
-import 'get_source_report_const_coverage_lib.dart' as lib;
-
-const String filename = "get_source_report_const_coverage_test";
-const Set<int> expectedLinesHit = {20, 22, 26};
-const Set<int> expectedLinesNotHit = {24};
-
-class Foo {
- final int x;
- // Expect this constructor to be coverage by coverage.
- const Foo([int? x]) : this.x = x ?? 42;
- // Expect this constructor to be coverage by coverage too.
- const Foo.named1([int? x]) : this.x = x ?? 42;
- // Expect this constructor to *NOT* be coverage by coverage.
- const Foo.named2([int? x]) : this.x = x ?? 42;
- // Expect this constructor to be coverage by coverage too (from lib).
- const Foo.named3([int? x]) : this.x = x ?? 42;
-}
-
-void testFunction() {
- const foo = Foo();
- const foo2 = Foo();
- const fooIdentical = identical(foo, foo2);
- print(fooIdentical);
-
- const namedFoo = Foo.named1();
- const namedFoo2 = Foo.named1();
- const namedIdentical = identical(namedFoo, namedFoo2);
- print(fooIdentical);
-
- debugger();
-
- // That this is called after (or at all) is not relevent for the code
- // coverage of constants.
- lib.testFunction();
-
- print("Done");
-}
-
-var tests = <IsolateTest>[
- hasStoppedAtBreakpoint,
- (Isolate isolate) async {
- final stack = await isolate.getStack();
-
- // Make sure we are in the right place.
- expect(stack.type, equals('Stack'));
- expect(stack['frames'].length, greaterThanOrEqualTo(1));
- expect(stack['frames'][0].function.name, equals('testFunction'));
-
- final List<Script> scripts = await isolate.getScripts();
- Script? foundScript;
- for (Script script in scripts) {
- if (script.uri.contains(filename)) {
- foundScript = script;
- break;
- }
- }
-
- Set<int> hits;
- {
- // Get report for everything; then collect for this library.
- final Map<String, Object> params = {
- 'reports': ['Coverage'],
- };
- final coverage =
- await isolate.invokeRpcNoUpgrade('getSourceReport', params);
- hits = getHitsFor(coverage, filename);
- await foundScript!.load();
- final Set<int> lines = {};
- for (int hit in hits) {
- // We expect every hit to be translatable to line
- // (i.e. tokenToLine to return non-null).
- lines.add(foundScript.tokenToLine(hit)!);
- }
- print("Token position hits: $hits --- line hits: $lines");
- expect(lines.intersection(expectedLinesHit), equals(expectedLinesHit));
- expect(lines.intersection(expectedLinesNotHit), isEmpty);
- }
- {
- // Now get report for the this file only.
- final Map<String, Object> params = {
- 'reports': ['Coverage'],
- 'scriptId': foundScript.id!
- };
- final coverage =
- await isolate.invokeRpcNoUpgrade('getSourceReport', params);
- final Set<int> localHits = getHitsFor(coverage, filename);
- expect(localHits.length, equals(hits.length));
- expect(hits.toList()..sort(), equals(localHits.toList()..sort()));
- print(localHits);
- }
- },
-];
-
-Set<int> getHitsFor(Map coverage, String uriContains) {
- final List scripts = coverage["scripts"];
- final Set<int> scriptIdsWanted = {};
- for (int i = 0; i < scripts.length; i++) {
- final Map script = scripts[i];
- final String scriptUri = script["uri"];
- if (scriptUri.contains(uriContains)) {
- scriptIdsWanted.add(i);
- }
- }
- final List ranges = coverage["ranges"];
- final Set<int> hits = {};
- for (int i = 0; i < ranges.length; i++) {
- final Map range = ranges[i];
- if (scriptIdsWanted.contains(range["scriptIndex"])) {
- if (range["coverage"] != null) {
- for (int hit in range["coverage"]["hits"]) {
- hits.add(hit);
- }
- }
- }
- }
- return hits;
-}
-
-main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index a1d5206..adea481 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -91,7 +91,7 @@
final numRanges = coverage['ranges'].length;
expect(coverage['type'], equals('SourceReport'));
- expect(numRanges, equals(11));
+ expect(numRanges, equals(10));
expect(coverage['ranges'][0], equals(expectedRange));
expect(coverage['scripts'].length, 1);
expect(
@@ -106,7 +106,7 @@
};
coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
expect(coverage['type'], equals('SourceReport'));
- expect(coverage['ranges'].length, 12);
+ expect(coverage['ranges'].length, 11);
expect(allRangesCompiled(coverage), isTrue);
// One function
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index c92c5e5..7a297eb 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -109,7 +109,6 @@
get_allocation_samples_test: Skip, Timeout
get_isolate_after_language_error_test: CompileTimeError
get_object_rpc_test: SkipByDesign
-get_source_report_const_coverage_test: SkipByDesign
get_source_report_test: Skip, Timeout
get_source_report_with_mixin_test: Skip, Timeout
get_stack_limit_rpc_test: Skip, Timeout
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart
deleted file mode 100644
index b0f078d..0000000
--- a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_lib.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2020, 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 "get_source_report_const_coverage_test.dart";
-
-void testFunction() {
- const namedFoo = Foo.named3();
- const namedFoo2 = Foo.named3();
- const namedIdentical = identical(namedFoo, namedFoo2);
- print("namedIdentical: $namedIdentical");
-}
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart b/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart
deleted file mode 100644
index 7c6af16..0000000
--- a/runtime/observatory_2/tests/service_2/get_source_report_const_coverage_test.dart
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2020, 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:observatory_2/service_io.dart';
-import 'package:test/test.dart';
-import 'test_helper.dart';
-import 'service_test_common.dart';
-import 'dart:developer';
-
-import 'get_source_report_const_coverage_lib.dart' as lib;
-
-const String filename = "get_source_report_const_coverage_test";
-const Set<int> expectedLinesHit = {20, 22, 26};
-const Set<int> expectedLinesNotHit = {24};
-
-class Foo {
- final int x;
- // Expect this constructor to be coverage by coverage.
- const Foo([int x]) : this.x = x ?? 42;
- // Expect this constructor to be coverage by coverage too.
- const Foo.named1([int x]) : this.x = x ?? 42;
- // Expect this constructor to *NOT* be coverage by coverage.
- const Foo.named2([int x]) : this.x = x ?? 42;
- // Expect this constructor to be coverage by coverage too (from lib).
- const Foo.named3([int x]) : this.x = x ?? 42;
-}
-
-void testFunction() {
- const foo = Foo();
- const foo2 = Foo();
- const fooIdentical = identical(foo, foo2);
- print(fooIdentical);
-
- const namedFoo = Foo.named1();
- const namedFoo2 = Foo.named1();
- const namedIdentical = identical(namedFoo, namedFoo2);
- print(fooIdentical);
-
- debugger();
-
- // That this is called after (or at all) is not relevent for the code
- // coverage of constants.
- lib.testFunction();
-
- print("Done");
-}
-
-var tests = <IsolateTest>[
- hasStoppedAtBreakpoint,
- (Isolate isolate) async {
- final stack = await isolate.getStack();
-
- // Make sure we are in the right place.
- expect(stack.type, equals('Stack'));
- expect(stack['frames'].length, greaterThanOrEqualTo(1));
- expect(stack['frames'][0].function.name, equals('testFunction'));
-
- final List<Script> scripts = await isolate.getScripts();
- Script foundScript;
- for (Script script in scripts) {
- if (script.uri.contains(filename)) {
- foundScript = script;
- break;
- }
- }
-
- Set<int> hits;
- {
- // Get report for everything; then collect for this library.
- final Map<String, Object> params = {
- 'reports': ['Coverage'],
- };
- final coverage =
- await isolate.invokeRpcNoUpgrade('getSourceReport', params);
- hits = getHitsFor(coverage, filename);
- await foundScript.load();
- final Set<int> lines = {};
- for (int hit in hits) {
- // We expect every hit to be translatable to line
- // (i.e. tokenToLine to return non-null).
- lines.add(foundScript.tokenToLine(hit));
- }
- print("Token position hits: $hits --- line hits: $lines");
- expect(lines.intersection(expectedLinesHit), equals(expectedLinesHit));
- expect(lines.intersection(expectedLinesNotHit), isEmpty);
- }
- {
- // Now get report for the this file only.
- final Map<String, Object> params = {
- 'reports': ['Coverage'],
- 'scriptId': foundScript.id
- };
- final coverage =
- await isolate.invokeRpcNoUpgrade('getSourceReport', params);
- final Set<int> localHits = getHitsFor(coverage, filename);
- expect(localHits.length, equals(hits.length));
- expect(hits.toList()..sort(), equals(localHits.toList()..sort()));
- print(localHits);
- }
- },
-];
-
-Set<int> getHitsFor(Map coverage, String uriContains) {
- final List scripts = coverage["scripts"];
- final Set<int> scriptIdsWanted = {};
- for (int i = 0; i < scripts.length; i++) {
- final Map script = scripts[i];
- final String scriptUri = script["uri"];
- if (scriptUri.contains(uriContains)) {
- scriptIdsWanted.add(i);
- }
- }
- final List ranges = coverage["ranges"];
- final Set<int> hits = {};
- for (int i = 0; i < ranges.length; i++) {
- final Map range = ranges[i];
- if (scriptIdsWanted.contains(range["scriptIndex"])) {
- if (range["coverage"] != null) {
- for (int hit in range["coverage"]["hits"]) {
- hits.add(hit);
- }
- }
- }
- }
- return hits;
-}
-
-main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/observatory_2/tests/service_2/get_source_report_test.dart b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
index 78ea471..97606de 100644
--- a/runtime/observatory_2/tests/service_2/get_source_report_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_source_report_test.dart
@@ -91,7 +91,7 @@
final numRanges = coverage['ranges'].length;
expect(coverage['type'], equals('SourceReport'));
- expect(numRanges, equals(11));
+ expect(numRanges, equals(10));
expect(coverage['ranges'][0], equals(expectedRange));
expect(coverage['scripts'].length, 1);
expect(
@@ -106,7 +106,7 @@
};
coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
expect(coverage['type'], equals('SourceReport'));
- expect(coverage['ranges'].length, 12);
+ expect(coverage['ranges'].length, 11);
expect(allRangesCompiled(coverage), isTrue);
// One function
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status
index e8d4784..d8996be 100644
--- a/runtime/observatory_2/tests/service_2/service_2_kernel.status
+++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -109,7 +109,6 @@
get_allocation_samples_test: Skip, Timeout
get_isolate_after_language_error_test: CompileTimeError
get_object_rpc_test: SkipByDesign
-get_source_report_const_coverage_test: SkipByDesign
get_source_report_test: Skip, Timeout
get_source_report_with_mixin_test: Skip, Timeout
get_stack_limit_rpc_test: Skip, Timeout
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 83f434f..15d0a86 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -891,9 +891,7 @@
Fragment implicit_type_checks;
if (dart_function.NeedsTypeArgumentTypeChecks()) {
B->BuildTypeArgumentTypeChecks(
- dart_function.CanReceiveDynamicInvocation()
- ? TypeChecksToBuild::kCheckAllTypeParameterBounds
- : TypeChecksToBuild::kCheckCovariantTypeParameterBounds,
+ TypeChecksToBuild::kCheckCovariantTypeParameterBounds,
&implicit_type_checks);
}
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 1620bbf..105feaa 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -3749,10 +3749,9 @@
const bool signature_contains_handles = marshaller.ContainsHandles();
- ASSERT(function.CanReceiveDynamicInvocation());
- BuildTypeArgumentTypeChecks(TypeChecksToBuild::kCheckAllTypeParameterBounds,
- &function_body);
- BuildArgumentTypeChecks(&function_body, &function_body, &function_body);
+ // FFI trampolines are accessed via closures, so non-covariant argument types
+ // and type arguments are either statically checked by the type system or
+ // dynamically checked via dynamic closure call dispatchers.
// Null check arguments before we go into the try catch, so that we don't
// catch our own null errors.
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 6cc0183..e706302 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2807,33 +2807,6 @@
return H.DartString(reader_.BufferAt(ReaderOffset()), size, Heap::kOld);
}
-ExternalTypedDataPtr KernelReaderHelper::GetConstantCoverageFor(
- intptr_t index) {
- AlternativeReadingScope alt(&reader_);
- SetOffset(GetOffsetForSourceInfo(index));
- SkipBytes(ReadUInt()); // skip uri.
- SkipBytes(ReadUInt()); // skip source.
- const intptr_t line_start_count = ReadUInt(); // read number of line start
- // entries.
- for (intptr_t i = 0; i < line_start_count; ++i) {
- ReadUInt();
- }
-
- SkipBytes(ReadUInt()); // skip import uri.
-
- intptr_t start_offset = ReaderOffset();
-
- // Read past "constant coverage constructors".
- const intptr_t constant_coverage_constructors = ReadUInt();
- for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
- ReadUInt();
- }
-
- intptr_t end_offset = ReaderOffset();
-
- return reader_.ExternalDataFromTo(start_offset, end_offset);
-}
-
intptr_t ActiveClass::MemberTypeParameterCount(Zone* zone) {
ASSERT(member != NULL);
if (member->IsFactory()) {
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 28877d0..d725cf7 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -1244,7 +1244,6 @@
const String& GetSourceFor(intptr_t index);
TypedDataPtr GetLineStartsFor(intptr_t index);
String& SourceTableImportUriFor(intptr_t index, uint32_t binaryVersion);
- ExternalTypedDataPtr GetConstantCoverageFor(intptr_t index);
Zone* zone_;
TranslationHelper& translation_helper_;
@@ -1283,8 +1282,6 @@
friend class ObfuscationProhibitionsMetadataHelper;
friend class LoadingUnitsMetadataHelper;
friend bool NeedsDynamicInvocationForwarder(const Function& function);
- friend ArrayPtr CollectConstConstructorCoverageFrom(
- const Script& interesting_script);
private:
DISALLOW_COPY_AND_ASSIGN(KernelReaderHelper);
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index bc1808e..64fb780 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -40,7 +40,6 @@
bool PrologueBuilder::HasEmptyPrologue(const Function& function) {
return !function.HasOptionalParameters() && !function.IsGeneric() &&
- !function.CanReceiveDynamicInvocation() &&
!function.IsClosureFunction();
}
@@ -53,26 +52,12 @@
const bool load_optional_arguments = function_.HasOptionalParameters();
const bool expect_type_args = function_.IsGeneric();
- const bool check_shapes = function_.CanReceiveDynamicInvocation();
Fragment prologue = Fragment(entry);
- // We only check for bad argument shapes and throw NSM in functions that
- // can receive dynamic invocation. Otherwise, the NSM block is never used
- // and so there's no need to create it. The helper methods can only throw
- // NSM in appropriate spots if one was created.
- JoinEntryInstr* nsm = nullptr;
- if (check_shapes) {
- nsm = BuildThrowNoSuchMethod();
- Fragment f = BuildTypeArgumentsLengthCheck(nsm, expect_type_args);
- if (link) prologue += f;
- }
if (load_optional_arguments) {
- Fragment f = BuildOptionalParameterHandling(
- nsm, parsed_function_->expression_temp_var());
- if (link) prologue += f;
- } else if (check_shapes) {
- Fragment f = BuildFixedParameterLengthChecks(nsm);
+ Fragment f =
+ BuildOptionalParameterHandling(parsed_function_->expression_temp_var());
if (link) prologue += f;
}
if (function_.IsClosureFunction()) {
@@ -80,7 +65,7 @@
if (!compiling_for_osr_) prologue += f;
}
if (expect_type_args) {
- Fragment f = BuildTypeArgumentsHandling(nsm);
+ Fragment f = BuildTypeArgumentsHandling();
if (link) prologue += f;
}
@@ -103,57 +88,8 @@
}
}
-Fragment PrologueBuilder::BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
- bool expect_type_args) {
- ASSERT(nsm != nullptr);
- Fragment check_type_args;
- JoinEntryInstr* done = BuildJoinEntry();
-
- // Type args are always optional, so length can always be zero.
- // If expect_type_args, a non-zero length must match the declaration length.
- TargetEntryInstr *then, *fail;
- check_type_args += LoadArgDescriptor();
- check_type_args += LoadNativeField(Slot::ArgumentsDescriptor_type_args_len());
- if (expect_type_args) {
- JoinEntryInstr* join2 = BuildJoinEntry();
-
- LocalVariable* len = MakeTemporary();
-
- TargetEntryInstr* otherwise;
- check_type_args += LoadLocal(len);
- check_type_args += IntConstant(0);
- check_type_args += BranchIfEqual(&then, &otherwise);
-
- TargetEntryInstr* then2;
- Fragment check_len(otherwise);
- check_len += LoadLocal(len);
- check_len += IntConstant(function_.NumTypeParameters());
- check_len += BranchIfEqual(&then2, &fail);
-
- Fragment(then) + Goto(join2);
- Fragment(then2) + Goto(join2);
-
- Fragment(join2) + Drop() + Goto(done);
- Fragment(fail) + Goto(nsm);
- } else {
- check_type_args += IntConstant(0);
- check_type_args += BranchIfEqual(&then, &fail);
- Fragment(then) + Goto(done);
- Fragment(fail) + Goto(nsm);
- }
-
- return Fragment(check_type_args.entry, done);
-}
-
Fragment PrologueBuilder::BuildOptionalParameterHandling(
- JoinEntryInstr* nsm,
LocalVariable* temp_var) {
- // We only need to check the shape of the arguments (correct parameter count
- // and correct names/provided required arguments) when the function can be
- // invoked dynamically. The caller only provides a non-nullptr nsm block if
- // dynamic invocation is possible.
- const bool check_arguments_shape = nsm != nullptr;
-
Fragment copy_args_prologue;
const int num_fixed_params = function_.num_fixed_parameters();
const int num_opt_pos_params = function_.NumOptionalPositionalParameters();
@@ -168,39 +104,15 @@
// Check that min_num_pos_args <= num_pos_args <= max_num_pos_args,
// where num_pos_args is the number of positional arguments passed in.
const int min_num_pos_args = num_fixed_params;
- const int max_num_pos_args = num_fixed_params + num_opt_pos_params;
copy_args_prologue += LoadArgDescriptor();
copy_args_prologue +=
LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
- LocalVariable* positional_count_var = MakeTemporary();
copy_args_prologue += LoadArgDescriptor();
copy_args_prologue += LoadNativeField(Slot::ArgumentsDescriptor_count());
LocalVariable* count_var = MakeTemporary();
- if (check_arguments_shape) {
- // Ensure the caller provided at least [min_num_pos_args] arguments.
- copy_args_prologue += IntConstant(min_num_pos_args);
- copy_args_prologue += LoadLocal(positional_count_var);
- copy_args_prologue += SmiRelationalOp(Token::kLTE);
- TargetEntryInstr *success1, *fail1;
- copy_args_prologue += BranchIfTrue(&success1, &fail1);
- copy_args_prologue = Fragment(copy_args_prologue.entry, success1);
-
- // Ensure the caller provided at most [max_num_pos_args] arguments.
- copy_args_prologue += LoadLocal(positional_count_var);
- copy_args_prologue += IntConstant(max_num_pos_args);
- copy_args_prologue += SmiRelationalOp(Token::kLTE);
- TargetEntryInstr *success2, *fail2;
- copy_args_prologue += BranchIfTrue(&success2, &fail2);
- copy_args_prologue = Fragment(copy_args_prologue.entry, success2);
-
- // Link up the argument check failing code.
- Fragment(fail1) + Goto(nsm);
- Fragment(fail2) + Goto(nsm);
- }
-
copy_args_prologue += LoadLocal(count_var);
copy_args_prologue += IntConstant(min_num_pos_args);
copy_args_prologue += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
@@ -290,19 +202,6 @@
}
copy_args_prologue += Goto(next_missing /* join good/not_good flows */);
copy_args_prologue.current = next_missing;
-
- if (check_arguments_shape) {
- // Check for unprocessed arguments and throw NSM if there are any.
- TargetEntryInstr *done, *unknown_named_arg_passed;
- copy_args_prologue += LoadLocal(positional_count_var);
- copy_args_prologue += LoadLocal(count_var);
- copy_args_prologue += BranchIfEqual(&done, &unknown_named_arg_passed);
- copy_args_prologue.current = done;
- {
- Fragment f(unknown_named_arg_passed);
- f += Goto(nsm);
- }
- }
} else {
ASSERT(num_opt_named_params > 0);
@@ -375,10 +274,7 @@
const bool required = check_required_params &&
function_.IsRequiredAt(opt_param_position[i]);
- // If this function cannot be invoked dynamically and this is a required
- // named argument, then we can just add this fragment directly without
- // checking the name to ensure it was provided.
- if (required && !check_arguments_shape) {
+ if (required) {
copy_args_prologue += good;
} else {
// name = arg_desc[names_offset + arg_desc_name_index + nameOffset]
@@ -410,42 +306,22 @@
good.Prepend(supplied);
good += Goto(join);
- // We had no match. If the param is required, throw a NoSuchMethod
- // error. Otherwise just load the default constant.
+ // We had no match, so load the default constant.
Fragment not_good(missing);
- if (required) {
- ASSERT(nsm != nullptr);
- not_good += Goto(nsm);
- } else {
- not_good += Constant(DefaultParameterValueAt(opt_param_position[i] -
- num_fixed_params));
+ not_good += Constant(
+ DefaultParameterValueAt(opt_param_position[i] - num_fixed_params));
- // Copy down with default value.
- not_good += StoreLocalRaw(TokenPosition::kNoSource,
- ParameterVariable(opt_param_position[i]));
- not_good += Drop();
- not_good += Goto(join);
- }
+ // Copy down with default value.
+ not_good += StoreLocalRaw(TokenPosition::kNoSource,
+ ParameterVariable(opt_param_position[i]));
+ not_good += Drop();
+ not_good += Goto(join);
copy_args_prologue.current = join;
}
copy_args_prologue += Drop(); // tuple_diff
}
-
- if (check_arguments_shape) {
- // Check for unprocessed arguments and throw NSM if there are any.
- TargetEntryInstr *done, *unknown_named_arg_passed;
- copy_args_prologue += LoadLocal(optional_count_var);
- copy_args_prologue += LoadLocal(optional_count_vars_processed);
- copy_args_prologue += BranchIfEqual(&done, &unknown_named_arg_passed);
- copy_args_prologue.current = done;
-
- {
- Fragment f(unknown_named_arg_passed);
- f += Goto(nsm);
- }
- }
}
copy_args_prologue += Drop(); // optional_count_var
@@ -455,32 +331,6 @@
return copy_args_prologue;
}
-Fragment PrologueBuilder::BuildFixedParameterLengthChecks(JoinEntryInstr* nsm) {
- Fragment check_args;
- JoinEntryInstr* done = BuildJoinEntry();
-
- check_args += LoadArgDescriptor();
- check_args += LoadNativeField(Slot::ArgumentsDescriptor_count());
- LocalVariable* count = MakeTemporary();
-
- TargetEntryInstr *then, *fail;
- check_args += LoadLocal(count);
- check_args += IntConstant(function_.num_fixed_parameters());
- check_args += BranchIfEqual(&then, &fail);
-
- TargetEntryInstr *then2, *fail2;
- Fragment check_len(then);
- check_len += LoadArgDescriptor();
- check_len += LoadNativeField(Slot::ArgumentsDescriptor_positional_count());
- check_len += BranchIfEqual(&then2, &fail2);
-
- Fragment(fail) + Goto(nsm);
- Fragment(fail2) + Goto(nsm);
- Fragment(then2) + Goto(done);
-
- return Fragment(check_args.entry, done);
-}
-
Fragment PrologueBuilder::BuildClosureContextHandling() {
LocalVariable* closure_parameter = parsed_function_->ParameterVariable(0);
LocalVariable* context = parsed_function_->current_context_var();
@@ -495,13 +345,7 @@
return populate_context;
}
-Fragment PrologueBuilder::BuildTypeArgumentsHandling(JoinEntryInstr* nsm) {
- // We only need to check the shape of the arguments (correct parameter count
- // and correct names/provided required arguments) when the function can be
- // invoked dynamically. The caller only provides a non-nullptr nsm block if
- // dynamic invocation is possible.
- const bool check_argument_shapes = nsm != nullptr;
-
+Fragment PrologueBuilder::BuildTypeArgumentsHandling() {
LocalVariable* type_args_var = parsed_function_->RawTypeArgumentsVariable();
ASSERT(type_args_var != nullptr);
@@ -539,15 +383,9 @@
StoreLocal(TokenPosition::kNoSource, type_args_var);
use_delayed_type_args += Drop();
- handling += TestDelayedTypeArgs(
- closure,
- /*present=*/
- // No need to check the type arguments length if this function cannot
- // be invoked dynamically, and thus we are not checking argument shapes.
- check_argument_shapes
- ? TestTypeArgsLen(use_delayed_type_args, Goto(nsm), 0)
- : use_delayed_type_args,
- /*absent=*/Fragment());
+ handling += TestDelayedTypeArgs(closure,
+ /*present=*/use_delayed_type_args,
+ /*absent=*/Fragment());
}
return handling;
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index 58923f9..c8d629d 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -49,8 +49,7 @@
BlockEntryInstr* BuildPrologue(BlockEntryInstr* entry,
PrologueInfo* prologue_info);
- Fragment BuildOptionalParameterHandling(JoinEntryInstr* nsm,
- LocalVariable* temp_var);
+ Fragment BuildOptionalParameterHandling(LocalVariable* temp_var);
static bool HasEmptyPrologue(const Function& function);
static bool PrologueSkippableOnUncheckedEntry(const Function& function);
@@ -58,14 +57,9 @@
intptr_t last_used_block_id() const { return last_used_block_id_; }
private:
- Fragment BuildTypeArgumentsLengthCheck(JoinEntryInstr* nsm,
- bool expect_type_args);
-
- Fragment BuildFixedParameterLengthChecks(JoinEntryInstr* nsm);
-
Fragment BuildClosureContextHandling();
- Fragment BuildTypeArgumentsHandling(JoinEntryInstr* nsm);
+ Fragment BuildTypeArgumentsHandling();
LocalVariable* ParameterVariable(intptr_t index) {
return parsed_function_->RawParameterVariable(index);
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 8ca008e..ea6b457 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -213,12 +213,6 @@
// arguments and dynamic targets do their own covariant checking.
// Thus, implicit closure functions perform no checking internally.
type_check_mode = kTypeCheckForImplicitClosureFunction;
- } else if (function.CanReceiveDynamicInvocation()) {
- // If the current function can be the direct target of a dynamic
- // invocation, that is, dynamic calls do not go through a dynamic
- // invocation forwarder or dynamic closure call dispatcher, then we must
- // check non-covariant parameters as well as covariant ones.
- type_check_mode = kTypeCheckAllParameters;
}
// Continue reading FunctionNode:
@@ -284,7 +278,7 @@
}
scope_->InsertParameterAt(pos++, result_->setter_value);
- if (is_method && !function.CanReceiveDynamicInvocation()) {
+ if (is_method) {
if (field.is_covariant()) {
result_->setter_value->set_is_explicit_covariant_parameter();
} else if (!field.is_generic_covariant_impl() ||
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index 1c7f122..9931e91 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -130,8 +130,6 @@
//
// Normally we have to check the parameter type.
ASSERT(function.NeedsArgumentTypeChecks());
- // Dynamic call sites will go to dyn:set:* instead.
- ASSERT(!function.CanReceiveDynamicInvocation());
// Covariant parameter types have to be checked, which we don't support.
if (field.is_covariant() || field.is_generic_covariant_impl()) return false;
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index 156a5c4..e4dae18 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -501,7 +501,7 @@
static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 64;
+static constexpr dart::compiler::target::word Script_InstanceSize = 56;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SignatureData_InstanceSize = 12;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -1022,7 +1022,7 @@
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 104;
+static constexpr dart::compiler::target::word Script_InstanceSize = 96;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -1534,7 +1534,7 @@
static constexpr dart::compiler::target::word Pointer_InstanceSize = 12;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 20;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 60;
-static constexpr dart::compiler::target::word Script_InstanceSize = 64;
+static constexpr dart::compiler::target::word Script_InstanceSize = 56;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SignatureData_InstanceSize = 12;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
@@ -2056,7 +2056,7 @@
static constexpr dart::compiler::target::word Pointer_InstanceSize = 24;
static constexpr dart::compiler::target::word ReceivePort_InstanceSize = 40;
static constexpr dart::compiler::target::word RegExp_InstanceSize = 120;
-static constexpr dart::compiler::target::word Script_InstanceSize = 104;
+static constexpr dart::compiler::target::word Script_InstanceSize = 96;
static constexpr dart::compiler::target::word SendPort_InstanceSize = 24;
static constexpr dart::compiler::target::word SignatureData_InstanceSize = 24;
static constexpr dart::compiler::target::word SingleTargetCache_InstanceSize =
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index d98eaa1..8761060 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -273,12 +273,10 @@
arguments_descriptor);
}
- if (!callable_function.CanReceiveDynamicInvocation()) {
- const auto& result = Object::Handle(
- zone, callable_function.DoArgumentTypesMatch(arguments, args_desc));
- if (result.IsError()) {
- Exceptions::PropagateError(Error::Cast(result));
- }
+ const auto& result = Object::Handle(
+ zone, callable_function.DoArgumentTypesMatch(arguments, args_desc));
+ if (result.IsError()) {
+ Exceptions::PropagateError(Error::Cast(result));
}
return InvokeFunction(callable_function, arguments, arguments_descriptor);
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 07932e6..7c53e72 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -347,36 +347,6 @@
script.set_debug_positions(array_object);
}
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-ArrayPtr CollectConstConstructorCoverageFrom(const Script& interesting_script) {
- Thread* thread = Thread::Current();
- Zone* zone = thread->zone();
- interesting_script.LookupSourceAndLineStarts(zone);
- TranslationHelper helper(thread);
- helper.InitFromScript(interesting_script);
-
- ExternalTypedData& data =
- ExternalTypedData::Handle(zone, interesting_script.constant_coverage());
-
- KernelReaderHelper kernel_reader(zone, &helper, interesting_script, data, 0);
-
- // Read "constant coverage constructors".
- const intptr_t constant_coverage_constructors = kernel_reader.ReadUInt();
- const Array& constructors =
- Array::Handle(Array::New(constant_coverage_constructors));
- for (intptr_t i = 0; i < constant_coverage_constructors; ++i) {
- NameIndex kernel_name = kernel_reader.ReadCanonicalNameReference();
- Class& klass = Class::ZoneHandle(
- zone,
- helper.LookupClassByKernelClass(helper.EnclosingName(kernel_name)));
- const Function& target = Function::ZoneHandle(
- zone, helper.LookupConstructorByKernelConstructor(klass, kernel_name));
- constructors.SetAt(i, target);
- }
- return constructors.raw();
-}
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-
ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field) {
ASSERT(field.is_static() && field.is_const());
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index 4b55de9..9b0d8de 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -195,10 +195,6 @@
void CollectTokenPositionsFor(const Script& script);
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-ArrayPtr CollectConstConstructorCoverageFrom(const Script& interesting_script);
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-
ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field);
ObjectPtr EvaluateMetadata(const Field& metadata_field,
bool is_annotations_offset);
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index a8cafe4..e37f325 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -2099,10 +2099,6 @@
const String& uri_string = helper_.SourceTableUriFor(index);
const String& import_uri_string =
helper_.SourceTableImportUriFor(index, program_->binary_version());
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- ExternalTypedData& constant_coverage =
- ExternalTypedData::Handle(Z, helper_.GetConstantCoverageFor(index));
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
String& sources = String::Handle(Z);
TypedData& line_starts = TypedData::Handle(Z);
@@ -2148,9 +2144,6 @@
script.set_kernel_script_index(index);
script.set_kernel_program_info(kernel_program_info_);
script.set_line_starts(line_starts);
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- script.set_constant_coverage(constant_coverage);
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
script.set_debug_positions(Array::null_array());
return script.raw();
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index bae9d93f..160aa54 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4215,12 +4215,10 @@
}
// This is a static function, so we pass an empty instantiator tav.
ASSERT(function.is_static());
- if (!function.CanReceiveDynamicInvocation()) {
- ObjectPtr type_error = function.DoArgumentTypesMatch(
- args, args_descriptor, Object::empty_type_arguments());
- if (type_error != Error::null()) {
- return type_error;
- }
+ ObjectPtr type_error = function.DoArgumentTypesMatch(
+ args, args_descriptor, Object::empty_type_arguments());
+ if (type_error != Error::null()) {
+ return type_error;
}
return DartEntry::InvokeFunction(function, args, args_descriptor_array);
}
@@ -9648,8 +9646,7 @@
}
// The prologue of those functions need to examine the arg descriptor for
// various purposes.
- return IsGeneric() || HasOptionalParameters() ||
- CanReceiveDynamicInvocation();
+ return IsGeneric() || HasOptionalParameters();
}
bool Function::MayHaveUncheckedEntryPoint() const {
@@ -11162,16 +11159,6 @@
StorePointer(&raw_ptr()->line_starts_, value.raw());
}
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-void Script::set_constant_coverage(const ExternalTypedData& value) const {
- StorePointer(&raw_ptr()->constant_coverage_, value.raw());
-}
-
-ExternalTypedDataPtr Script::constant_coverage() const {
- return raw_ptr()->constant_coverage_;
-}
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-
void Script::set_debug_positions(const Array& value) const {
StorePointer(&raw_ptr()->debug_positions_, value.raw());
}
@@ -12718,12 +12705,10 @@
return DartEntry::InvokeNoSuchMethod(thread, receiver, target_name, args,
args_descriptor_array);
}
- if (!function.CanReceiveDynamicInvocation()) {
- ObjectPtr type_error = function.DoArgumentTypesMatch(
- args, args_descriptor, instantiator_type_args);
- if (type_error != Error::null()) {
- return type_error;
- }
+ ObjectPtr type_error = function.DoArgumentTypesMatch(args, args_descriptor,
+ instantiator_type_args);
+ if (type_error != Error::null()) {
+ return type_error;
}
return DartEntry::InvokeFunction(function, args, args_descriptor_array);
}
@@ -12920,12 +12905,10 @@
}
// This is a static function, so we pass an empty instantiator tav.
ASSERT(function.is_static());
- if (!function.CanReceiveDynamicInvocation()) {
- ObjectPtr type_error = function.DoArgumentTypesMatch(
- args, args_descriptor, Object::empty_type_arguments());
- if (type_error != Error::null()) {
- return type_error;
- }
+ ObjectPtr type_error = function.DoArgumentTypesMatch(
+ args, args_descriptor, Object::empty_type_arguments());
+ if (type_error != Error::null()) {
+ return type_error;
}
return DartEntry::InvokeFunction(function, args, args_descriptor_array);
}
@@ -14896,6 +14879,24 @@
}
#endif
+void ICData::SetTargetAtPos(const Array& data,
+ intptr_t data_pos,
+ intptr_t num_args_tested,
+ const Function& target) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // JIT
+ data.SetAt(data_pos + TargetIndexFor(num_args_tested), target);
+#else
+ // AOT
+ ASSERT(target.HasCode());
+ const Code& code = Code::Handle(target.CurrentCode());
+ const Smi& entry_point =
+ Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
+ data.SetAt(data_pos + CodeIndexFor(num_args_tested), code);
+ data.SetAt(data_pos + EntryPointIndexFor(num_args_tested), entry_point);
+#endif
+}
+
const char* ICData::ToCString() const {
Zone* zone = Thread::Current()->zone();
const String& name = String::Handle(zone, target_name());
@@ -15347,24 +15348,15 @@
data_pos = 0;
}
data.SetAt(data_pos, Smi::Handle(Smi::New(receiver_class_id)));
+ SetTargetAtPos(data, data_pos, kNumArgsTested, target);
#if !defined(DART_PRECOMPILED_RUNTIME)
- // JIT
- data.SetAt(data_pos + TargetIndexFor(kNumArgsTested), target);
data.SetAt(data_pos + CountIndexFor(kNumArgsTested),
Smi::Handle(Smi::New(count)));
if (is_tracking_exactness()) {
data.SetAt(data_pos + ExactnessIndexFor(kNumArgsTested),
Smi::Handle(Smi::New(exactness.Encode())));
}
-#else
- // AOT
- ASSERT(target.HasCode());
- const Code& code = Code::Handle(target.CurrentCode());
- const Smi& entry_point =
- Smi::Handle(Smi::FromAlignedAddress(code.EntryPoint()));
- data.SetAt(data_pos + CodeIndexFor(kNumArgsTested), code);
- data.SetAt(data_pos + EntryPointIndexFor(kNumArgsTested), entry_point);
#endif
// Multithreaded access to ICData requires setting of array to be the last
@@ -15839,9 +15831,13 @@
cid = Smi::New((*cids)[i]);
array.SetAt(i, cid);
}
+
+ SetTargetAtPos(array, 0, num_args_tested, target);
+#if !defined(DART_PRECOMPILED_RUNTIME)
array.SetAt(CountIndexFor(num_args_tested), Object::smi_zero());
- array.SetAt(TargetIndexFor(num_args_tested), target);
+#endif
WriteSentinel(array, entry_len);
+
result.set_entries(array);
return result.raw();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 584e180..3c70ead 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2258,6 +2258,11 @@
void SetNumArgsTested(intptr_t value) const;
void SetReceiversStaticType(const AbstractType& type) const;
+ static void SetTargetAtPos(const Array& data,
+ intptr_t data_pos,
+ intptr_t num_args_tested,
+ const Function& target);
+
// This bit is set when a call site becomes megamorphic and starts using a
// MegamorphicCache instead of ICData. It means that the entries in the
// ICData are incomplete and the MegamorphicCache needs to also be consulted
@@ -2849,10 +2854,6 @@
return (kind() == FunctionLayout::kConstructor) && is_static();
}
- // Whether this function can receive an invocation where the number and names
- // of arguments have not been checked.
- bool CanReceiveDynamicInvocation() const { return IsFfiTrampoline(); }
-
bool HasThisParameter() const {
return IsDynamicFunction(/*allow_abstract=*/true) ||
IsGenerativeConstructor() || (IsFieldInitializer() && !is_static());
@@ -4501,12 +4502,6 @@
TypedDataPtr line_starts() const;
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- ExternalTypedDataPtr constant_coverage() const;
-
- void set_constant_coverage(const ExternalTypedData& value) const;
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
-
void set_line_starts(const TypedData& value) const;
void set_debug_positions(const Array& value) const;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index bbfc8f7..6ef0636 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1253,9 +1253,6 @@
StringPtr resolved_url_;
ArrayPtr compile_time_constants_;
TypedDataPtr line_starts_;
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
- ExternalTypedDataPtr constant_coverage_;
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
ArrayPtr debug_positions_;
KernelProgramInfoPtr kernel_program_info_;
StringPtr source_;
@@ -1287,17 +1284,8 @@
kLazyLookupSourceAndLineStartsSize>;
uint8_t flags_;
+ intptr_t kernel_script_index_;
int64_t load_timestamp_;
- int32_t kernel_script_index_;
-#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) && \
- defined(ARCH_IS_32_BIT)
- // MSVC aligns sizeof(ScriptLayout) by 8 on 32-bit because rgw structure
- // contains int64_t member, while clang does not.
- // This member is thus needed to ensure consistent struct size across all
- // compilers.
- int32_t padding_;
-#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) && \
- // defined(ARCH_IS_32_BIT)
};
class LibraryLayout : public ObjectLayout {
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index f241c0c..8ef9463 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1596,6 +1596,9 @@
void DoMegamorphicMiss(const MegamorphicCache& data,
const Function& target_function);
+ ICDataPtr NewICData();
+ ICDataPtr NewICDataWithTarget(intptr_t cid, const Function& target);
+
Isolate* isolate_;
Thread* thread_;
Zone* zone_;
@@ -1613,16 +1616,11 @@
void SwitchableCallHandler::DoUnlinkedCall(const UnlinkedCall& unlinked,
const Function& target_function) {
- const String& name = String::Handle(zone_, unlinked.target_name());
- const Array& descriptor =
- Array::Handle(zone_, unlinked.arguments_descriptor());
- const ICData& ic_data =
- ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
- DeoptId::kNone, 1, /* args_tested */
- ICData::kInstance));
- if (!target_function.IsNull()) {
- ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
- }
+ const auto& ic_data = ICData::Handle(
+ zone_,
+ target_function.IsNull()
+ ? NewICData()
+ : NewICDataWithTarget(receiver_.GetClassId(), target_function));
Object& object = Object::Handle(zone_, ic_data.raw());
Code& code = Code::Handle(zone_, StubCode::ICCallThroughCode().raw());
@@ -1746,14 +1744,10 @@
zone_,
Resolve(thread_, zone_, old_receiver_class, name_, args_descriptor_));
- const ICData& ic_data = ICData::Handle(
- zone_, ICData::New(caller_function_, name_, args_descriptor_,
- DeoptId::kNone, 1, /* args_tested */
- ICData::kInstance));
- // Add the first target.
- if (!old_target.IsNull()) {
- ic_data.AddReceiverCheck(old_expected_cid, old_target);
- }
+ const auto& ic_data = ICData::Handle(
+ zone_, old_target.IsNull()
+ ? NewICData()
+ : NewICDataWithTarget(old_expected_cid, old_target));
if (is_monomorphic_hit) {
// The site just have been updated to monomorphic state with same
@@ -1794,6 +1788,7 @@
arguments_.SetArgAt(0, stub);
arguments_.SetReturn(ic_data);
#else // JIT
+
const ICData& ic_data = ICData::Handle(
zone_,
FindICDataForInstanceCall(zone_, caller_code_, caller_frame_->pc()));
@@ -1836,13 +1831,11 @@
Function::Handle(zone_, Function::RawCast(old_target_code.owner()));
// We lost the original ICData when we patched to the monomorphic case.
- const ICData& ic_data = ICData::Handle(
- zone_, ICData::New(caller_function_, name_, args_descriptor_,
- DeoptId::kNone, 1, /* args_tested */
- ICData::kInstance));
- if (!target_function.IsNull()) {
- ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
- }
+ const auto& ic_data = ICData::Handle(
+ zone_,
+ target_function.IsNull()
+ ? NewICData()
+ : NewICDataWithTarget(receiver_.GetClassId(), target_function));
intptr_t lower = data.lower_limit();
intptr_t upper = data.upper_limit();
@@ -1957,6 +1950,20 @@
arguments_.SetReturn(data);
}
+ICDataPtr SwitchableCallHandler::NewICData() {
+ return ICData::New(caller_function_, name_, args_descriptor_, DeoptId::kNone,
+ /*num_args_tested=*/1, ICData::kInstance);
+}
+
+ICDataPtr SwitchableCallHandler::NewICDataWithTarget(intptr_t cid,
+ const Function& target) {
+ GrowableArray<intptr_t> cids(1);
+ cids.Add(cid);
+ return ICData::NewWithCheck(caller_function_, name_, args_descriptor_,
+ DeoptId::kNone, /*num_args_tested=*/1,
+ ICData::kInstance, &cids, target);
+}
+
FunctionPtr SwitchableCallHandler::ResolveTargetFunction(const Object& data) {
switch (data.GetClassId()) {
case kUnlinkedCallCid: {
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 3f074ff..84f5495 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -565,19 +565,6 @@
// Visit all closures for this isolate.
VisitClosures(&ranges);
-
- // Output constant coverage if coverage is requested.
- if (IsReportRequested(kCoverage)) {
- // Find all scripts. We need to go though all scripts because a script
- // (even one we don't want) can add coverage to another library (i.e.
- // potentially one we want).
- DirectChainedHashMap<ScriptTableTrait> local_script_table;
- GrowableArray<ScriptTableEntry*> local_script_table_entries;
- CollectAllScripts(&local_script_table, &local_script_table_entries);
- CollectConstConstructorCoverageFromScripts(&local_script_table_entries,
- &ranges);
- CleanupCollectedScripts(&local_script_table, &local_script_table_entries);
- }
}
// Print the script table.
@@ -585,102 +572,5 @@
PrintScriptTable(&scripts);
}
-void SourceReport::CollectAllScripts(
- DirectChainedHashMap<ScriptTableTrait>* local_script_table,
- GrowableArray<ScriptTableEntry*>* local_script_table_entries) {
- ScriptTableEntry wrapper;
- const GrowableObjectArray& libs = GrowableObjectArray::Handle(
- zone(), thread()->isolate()->object_store()->libraries());
- Library& lib = Library::Handle(zone());
- Script& scriptRef = Script::Handle(zone());
- for (int i = 0; i < libs.Length(); i++) {
- lib ^= libs.At(i);
- const Array& scripts = Array::Handle(zone(), lib.LoadedScripts());
- for (intptr_t j = 0; j < scripts.Length(); j++) {
- scriptRef ^= scripts.At(j);
- const String& url = String::Handle(zone(), scriptRef.url());
- wrapper.key = &url;
- wrapper.script = &Script::Handle(zone(), scriptRef.raw());
- ScriptTableEntry* pair = local_script_table->LookupValue(&wrapper);
- if (pair != NULL) {
- // Existing one.
- continue;
- }
- // New one. Insert.
- ScriptTableEntry* tmp = new ScriptTableEntry();
- tmp->key = &url;
- tmp->index = next_script_index_++;
- tmp->script = wrapper.script;
- local_script_table_entries->Add(tmp);
- local_script_table->Insert(tmp);
- }
- }
-}
-
-void SourceReport::CleanupCollectedScripts(
- DirectChainedHashMap<ScriptTableTrait>* local_script_table,
- GrowableArray<ScriptTableEntry*>* local_script_table_entries) {
- for (intptr_t i = 0; i < local_script_table_entries->length(); i++) {
- delete local_script_table_entries->operator[](i);
- local_script_table_entries->operator[](i) = NULL;
- }
- local_script_table_entries->Clear();
- local_script_table->Clear();
-}
-
-void SourceReport::CollectConstConstructorCoverageFromScripts(
- GrowableArray<ScriptTableEntry*>* local_script_table_entries,
- JSONArray* ranges) {
- // Now output the wanted constant coverage.
- for (intptr_t i = 0; i < local_script_table_entries->length(); i++) {
- const Script* script = local_script_table_entries->At(i)->script;
- bool script_ok = true;
- if (script_ != NULL && !script_->IsNull()) {
- if (script->raw() != script_->raw()) {
- // This is the wrong script.
- script_ok = false;
- }
- }
-
- // Whether we want *this* script or not we need to look at the constant
- // constructor coverage. Any of those could be in a script we *do* want.
- {
- Script& scriptRef = Script::Handle(zone());
- const Array& constructors =
- Array::Handle(kernel::CollectConstConstructorCoverageFrom(*script));
- intptr_t constructors_count = constructors.Length();
- Function& constructor = Function::Handle(zone());
- Code& code = Code::Handle(zone());
- for (intptr_t i = 0; i < constructors_count; i++) {
- constructor ^= constructors.At(i);
- // Check if we want coverage for this constructor.
- if (ShouldSkipFunction(constructor)) {
- continue;
- }
- scriptRef ^= constructor.script();
- code ^= constructor.unoptimized_code();
- const TokenPosition begin_pos = constructor.token_pos();
- const TokenPosition end_pos = constructor.end_token_pos();
- JSONObject range(ranges);
- range.AddProperty("scriptIndex", GetScriptIndex(scriptRef));
- range.AddProperty("compiled",
- !code.IsNull()); // Does this make a difference?
- range.AddProperty("startPos", begin_pos);
- range.AddProperty("endPos", end_pos);
-
- JSONObject cov(&range, "coverage");
- {
- JSONArray hits(&cov, "hits");
- hits.AddValue(begin_pos);
- }
- {
- JSONArray misses(&cov, "misses");
- // No misses
- }
- }
- }
- }
-}
-
} // namespace dart
#endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 4ec20c9..0a3ddb1 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -112,18 +112,6 @@
}
};
- void CollectAllScripts(
- DirectChainedHashMap<ScriptTableTrait>* local_script_table,
- GrowableArray<ScriptTableEntry*>* local_script_table_entries);
-
- void CleanupCollectedScripts(
- DirectChainedHashMap<ScriptTableTrait>* local_script_table,
- GrowableArray<ScriptTableEntry*>* local_script_table_entries);
-
- void CollectConstConstructorCoverageFromScripts(
- GrowableArray<ScriptTableEntry*>* local_script_table_entries,
- JSONArray* ranges);
-
intptr_t report_set_;
CompileMode compile_mode_;
Thread* thread_;
diff --git a/tests/ffi/function_test.dart b/tests/ffi/function_test.dart
index 376711b..bff456e 100644
--- a/tests/ffi/function_test.dart
+++ b/tests/ffi/function_test.dart
@@ -69,13 +69,22 @@
void testNativeFunctionFromLookup() {
Expect.equals(49, sumPlus42(3, 4));
+ Expect.equals(49, (sumPlus42 as dynamic)(3, 4));
+ Expect.throwsNoSuchMethodError(() => (sumPlus42 as dynamic)());
+ Expect.throwsTypeError(() => (sumPlus42 as dynamic)(3, 4.0));
Expect.equals(625, intComputation(125, 250, 500, 1000));
+ Expect.equals(625, (intComputation as dynamic)(125, 250, 500, 1000));
Expect.equals(
0x7FFFFFFFFFFFFFFF, intComputation(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
Expect.equals(
-0x8000000000000000, intComputation(0, 0, 0, -0x8000000000000000));
+
+ Expect.equals(0x7FFFFFFFFFFFFFFF,
+ (intComputation as dynamic)(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
+ Expect.equals(-0x8000000000000000,
+ (intComputation as dynamic)(0, 0, 0, -0x8000000000000000));
}
typedef NativeReturnMaxUint8 = Uint8 Function();
diff --git a/tests/ffi_2/function_test.dart b/tests/ffi_2/function_test.dart
index 376711b..bff456e 100644
--- a/tests/ffi_2/function_test.dart
+++ b/tests/ffi_2/function_test.dart
@@ -69,13 +69,22 @@
void testNativeFunctionFromLookup() {
Expect.equals(49, sumPlus42(3, 4));
+ Expect.equals(49, (sumPlus42 as dynamic)(3, 4));
+ Expect.throwsNoSuchMethodError(() => (sumPlus42 as dynamic)());
+ Expect.throwsTypeError(() => (sumPlus42 as dynamic)(3, 4.0));
Expect.equals(625, intComputation(125, 250, 500, 1000));
+ Expect.equals(625, (intComputation as dynamic)(125, 250, 500, 1000));
Expect.equals(
0x7FFFFFFFFFFFFFFF, intComputation(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
Expect.equals(
-0x8000000000000000, intComputation(0, 0, 0, -0x8000000000000000));
+
+ Expect.equals(0x7FFFFFFFFFFFFFFF,
+ (intComputation as dynamic)(0, 0, 0, 0x7FFFFFFFFFFFFFFF));
+ Expect.equals(-0x8000000000000000,
+ (intComputation as dynamic)(0, 0, 0, -0x8000000000000000));
}
typedef NativeReturnMaxUint8 = Uint8 Function();
diff --git a/tools/VERSION b/tools/VERSION
index 7c1de33..ff6e07f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 103
+PRERELEASE 104
PRERELEASE_PATCH 0
\ No newline at end of file